--- /dev/null
--- /dev/null
++noinst_LIBRARIES = libAircraft.a
++
++libAircraft_a_SOURCES = aircraft.cxx aircraft.hxx
++
++INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib -I$(top_builddir)/Simulator
--- /dev/null
--- /dev/null
++// aircraft.cxx -- various aircraft routines
++//
++// Written by Curtis Olson, started May 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$
++// (Log is kept at end of this file)
++
++
++#include <stdio.h>
++
++#include "aircraft.hxx"
++#include <Debug/logstream.hxx>
++#include <Include/fg_constants.h>
++
++// This is a record containing all the info for the aircraft currently
++// being operated
++fgAIRCRAFT current_aircraft;
++
++
++// Initialize an Aircraft structure
++void fgAircraftInit( void ) {
++ FG_LOG( FG_AIRCRAFT, FG_INFO, "Initializing Aircraft structure" );
++
++ current_aircraft.fdm_state = &cur_fdm_state;
++ current_aircraft.controls = &controls;
++}
++
++
++// Display various parameters to stdout
++void fgAircraftOutputCurrent(fgAIRCRAFT *a) {
++ FGInterface *f;
++
++ f = a->fdm_state;
++
++ FG_LOG( FG_FLIGHT, FG_DEBUG,
++ "Pos = ("
++ << (f->get_Longitude() * 3600.0 * RAD_TO_DEG) << ","
++ << (f->get_Latitude() * 3600.0 * RAD_TO_DEG) << ","
++ << f->get_Altitude()
++ << ") (Phi,Theta,Psi)=("
++ << f->get_Phi() << ","
++ << f->get_Theta() << ","
++ << f->get_Psi() << ")" );
++
++ FG_LOG( FG_FLIGHT, FG_DEBUG,
++ "Kts = " << f->get_V_equiv_kts()
++ << " Elev = " << controls.get_elevator()
++ << " Aileron = " << controls.get_aileron()
++ << " Rudder = " << controls.get_rudder()
++ << " Power = " << controls.get_throttle( 0 ) );
++}
++
++
++// $Log$
++// Revision 1.7 1999/02/05 21:28:09 curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.6 1998/12/05 15:53:59 curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.5 1998/12/03 01:14:58 curt
++// Converted fgFLIGHT to a class.
++//
++// Revision 1.4 1998/11/06 21:17:31 curt
++// Converted to new logstream debugging facility. This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.3 1998/10/25 14:08:37 curt
++// Turned "struct fgCONTROLS" into a class, with inlined accessor functions.
++//
++// Revision 1.2 1998/10/17 01:33:52 curt
++// C++ ifying ...
++//
++// Revision 1.1 1998/10/16 23:26:47 curt
++// C++-ifying.
++//
++// Revision 1.19 1998/04/25 22:06:24 curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.18 1998/04/18 04:13:56 curt
++// Moved fg_debug.c to it's own library.
++//
++// Revision 1.17 1998/02/12 21:59:31 curt
++// Incorporated code changes contributed by Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.16 1998/02/07 15:29:31 curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.15 1998/01/27 00:47:46 curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.14 1998/01/19 19:26:56 curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.13 1997/12/15 23:54:30 curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.12 1997/12/10 22:37:37 curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.11 1997/09/13 02:00:05 curt
++// Mostly working on stars and generating sidereal time for accurate star
++// placement.
++//
++// Revision 1.10 1997/08/27 03:29:56 curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.9 1997/07/19 22:39:08 curt
++// Moved PI to ../constants.h
++//
++// Revision 1.8 1997/06/25 15:39:45 curt
++// Minor changes to compile with rsxnt/win32.
++//
++// Revision 1.7 1997/06/02 03:01:39 curt
++// Working on views (side, front, back, transitions, etc.)
++//
++// Revision 1.6 1997/05/31 19:16:26 curt
++// Elevator trim added.
++//
++// Revision 1.5 1997/05/30 19:30:14 curt
++// The LaRCsim flight model is starting to look like it is working.
++//
++// Revision 1.4 1997/05/30 03:54:11 curt
++// Made a bit more progress towards integrating the LaRCsim flight model.
++//
++// Revision 1.3 1997/05/29 22:39:56 curt
++// Working on incorporating the LaRCsim flight model.
++//
++// Revision 1.2 1997/05/23 15:40:29 curt
++// Added GNU copyright headers.
++//
++// Revision 1.1 1997/05/16 15:58:24 curt
++// Initial revision.
++//
++
--- /dev/null
--- /dev/null
++//*************************************************************************
++// aircraft.hxx -- define shared aircraft parameters
++//
++// Written by Curtis Olson, started May 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$
++// (Log is kept at end of this file)
++//*************************************************************************/
++
++
++#ifndef _AIRCRAFT_HXX
++#define _AIRCRAFT_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++
++#include <FDM/flight.hxx>
++#include <Controls/controls.hxx>
++
++
++// Define a structure containing all the parameters for an aircraft
++typedef struct{
++ FGInterface *fdm_state;
++ FGControls *controls;
++} fgAIRCRAFT ;
++
++
++// current_aircraft contains all the parameters of the aircraft
++// currently being operated.
++extern fgAIRCRAFT current_aircraft;
++
++
++// Initialize an Aircraft structure
++void fgAircraftInit( void );
++
++
++// Display various parameters to stdout
++void fgAircraftOutputCurrent(fgAIRCRAFT *a);
++
++
++#endif // _AIRCRAFT_HXX
++
++
++// $Log$
++// Revision 1.6 1999/02/05 21:28:10 curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.5 1999/02/01 21:33:24 curt
++// Renamed FlightGear/Simulator/Flight to FlightGear/Simulator/FDM since
++// Jon accepted my offer to do this and thought it was a good idea.
++//
++// Revision 1.4 1998/12/05 16:13:10 curt
++// Renamed class fgCONTROLS to class FGControls.
++//
++// Revision 1.3 1998/12/05 15:54:01 curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.2 1998/10/17 01:33:54 curt
++// C++ ifying ...
++//
++// Revision 1.1 1998/10/16 23:26:49 curt
++// C++-ifying.
++//
++// Revision 1.12 1998/04/22 13:26:15 curt
++// C++ - ifing the code a bit.
++//
++// Revision 1.11 1998/04/21 17:02:27 curt
++// Prepairing for C++ integration.
++//
++// Revision 1.10 1998/02/07 15:29:32 curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.9 1998/01/22 02:59:23 curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.8 1998/01/19 19:26:57 curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.7 1997/12/10 22:37:38 curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.6 1997/09/13 02:00:06 curt
++// Mostly working on stars and generating sidereal time for accurate star
++// placement.
++//
++// Revision 1.5 1997/08/27 03:29:58 curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.4 1997/07/23 21:52:17 curt
++// Put comments around the text after an #endif for increased portability.
++//
++// Revision 1.3 1997/06/21 17:12:42 curt
++// Capitalized subdirectory names.
++//
++// Revision 1.2 1997/05/23 15:40:30 curt
++// Added GNU copyright headers.
++//
++// Revision 1.1 1997/05/16 15:58:25 curt
++// Initial revision.
++//
--- /dev/null
--- /dev/null
++noinst_LIBRARIES = libAirports.a
++
++libAirports_a_SOURCES = \
++ genapt.cxx genapt.hxx \
++ simple.cxx simple.hxx
++
++INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib -I$(top_builddir)/Simulator
--- /dev/null
--- /dev/null
++//
++// genapt.cxx -- generate airport scenery from the given definition file
++//
++// Written by Curtis Olson, started September 1998.
++//
++// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#include <Include/compiler.h>
++
++#include STL_STRING
++#include <vector>
++
++#ifdef __BORLANDC__
++# define exception c_exception
++#endif
++#include <math.h>
++
++#ifdef FG_HAVE_NATIVE_SGI_COMPILERS
++# include <strings.h>
++#endif
++
++#include <Debug/logstream.hxx>
++// #include <Include/fg_types.h>
++#include <Math/fg_geodesy.hxx>
++#include <Math/mat3.h>
++#include <Math/point3d.hxx>
++#include <Math/polar3d.hxx>
++#include <Misc/fgstream.hxx>
++#include <Objects/material.hxx>
++
++// #include <gpc/gpc.h>
++
++#include "genapt.hxx"
++
++FG_USING_STD(string);
++FG_USING_STD(vector);
++
++
++typedef vector < Point3D > container;
++typedef container::iterator iterator;
++typedef container::const_iterator const_iterator;
++
++
++#define FG_APT_BASE_TEX_CONSTANT 2000.0
++
++// Calculate texture coordinates for a given point.
++static Point3D calc_tex_coords(double *node, const Point3D& ref) {
++ Point3D cp;
++ Point3D pp;
++
++ cp = Point3D( node[0] + ref.x(), node[1] + ref.y(), node[2] + ref.z() );
++
++ pp = fgCartToPolar3d(cp);
++
++ pp.setx( fmod(FG_APT_BASE_TEX_CONSTANT * pp.x(), 10.0) );
++ pp.sety( fmod(FG_APT_BASE_TEX_CONSTANT * pp.y(), 10.0) );
++
++ if ( pp.x() < 0.0 ) {
++ pp.setx( pp.x() + 10.0 );
++ }
++
++ if ( pp.y() < 0.0 ) {
++ pp.sety( pp.y() + 10.0 );
++ }
++
++ return(pp);
++}
++
++
++// generate the actual base area for the airport
++static void
++gen_base( const Point3D& average, const container& perimeter, fgTILE *t)
++{
++ GLint display_list;
++ Point3D cart, cart_trans, tex;
++ MAT3vec normal;
++ double dist, max_dist, temp;
++ int center_num, i;
++
++ fgFRAGMENT fragment;
++
++ max_dist = 0.0;
++
++ FG_LOG( FG_TERRAIN, FG_INFO,
++ "generating airport base for size = " << perimeter.size() );
++
++ fragment.init();
++ fragment.tile_ptr = t;
++
++ // find airport base material in the properties list
++ if ( ! material_mgr.find( APT_BASE_MATERIAL, fragment.material_ptr )) {
++ FG_LOG( FG_TERRAIN, FG_ALERT,
++ "Ack! unknown material name = " << APT_BASE_MATERIAL
++ << " in fgAptGenerat()" );
++ }
++
++ FG_LOG( FG_TERRAIN, FG_INFO,
++ " tile center = "
++ << t->center.x() << " " << t->center.y() << " " << t->center.z() );
++ FG_LOG( FG_TERRAIN, FG_INFO,
++ " airport center = "
++ << average.x() << " " << average.y() << " " << average.z() );
++ fragment.center = average;
++
++ normal[0] = average.x();
++ normal[1] = average.y();
++ normal[2] = average.z();
++ MAT3_NORMALIZE_VEC(normal, temp);
++
++ display_list = xglGenLists(1);
++ xglNewList(display_list, GL_COMPILE);
++ xglBegin(GL_TRIANGLE_FAN);
++
++ // first point center of fan
++ cart_trans = average - t->center;
++ t->nodes[t->ncount][0] = cart_trans.x();
++ t->nodes[t->ncount][1] = cart_trans.y();
++ t->nodes[t->ncount][2] = cart_trans.z();
++ center_num = t->ncount;
++ t->ncount++;
++
++ tex = calc_tex_coords( t->nodes[t->ncount-1], t->center );
++ xglTexCoord2f(tex.x(), tex.y());
++ xglNormal3dv(normal);
++ xglVertex3dv(t->nodes[t->ncount-1]);
++
++ // first point on perimeter
++ const_iterator current = perimeter.begin();
++ cart = fgGeodToCart( *current );
++ cart_trans = cart - t->center;
++ t->nodes[t->ncount][0] = cart_trans.x();
++ t->nodes[t->ncount][1] = cart_trans.y();
++ t->nodes[t->ncount][2] = cart_trans.z();
++ t->ncount++;
++
++ i = 1;
++ tex = calc_tex_coords( t->nodes[i], t->center );
++ dist = cart.distance3Dsquared(average);
++ if ( dist > max_dist ) {
++ max_dist = dist;
++ }
++ xglTexCoord2f(tex.x(), tex.y());
++ xglVertex3dv(t->nodes[i]);
++ ++current;
++ ++i;
++
++ const_iterator last = perimeter.end();
++ for ( ; current != last; ++current ) {
++ cart = fgGeodToCart( *current );
++ cart_trans = cart - t->center;
++ t->nodes[t->ncount][0] = cart_trans.x();
++ t->nodes[t->ncount][1] = cart_trans.y();
++ t->nodes[t->ncount][2] = cart_trans.z();
++ t->ncount++;
++ fragment.add_face(center_num, i - 1, i);
++
++ tex = calc_tex_coords( t->nodes[i], t->center );
++ dist = cart.distance3Dsquared(average);
++ if ( dist > max_dist ) {
++ max_dist = dist;
++ }
++ xglTexCoord2f(tex.x(), tex.y());
++ xglVertex3dv(t->nodes[i]);
++ i++;
++ }
++
++ // last point (first point in perimeter list)
++ current = perimeter.begin();
++ cart = fgGeodToCart( *current );
++ cart_trans = cart - t->center;
++ fragment.add_face(center_num, i - 1, 1);
++
++ tex = calc_tex_coords( t->nodes[1], t->center );
++ xglTexCoord2f(tex.x(), tex.y());
++ xglVertex3dv(t->nodes[1]);
++
++ xglEnd();
++ xglEndList();
++
++ fragment.bounding_radius = sqrt(max_dist);
++ fragment.display_list = display_list;
++
++ t->fragment_list.push_back(fragment);
++}
++
++
++// Load a .apt file and register the GL fragments with the
++// corresponding tile
++int
++fgAptGenerate(const string& path, fgTILE *tile)
++{
++ string token;
++ string apt_id, apt_name;
++ char c;
++ int i = 1;
++
++ // face list (this indexes into the master tile vertex list)
++ container perimeter;
++ Point3D p, average;
++ double avex = 0.0, avey = 0.0, avez = 0.0;
++ int size;
++
++ // gpc_vertex p_2d, list_2d[MAX_PERIMETER];
++ // gpc_vertex_list perimeter_2d;
++
++ fg_gzifstream in( path );
++ if ( !in ) {
++ // exit immediately assuming an airport file for this tile
++ // doesn't exist.
++ return 0;
++ }
++
++ apt_id = "";
++
++ // read in each line of the file
++ in >> skipcomment;
++ while ( ! in.eof() )
++ {
++ in >> token;
++
++ if ( token == "a" ) {
++ // airport info record (start of airport)
++
++ if ( apt_id.length() > 0 ) {
++ // we have just finished reading and airport record.
++ // process the info
++ gen_base(average, perimeter, tile);
++ }
++
++ FG_LOG( FG_TERRAIN, FG_INFO, "Reading airport record" );
++ in >> apt_id;
++ apt_name = "";
++ i = 1;
++ avex = avey = avez = 0.0;
++ perimeter.erase( perimeter.begin(), perimeter.end() );
++ // skip to end of line.
++ while ( in.get(c) && c != '\n' ) {
++ apt_name += c;
++ }
++ FG_LOG( FG_TERRAIN, FG_INFO,
++ "\tID = " << apt_id << " Name = " << apt_name );
++ } else if ( token == "p" ) {
++ // airport area bounding polygon coordinate. These
++ // specify a convex hull that should already have been cut
++ // out of the base terrain. The points are given in
++ // counter clockwise order and are specified in lon/lat
++ // degrees.
++ in >> p;
++ avex += tile->nodes[i][0];
++ avey += tile->nodes[i][1];
++ avez += tile->nodes[i][2];
++ perimeter.push_back(p);
++ ++i;
++ } else if ( token == "r" ) {
++ // runway record
++ // skip for now
++ while ( in.get(c) && c != '\n' );
++ }
++
++ in >> skipcomment;
++ }
++
++ if ( apt_id.length() > 0 ) {
++ // we have just finished reading and airport record.
++ // process the info
++ size = perimeter.size();
++ average = Point3D( avex / (double)size + tile->center.x(),
++ avey / (double)size + tile->center.y(),
++ avez / (double)size + tile->center.z() );
++
++ gen_base(average, perimeter, tile);
++ }
++
++ return 1;
++}
++
++
++// $Log$
++// Revision 1.14 1999/03/02 01:02:31 curt
++// Tweaks for building with native SGI compilers.
++//
++// Revision 1.13 1999/02/26 22:08:34 curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.12 1999/02/01 21:08:33 curt
++// Optimizations from Norman Vine.
++//
++// Revision 1.11 1998/11/23 21:48:09 curt
++// Borland portability tweaks.
++//
++// Revision 1.10 1998/11/07 19:07:06 curt
++// Enable release builds using the --without-logging option to the configure
++// script. Also a couple log message cleanups, plus some C to C++ comment
++// conversion.
++//
++// Revision 1.9 1998/11/06 21:17:32 curt
++// Converted to new logstream debugging facility. This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.8 1998/11/06 14:46:59 curt
++// Changes to track Bernie's updates to fgstream.
++//
++// Revision 1.7 1998/10/20 18:26:06 curt
++// Updates to point3d.hxx
++//
++// Revision 1.6 1998/10/18 01:17:16 curt
++// Point3D tweaks.
++//
++// Revision 1.5 1998/10/16 23:27:14 curt
++// C++-ifying.
++//
++// Revision 1.4 1998/10/16 00:51:46 curt
++// Converted to Point3D class.
++//
++// Revision 1.3 1998/09/21 20:55:00 curt
++// Used the cartesian form of the airport area coordinates to determine the
++// center.
++//
++// Revision 1.2 1998/09/14 12:44:30 curt
++// Don't recalculate perimeter points since it is not likely that they will match
++// exactly with the previously calculated points, which will leave an ugly gap
++// around the airport area.
++//
++// Revision 1.1 1998/09/14 02:14:01 curt
++// Initial revision of genapt.[ch]xx for generating airport scenery.
++//
--- /dev/null
--- /dev/null
++//
++// getapt.hxx -- generate airport scenery from the given definition file
++//
++// Written by Curtis Olson, started September 1998.
++//
++// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#ifndef _GENAPT_HXX
++#define _GENAPT_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++
++#include <Include/compiler.h>
++
++#include STL_STRING
++#include <set>
++
++#ifdef __BORLANDC__
++# define exception c_exception
++#endif
++
++#include <Scenery/tile.hxx>
++
++FG_USING_STD(string);
++FG_USING_STD(set);
++
++
++// maximum size of airport perimeter structure, even for complex
++// airports such as KORD this number is typically not very big.
++#define MAX_PERIMETER 20
++
++// name of the material to use for the airport base
++#define APT_BASE_MATERIAL "grass"
++
++
++// Load a .apt file and register the GL fragments with the
++// corresponding tile
++int
++fgAptGenerate(const string& path, fgTILE *tile);
++
++
++#endif /* _AIRPORTS_HXX */
++
++
++// $Log$
++// Revision 1.3 1999/03/02 01:02:32 curt
++// Tweaks for building with native SGI compilers.
++//
++// Revision 1.2 1998/11/23 21:48:10 curt
++// Borland portability tweaks.
++//
++// Revision 1.1 1998/09/14 02:14:01 curt
++// Initial revision of genapt.[ch]xx for generating airport scenery.
++//
++//
--- /dev/null
--- /dev/null
++//
++// simple.cxx -- a really simplistic class to manage airport ID,
++// lat, lon of the center of one of it's runways, and
++// elevation in feet.
++//
++// Written by Curtis Olson, started April 1998.
++//
++// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#include <Include/compiler.h>
++
++#include <Debug/logstream.hxx>
++#include <Misc/fgstream.hxx>
++#include <Main/options.hxx>
++
++#include STL_STRING
++#include STL_FUNCTIONAL
++#include STL_ALGORITHM
++
++#include "simple.hxx"
++
++
++fgAIRPORTS::fgAIRPORTS() {
++}
++
++
++// load the data
++int fgAIRPORTS::load( const string& file ) {
++ fgAIRPORT a;
++
++ // build the path name to the airport file
++ string path = current_options.get_fg_root() + "/Airports/" + file;
++
++ airports.erase( airports.begin(), airports.end() );
++
++ fg_gzifstream in( path );
++ if ( !in ) {
++ FG_LOG( FG_GENERAL, FG_ALERT, "Cannot open file: " << path );
++ exit(-1);
++ }
++
++ /*
++ // We can use the STL copy algorithm because the input
++ // file doesn't contain and comments or blank lines.
++ copy( istream_iterator<fgAIRPORT,ptrdiff_t>(in.stream()),
++ istream_iterator<fgAIRPORT,ptrdiff_t>(),
++ inserter( airports, airports.begin() ) );
++ */
++
++ // read in each line of the file
++ in >> skipcomment;
++ while ( ! in.eof() )
++ {
++ in >> a;
++ airports.insert(a);
++ in >> skipcomment;
++ }
++
++ return 1;
++}
++
++
++// search for the specified id
++bool
++fgAIRPORTS::search( const string& id, fgAIRPORT* a ) const
++{
++ const_iterator it = airports.find( fgAIRPORT(id) );
++ if ( it != airports.end() )
++ {
++ *a = *it;
++ return true;
++ }
++ else
++ {
++ return false;
++ }
++}
++
++
++fgAIRPORT
++fgAIRPORTS::search( const string& id ) const
++{
++ fgAIRPORT a;
++ this->search( id, &a );
++ return a;
++}
++
++
++// Destructor
++fgAIRPORTS::~fgAIRPORTS( void ) {
++}
++
++
++// $Log$
++// Revision 1.10 1999/02/26 22:08:35 curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.9 1998/11/06 21:17:34 curt
++// Converted to new logstream debugging facility. This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.8 1998/11/06 14:47:01 curt
++// Changes to track Bernie's updates to fgstream.
++//
++// Revision 1.7 1998/09/08 21:38:41 curt
++// Changes by Bernie Bright.
++//
++// Revision 1.6 1998/09/03 21:25:02 curt
++// tweaked in data file comment handling.
++//
++// Revision 1.5 1998/09/02 14:35:38 curt
++// Rewrote simple airport loader so it can deal with comments and blank lines.
++//
++// Revision 1.4 1998/09/01 19:02:53 curt
++// Changes contributed by Bernie Bright <bbright@c031.aone.net.au>
++// - The new classes in libmisc.tgz define a stream interface into zlib.
++// I've put these in a new directory, Lib/Misc. Feel free to rename it
++// to something more appropriate. However you'll have to change the
++// include directives in all the other files. Additionally you'll have
++// add the library to Lib/Makefile.am and Simulator/Main/Makefile.am.
++//
++// The StopWatch class in Lib/Misc requires a HAVE_GETRUSAGE autoconf
++// test so I've included the required changes in config.tgz.
++//
++// There are a fair few changes to Simulator/Objects as I've moved
++// things around. Loading tiles is quicker but thats not where the delay
++// is. Tile loading takes a few tenths of a second per file on a P200
++// but it seems to be the post-processing that leads to a noticeable
++// blip in framerate. I suppose its time to start profiling to see where
++// the delays are.
++//
++// I've included a brief description of each archives contents.
++//
++// Lib/Misc/
++// zfstream.cxx
++// zfstream.hxx
++// C++ stream interface into zlib.
++// Taken from zlib-1.1.3/contrib/iostream/.
++// Minor mods for STL compatibility.
++// There's no copyright associated with these so I assume they're
++// covered by zlib's.
++//
++// fgstream.cxx
++// fgstream.hxx
++// FlightGear input stream using gz_ifstream. Tries to open the
++// given filename. If that fails then filename is examined and a
++// ".gz" suffix is removed or appended and that file is opened.
++//
++// stopwatch.hxx
++// A simple timer for benchmarking. Not used in production code.
++// Taken from the Blitz++ project. Covered by GPL.
++//
++// strutils.cxx
++// strutils.hxx
++// Some simple string manipulation routines.
++//
++// Simulator/Airports/
++// Load airports database using fgstream.
++// Changed fgAIRPORTS to use set<> instead of map<>.
++// Added bool fgAIRPORTS::search() as a neater way doing the lookup.
++// Returns true if found.
++//
++// Simulator/Astro/
++// Modified fgStarsInit() to load stars database using fgstream.
++//
++// Simulator/Objects/
++// Modified fgObjLoad() to use fgstream.
++// Modified fgMATERIAL_MGR::load_lib() to use fgstream.
++// Many changes to fgMATERIAL.
++// Some changes to fgFRAGMENT but I forget what!
++//
++// Revision 1.3 1998/08/27 17:01:55 curt
++// Contributions from Bernie Bright <bbright@c031.aone.net.au>
++// - use strings for fg_root and airport_id and added methods to return
++// them as strings,
++// - inlined all access methods,
++// - made the parsing functions private methods,
++// - deleted some unused functions.
++// - propogated some of these changes out a bit further.
++//
++// Revision 1.2 1998/08/25 20:53:24 curt
++// Shuffled $FG_ROOT file layout.
++//
++// Revision 1.1 1998/08/25 17:19:13 curt
++// Moved from ../Main/
++//
++// Revision 1.8 1998/07/13 21:01:37 curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.7 1998/06/03 22:01:07 curt
++// Tweaking sound library usage.
++//
++// Revision 1.6 1998/06/03 00:47:13 curt
++// Updated to compile in audio support if OSS available.
++// Updated for new version of Steve's audio library.
++// STL includes don't use .h
++// Small view optimizations.
++//
++// Revision 1.5 1998/05/29 20:37:22 curt
++// Tweaked material properties & lighting a bit in GLUTmain.cxx.
++// Read airport list into a "map" STL for dynamic list sizing and fast tree
++// based lookups.
++//
++// Revision 1.4 1998/05/13 18:26:25 curt
++// Root path info moved to fgOPTIONS.
++//
++// Revision 1.3 1998/05/06 03:16:24 curt
++// Added an averaged global frame rate counter.
++// Added an option to control tile radius.
++//
++// Revision 1.2 1998/04/28 21:42:50 curt
++// Wrapped zlib calls up so we can conditionally comment out zlib support.
++//
++// Revision 1.1 1998/04/25 15:11:11 curt
++// Added an command line option to set starting position based on airport ID.
++//
++//
--- /dev/null
--- /dev/null
++//
++// simple.hxx -- a really simplistic class to manage airport ID,
++// lat, lon of the center of one of it's runways, and
++// elevation in feet.
++//
++// Written by Curtis Olson, started April 1998.
++//
++// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#ifndef _AIRPORTS_HXX
++#define _AIRPORTS_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++
++#include <Include/compiler.h>
++#ifdef FG_HAVE_STD_INCLUDES
++# include <istream>
++#else
++# include <istream.h>
++#endif
++
++#include STL_STRING
++#include <set>
++
++FG_USING_STD(string);
++FG_USING_STD(set);
++FG_USING_STD(istream);
++
++
++class fgAIRPORT {
++public:
++ fgAIRPORT( const string& name = "",
++ double lon = 0.0,
++ double lat = 0.0,
++ double ele = 0.0 )
++ : id(name), longitude(lon), latitude(lat), elevation(ele) {}
++
++ bool operator < ( const fgAIRPORT& a ) const {
++ return id < a.id;
++ }
++
++public:
++ string id;
++ double longitude;
++ double latitude;
++ double elevation;
++};
++
++inline istream&
++operator >> ( istream& in, fgAIRPORT& a )
++{
++ return in >> a.id >> a.longitude >> a.latitude >> a.elevation;
++}
++
++class fgAIRPORTS {
++public:
++#ifdef FG_NO_DEFAULT_TEMPLATE_ARGS
++ typedef set< fgAIRPORT, less< fgAIRPORT > > container;
++#else
++ typedef set< fgAIRPORT > container;
++#endif
++ typedef container::iterator iterator;
++ typedef container::const_iterator const_iterator;
++
++private:
++ container airports;
++
++public:
++
++ // Constructor
++ fgAIRPORTS();
++
++ // Destructor
++ ~fgAIRPORTS();
++
++ // load the data
++ int load( const string& file );
++
++ // search for the specified id.
++ // Returns true if successful, otherwise returns false.
++ // On success, airport data is returned thru "airport" pointer.
++ // "airport" is not changed if "id" is not found.
++ bool search( const string& id, fgAIRPORT* airport ) const;
++ fgAIRPORT search( const string& id ) const;
++};
++
++
++#endif /* _AIRPORTS_HXX */
++
++
++// $Log$
++// Revision 1.8 1999/03/15 17:58:57 curt
++// MSVC++ portability tweaks contributed by Bernie Bright.
++// Added using std::istream declaration.
++//
++// Revision 1.7 1999/03/02 01:02:33 curt
++// Tweaks for building with native SGI compilers.
++//
++// Revision 1.6 1999/02/26 22:08:36 curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.5 1998/11/02 18:25:34 curt
++// Check for __CYGWIN__ (b20) as well as __CYGWIN32__ (pre b20 compilers)
++// Other misc. tweaks.
++//
++// Revision 1.4 1998/09/08 21:38:43 curt
++// Changes by Bernie Bright.
++//
++// Revision 1.3 1998/09/01 19:02:54 curt
++// Changes contributed by Bernie Bright <bbright@c031.aone.net.au>
++// - The new classes in libmisc.tgz define a stream interface into zlib.
++// I've put these in a new directory, Lib/Misc. Feel free to rename it
++// to something more appropriate. However you'll have to change the
++// include directives in all the other files. Additionally you'll have
++// add the library to Lib/Makefile.am and Simulator/Main/Makefile.am.
++//
++// The StopWatch class in Lib/Misc requires a HAVE_GETRUSAGE autoconf
++// test so I've included the required changes in config.tgz.
++//
++// There are a fair few changes to Simulator/Objects as I've moved
++// things around. Loading tiles is quicker but thats not where the delay
++// is. Tile loading takes a few tenths of a second per file on a P200
++// but it seems to be the post-processing that leads to a noticeable
++// blip in framerate. I suppose its time to start profiling to see where
++// the delays are.
++//
++// I've included a brief description of each archives contents.
++//
++// Lib/Misc/
++// zfstream.cxx
++// zfstream.hxx
++// C++ stream interface into zlib.
++// Taken from zlib-1.1.3/contrib/iostream/.
++// Minor mods for STL compatibility.
++// There's no copyright associated with these so I assume they're
++// covered by zlib's.
++//
++// fgstream.cxx
++// fgstream.hxx
++// FlightGear input stream using gz_ifstream. Tries to open the
++// given filename. If that fails then filename is examined and a
++// ".gz" suffix is removed or appended and that file is opened.
++//
++// stopwatch.hxx
++// A simple timer for benchmarking. Not used in production code.
++// Taken from the Blitz++ project. Covered by GPL.
++//
++// strutils.cxx
++// strutils.hxx
++// Some simple string manipulation routines.
++//
++// Simulator/Airports/
++// Load airports database using fgstream.
++// Changed fgAIRPORTS to use set<> instead of map<>.
++// Added bool fgAIRPORTS::search() as a neater way doing the lookup.
++// Returns true if found.
++//
++// Simulator/Astro/
++// Modified fgStarsInit() to load stars database using fgstream.
++//
++// Simulator/Objects/
++// Modified fgObjLoad() to use fgstream.
++// Modified fgMATERIAL_MGR::load_lib() to use fgstream.
++// Many changes to fgMATERIAL.
++// Some changes to fgFRAGMENT but I forget what!
++//
++// Revision 1.2 1998/08/27 17:01:56 curt
++// Contributions from Bernie Bright <bbright@c031.aone.net.au>
++// - use strings for fg_root and airport_id and added methods to return
++// them as strings,
++// - inlined all access methods,
++// - made the parsing functions private methods,
++// - deleted some unused functions.
++// - propogated some of these changes out a bit further.
++//
++// Revision 1.1 1998/08/25 17:19:14 curt
++// Moved from ../Main/
++//
++// Revision 1.7 1998/07/24 21:39:09 curt
++// Debugging output tweaks.
++// Cast glGetString to (char *) to avoid compiler errors.
++// Optimizations to fgGluLookAt() by Norman Vine.
++//
++// Revision 1.6 1998/07/06 21:34:19 curt
++// Added an enable/disable splash screen option.
++// Added an enable/disable intro music option.
++// Added an enable/disable instrument panel option.
++// Added an enable/disable mouse pointer option.
++// Added using namespace std for compilers that support this.
++//
++// Revision 1.5 1998/06/17 21:35:11 curt
++// Refined conditional audio support compilation.
++// Moved texture parameter setup calls to ../Scenery/materials.cxx
++// #include <string.h> before various STL includes.
++// Make HUD default state be enabled.
++//
++// Revision 1.4 1998/06/03 00:47:14 curt
++// Updated to compile in audio support if OSS available.
++// Updated for new version of Steve's audio library.
++// STL includes don't use .h
++// Small view optimizations.
++//
++// Revision 1.3 1998/06/01 17:54:42 curt
++// Added Linux audio support.
++// avoid glClear( COLOR_BUFFER_BIT ) when not using it to set the sky color.
++// map stl tweaks.
++//
++// Revision 1.2 1998/05/29 20:37:22 curt
++// Tweaked material properties & lighting a bit in GLUTmain.cxx.
++// Read airport list into a "map" STL for dynamic list sizing and fast tree
++// based lookups.
++//
++// Revision 1.1 1998/04/25 15:11:11 curt
++// Added an command line option to set starting position based on airport ID.
++//
++//
--- /dev/null
--- /dev/null
++noinst_LIBRARIES = libAstro.a
++
++libAstro_a_SOURCES = \
++ celestialBody.cxx celestialBody.hxx \
++ jupiter.cxx jupiter.hxx \
++ mars.cxx mars.hxx \
++ mercury.cxx mercury.hxx \
++ moon.cxx moon.hxx \
++ neptune.cxx neptune.hxx \
++ pluto.hxx \
++ saturn.cxx saturn.hxx \
++ sky.cxx sky.hxx \
++ solarsystem.cxx solarsystem.hxx \
++ star.cxx star.hxx \
++ stars.cxx stars.hxx \
++ uranus.cxx uranus.hxx \
++ venus.cxx venus.hxx
++
++INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib -I$(top_builddir)/Simulator
--- /dev/null
--- /dev/null
++/**************************************************************************
++ * celestialBody.cxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution
++ * with the FlightGear project. Version 2 was written in August and
++ * September 1998. This code is based upon algorithms and data kindly
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se).
++ *
++ * 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$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++#include "celestialBody.hxx"
++#include "star.hxx"
++#include <Debug/logstream.hxx>
++
++#ifdef FG_MATH_EXCEPTION_CLASH
++# define exception c_exception
++#endif
++#include <math.h>
++
++/**************************************************************************
++ * void CelestialBody::updatePosition(fgTIME *t, Star *ourSun)
++ *
++ * Basically, this member function provides a general interface for
++ * calculating the right ascension and declinaion. This function is
++ * used for calculating the planetary positions. For the planets, an
++ * overloaded member function is provided to additionally calculate the
++ * planet's magnitude.
++ * The sun and moon have their own overloaded updatePosition member, as their
++ * position is calculated an a slightly different manner.
++ *
++ * arguments:
++ * fgTIME t: provides the current time.
++ * Star *ourSun: the sun's position is needed to convert heliocentric
++ * coordinates into geocentric coordinates.
++ *
++ * return value: none
++ *
++ *************************************************************************/
++void CelestialBody::updatePosition(fgTIME *t, Star *ourSun)
++{
++ double eccAnom, v, ecl, actTime,
++ xv, yv, xh, yh, zh, xg, yg, zg, xe, ye, ze;
++
++ updateOrbElements(t);
++ actTime = fgCalcActTime(t);
++
++ // calcualate the angle bewteen ecliptic and equatorial coordinate system
++ ecl = DEG_TO_RAD * (23.4393 - 3.563E-7 *actTime);
++
++ eccAnom = fgCalcEccAnom(M, e); //calculate the eccentric anomaly
++ xv = a * (cos(eccAnom) - e);
++ yv = a * (sqrt (1.0 - e*e) * sin(eccAnom));
++ v = atan2(yv, xv); // the planet's true anomaly
++ r = sqrt (xv*xv + yv*yv); // the planet's distance
++
++ // calculate the planet's position in 3D space
++ xh = r * (cos(N) * cos(v+w) - sin(N) * sin(v+w) * cos(i));
++ yh = r * (sin(N) * cos(v+w) + cos(N) * sin(v+w) * cos(i));
++ zh = r * (sin(v+w) * sin(i));
++
++ // calculate the ecliptic longitude and latitude
++ xg = xh + ourSun->getxs();
++ yg = yh + ourSun->getys();
++ zg = zh;
++
++ lonEcl = atan2(yh, xh);
++ latEcl = atan2(zh, sqrt(xh*xh+yh*yh));
++
++ xe = xg;
++ ye = yg * cos(ecl) - zg * sin(ecl);
++ ze = yg * sin(ecl) + zg * cos(ecl);
++ rightAscension = atan2(ye, xe);
++ declination = atan2(ze, sqrt(xe*xe + ye*ye));
++ FG_LOG(FG_GENERAL, FG_INFO, "Planet found at : "
++ << rightAscension << " (ra), " << declination << " (dec)" );
++
++ //calculate some variables specific to calculating the magnitude
++ //of the planet
++ R = sqrt (xg*xg + yg*yg + zg*zg);
++ s = ourSun->getDistance();
++
++ // It is possible from these calculations for the argument to acos
++ // to exceed the valid range for acos(). So we do a little extra
++ // checking.
++
++ double tmp = (r*r + R*R - s*s) / (2*r*R);
++ if ( tmp > 1.0) {
++ tmp = 1.0;
++ } else if ( tmp < -1.0) {
++ tmp = -1.0;
++ }
++
++ FV = RAD_TO_DEG * acos( tmp );
++};
++
++/****************************************************************************
++ * double CelestialBody::fgCalcEccAnom(double M, double e)
++ * this private member calculates the eccentric anomaly of a celestial body,
++ * given its mean anomaly and eccentricity.
++ *
++ * -Mean anomaly: the approximate angle between the perihelion and the current
++ * position. this angle increases uniformly with time.
++ *
++ * True anomaly: the actual angle between perihelion and current position.
++ *
++ * Eccentric anomaly: this is an auxilary angle, used in calculating the true
++ * anomaly from the mean anomaly.
++ *
++ * -eccentricity. Indicates the amount in which the orbit deviates from a
++ * circle (0 = circle, 0-1, is ellipse, 1 = parabola, > 1 = hyperbola).
++ *
++ * This function is also known as solveKeplersEquation()
++ *
++ * arguments:
++ * M: the mean anomaly
++ * e: the eccentricity
++ *
++ * return value:
++ * the eccentric anomaly
++ *
++ ****************************************************************************/
++double CelestialBody::fgCalcEccAnom(double M, double e)
++{
++ double
++ eccAnom, E0, E1, diff;
++
++ eccAnom = M + e * sin(M) * (1.0 + e * cos (M));
++ // iterate to achieve a greater precision for larger eccentricities
++ if (e > 0.05)
++ {
++ E0 = eccAnom;
++ do
++ {
++ E1 = E0 - (E0 - e * sin(E0) - M) / (1 - e *cos(E0));
++ diff = fabs(E0 - E1);
++ E0 = E1;
++ }
++ while (diff > (DEG_TO_RAD * 0.001));
++ return E0;
++ }
++ return eccAnom;
++}
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
--- /dev/null
--- /dev/null
++/**************************************************************************
++ * celestialBody.hxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution
++ * with the FlightGear project. Version 2 was written in August and
++ * September 1998. This code is based upon algorithms and data kindly
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se).
++ *
++ * 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$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++
++#ifndef _CELESTIALBODY_H_
++#define _CELESTIALBODY_H_
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++
++#include <Time/fg_time.hxx>
++#include <Include/fg_constants.h>
++
++class Star;
++
++class CelestialBody
++{
++protected: // make the data protected, in order to give the inherited
++ // classes direct access to the data
++ double NFirst; /* longitude of the ascending node first part */
++ double NSec; /* longitude of the ascending node second part */
++ double iFirst; /* inclination to the ecliptic first part */
++ double iSec; /* inclination to the ecliptic second part */
++ double wFirst; /* first part of argument of perihelion */
++ double wSec; /* second part of argument of perihelion */
++ double aFirst; /* semimayor axis first part*/
++ double aSec; /* semimayor axis second part */
++ double eFirst; /* eccentricity first part */
++ double eSec; /* eccentricity second part */
++ double MFirst; /* Mean anomaly first part */
++ double MSec; /* Mean anomaly second part */
++
++ double N, i, w, a, e, M; /* the resulting orbital elements, obtained from the former */
++
++ double rightAscension, declination;
++ double r, R, s, FV;
++ double magnitude;
++ double lonEcl, latEcl;
++
++ double fgCalcEccAnom(double M, double e);
++ double fgCalcActTime(fgTIME *t);
++ void updateOrbElements(fgTIME *t);
++
++public:
++ CelestialBody(double Nf, double Ns,
++ double If, double Is,
++ double wf, double ws,
++ double af, double as,
++ double ef, double es,
++ double Mf, double Ms, fgTIME *t);
++ void getPos(double *ra, double *dec);
++ void getPos(double *ra, double *dec, double *magnitude);
++ double getLon();
++ double getLat();
++ void updatePosition(fgTIME *t, Star *ourSun);
++};
++
++/*****************************************************************************
++ * inline CelestialBody::CelestialBody
++ * public constructor for a generic celestialBody object.
++ * initializes the 6 primary orbital elements. The elements are:
++ * N: longitude of the ascending node
++ * i: inclination to the ecliptic
++ * w: argument of perihelion
++ * a: semi-major axis, or mean distance from the sun
++ * e: eccenticity
++ * M: mean anomaly
++ * Each orbital element consists of a constant part and a variable part that
++ * gradually changes over time.
++ *
++ * Argumetns:
++ * the 13 arguments to the constructor constitute the first, constant
++ * ([NiwaeM]f) and the second variable ([NiwaeM]s) part of the orbital
++ * elements. The 13th argument is the current time. Note that the inclination
++ * is written with a capital (If, Is), because 'if' is a reserved word in the
++ * C/C++ programming language.
++ ***************************************************************************/
++inline CelestialBody::CelestialBody(double Nf, double Ns,
++ double If, double Is,
++ double wf, double ws,
++ double af, double as,
++ double ef, double es,
++ double Mf, double Ms, fgTIME *t)
++{
++ NFirst = Nf; NSec = Ns;
++ iFirst = If; iSec = Is;
++ wFirst = wf; wSec = ws;
++ aFirst = af; aSec = as;
++ eFirst = ef; eSec = es;
++ MFirst = Mf; MSec = Ms;
++ updateOrbElements(t);
++};
++
++/****************************************************************************
++ * inline void CelestialBody::updateOrbElements(fgTIME *t)
++ * given the current time, this private member calculates the actual
++ * orbital elements
++ *
++ * Arguments: fgTIME *t: the current time:
++ *
++ * return value: none
++ ***************************************************************************/
++inline void CelestialBody::updateOrbElements(fgTIME *t)
++{
++ double actTime = fgCalcActTime(t);
++ M = DEG_TO_RAD * (MFirst + (MSec * actTime));
++ w = DEG_TO_RAD * (wFirst + (wSec * actTime));
++ N = DEG_TO_RAD * (NFirst + (NSec * actTime));
++ i = DEG_TO_RAD * (iFirst + (iSec * actTime));
++ e = eFirst + (eSec * actTime);
++ a = aFirst + (aSec * actTime);
++}
++/*****************************************************************************
++ * inline double CelestialBody::fgCalcActTime(fgTIME *t)
++ * this private member function returns the offset in days from the epoch for
++ * wich the orbital elements are calculated (Jan, 1st, 2000).
++ *
++ * Argument: the current time
++ *
++ * return value: the (fractional) number of days until Jan 1, 2000.
++ ****************************************************************************/
++inline double CelestialBody::fgCalcActTime(fgTIME *t)
++{
++ return (t->mjd - 36523.5);
++}
++
++/*****************************************************************************
++ * inline void CelestialBody::getPos(double* ra, double* dec)
++ * gives public access to Right Ascension and declination
++ *
++ ****************************************************************************/
++inline void CelestialBody::getPos(double* ra, double* dec)
++{
++ *ra = rightAscension;
++ *dec = declination;
++}
++
++/*****************************************************************************
++ * inline void CelestialBody::getPos(double* ra, double* dec, double* magnitude
++ * gives public acces to the current Right ascension, declination, and
++ * magnitude
++ ****************************************************************************/
++inline void CelestialBody::getPos(double* ra, double* dec, double* magn)
++{
++ *ra = rightAscension;
++ *dec = declination;
++ *magn = magnitude;
++}
++
++inline double CelestialBody::getLon()
++{
++ return lonEcl;
++}
++
++inline double CelestialBody::getLat()
++{
++ return latEcl;
++}
++
++#endif // _CELESTIALBODY_H_
++
++
++
++
++
++
++
++
++
++
++
++
--- /dev/null
--- /dev/null
++/**************************************************************************
++ * jupiter.cxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution
++ * with the FlightGear project. Version 2 was written in August and
++ * September 1998. This code is based upon algorithms and data kindly
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se).
++ *
++ * 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$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++
++#ifdef __BORLANDC__
++# define exception c_exception
++#endif
++#include <math.h>
++
++#include "jupiter.hxx"
++
++/*************************************************************************
++ * Jupiter::Jupiter(fgTIME *t)
++ * Public constructor for class Jupiter
++ * Argument: The current time.
++ * the hard coded orbital elements for Jupiter are passed to
++ * CelestialBody::CelestialBody();
++ ************************************************************************/
++Jupiter::Jupiter(fgTIME *t) :
++ CelestialBody(100.4542, 2.7685400E-5,
++ 1.3030, -1.557E-7,
++ 273.8777, 1.6450500E-5,
++ 5.2025600, 0.000000,
++ 0.048498, 4.469E-9,
++ 19.89500, 0.08308530010, t)
++{
++}
++
++/*************************************************************************
++ * void Jupiter::updatePosition(fgTIME *t, Star *ourSun)
++ *
++ * calculates the current position of Jupiter, by calling the base class,
++ * CelestialBody::updatePosition(); The current magnitude is calculated using
++ * a Jupiter specific equation
++ *************************************************************************/
++void Jupiter::updatePosition(fgTIME *t, Star *ourSun)
++{
++ CelestialBody::updatePosition(t, ourSun);
++ magnitude = -9.25 + 5*log10( r*R ) + 0.014 * FV;
++}
++
++
++
++
--- /dev/null
--- /dev/null
++/**************************************************************************
++ * jupiter.hxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution
++ * with the FlightGear project. Version 2 was written in August and
++ * September 1998. This code is based upon algorithms and data kindly
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se).
++ *
++ * 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$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++#ifndef _JUPITER_HXX_
++#define _JUPITER_HXX_
++
++#include <Time/fg_time.hxx>
++#include "celestialBody.hxx"
++#include "star.hxx"
++
++class Jupiter : public CelestialBody
++{
++public:
++ Jupiter (fgTIME *t);
++ void updatePosition(fgTIME *t, Star *ourSun);
++};
++
++#endif // _JUPITER_HXX_
--- /dev/null
--- /dev/null
++/**************************************************************************
++ * mars.cxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution
++ * with the FlightGear project. Version 2 was written in August and
++ * September 1998. This code is based upon algorithms and data kindly
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se).
++ *
++ * 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$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++#ifdef __BORLANDC__
++# define exception c_exception
++#endif
++#include <math.h>
++
++#include "mars.hxx"
++
++/*************************************************************************
++ * Mars::Mars(fgTIME *t)
++ * Public constructor for class Mars
++ * Argument: The current time.
++ * the hard coded orbital elements for Mars are passed to
++ * CelestialBody::CelestialBody();
++ ************************************************************************/
++Mars::Mars(fgTIME *t) :
++ CelestialBody(49.55740, 2.1108100E-5,
++ 1.8497, -1.78E-8,
++ 286.5016, 2.9296100E-5,
++ 1.5236880, 0.000000,
++ 0.093405, 2.516E-9,
++ 18.60210, 0.52402077660, t)
++{
++}
++/*************************************************************************
++ * void Mars::updatePosition(fgTIME *t, Star *ourSun)
++ *
++ * calculates the current position of Mars, by calling the base class,
++ * CelestialBody::updatePosition(); The current magnitude is calculated using
++ * a Mars specific equation
++ *************************************************************************/
++void Mars::updatePosition(fgTIME *t, Star *ourSun)
++{
++ CelestialBody::updatePosition(t, ourSun);
++ magnitude = -1.51 + 5*log10( r*R ) + 0.016 * FV;
++}
--- /dev/null
--- /dev/null
++/**************************************************************************
++ * mars.hxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution
++ * with the FlightGear project. Version 2 was written in August and
++ * September 1998. This code is based upon algorithms and data kindly
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se).
++ *
++ * 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$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++#ifndef _MARS_HXX_
++#define _MARS_HXX_
++
++#include <Time/fg_time.hxx>
++#include "celestialBody.hxx"
++#include "star.hxx"
++
++class Mars : public CelestialBody
++{
++public:
++ Mars ( fgTIME *t);
++ void updatePosition(fgTIME *t, Star *ourSun);
++};
++
++#endif // _MARS_HXX_
--- /dev/null
--- /dev/null
++/**************************************************************************
++ * mercury.cxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution
++ * with the FlightGear project. Version 2 was written in August and
++ * September 1998. This code is based upon algorithms and data kindly
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se).
++ *
++ * 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$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++#ifdef __BORLANDC__
++# define exception c_exception
++#endif
++#include <math.h>
++
++#include "mercury.hxx"
++
++/*************************************************************************
++ * Mercury::Mercury(fgTIME *t)
++ * Public constructor for class Mercury
++ * Argument: The current time.
++ * the hard coded orbital elements for Mercury are passed to
++ * CelestialBody::CelestialBody();
++ ************************************************************************/
++Mercury::Mercury(fgTIME *t) :
++ CelestialBody (48.33130, 3.2458700E-5,
++ 7.0047, 5.00E-8,
++ 29.12410, 1.0144400E-5,
++ 0.3870980, 0.000000,
++ 0.205635, 5.59E-10,
++ 168.6562, 4.09233443680, t)
++{
++}
++/*************************************************************************
++ * void Mercury::updatePosition(fgTIME *t, Star *ourSun)
++ *
++ * calculates the current position of Mercury, by calling the base class,
++ * CelestialBody::updatePosition(); The current magnitude is calculated using
++ * a Mercury specific equation
++ *************************************************************************/
++void Mercury::updatePosition(fgTIME *t, Star *ourSun)
++{
++ CelestialBody::updatePosition(t, ourSun);
++ magnitude = -0.36 + 5*log10( r*R ) + 0.027 * FV + 2.2E-13 * pow(FV, 6);
++}
++
++
--- /dev/null
--- /dev/null
++/**************************************************************************
++ * mercury.hxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution
++ * with the FlightGear project. Version 2 was written in August and
++ * September 1998. This code is based upon algorithms and data kindly
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se).
++ *
++ * 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$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++#ifndef _MERCURY_HXX_
++#define _MERCURY_HXX_
++
++#include <Time/fg_time.hxx>
++#include "celestialBody.hxx"
++#include "star.hxx"
++
++class Mercury : public CelestialBody
++{
++public:
++ Mercury ( fgTIME *t);
++ void updatePosition(fgTIME *t, Star* ourSun);
++};
++
++#endif // _MERURY_HXX_
--- /dev/null
--- /dev/null
++/**************************************************************************
++ * moon.cxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution
++ * with the FlightGear project. Version 2 was written in August and
++ * September 1998. This code is based upon algorithms and data kindly
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se).
++ *
++ * 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$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++#include <FDM/flight.hxx>
++
++#include <string.h>
++#include "moon.hxx"
++
++#include <Debug/logstream.hxx>
++#include <Objects/texload.h>
++
++#ifdef __BORLANDC__
++# define exception c_exception
++#endif
++#include <math.h>
++
++
++/*************************************************************************
++ * Moon::Moon(fgTIME *t)
++ * Public constructor for class Moon. Initializes the orbital elements and
++ * sets up the moon texture.
++ * Argument: The current time.
++ * the hard coded orbital elements for Moon are passed to
++ * CelestialBody::CelestialBody();
++ ************************************************************************/
++Moon::Moon(fgTIME *t) :
++ CelestialBody(125.1228, -0.0529538083,
++ 5.1454, 0.00000,
++ 318.0634, 0.1643573223,
++ 60.266600, 0.000000,
++ 0.054900, 0.000000,
++ 115.3654, 13.0649929509, t)
++{
++ string tpath, fg_tpath;
++ int width, height;
++
++ FG_LOG( FG_GENERAL, FG_INFO, "Initializing Moon Texture");
++#ifdef GL_VERSION_1_1
++ xglGenTextures(1, &moon_texid);
++ xglBindTexture(GL_TEXTURE_2D, moon_texid);
++#elif GL_EXT_texture_object
++ xglGenTexturesEXT(1, &moon_texid);
++ xglBindTextureEXT(GL_TEXTURE_2D, moon_texid);
++#else
++# error port me
++#endif
++
++ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
++ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
++ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
++
++ // load in the texture data
++ tpath = current_options.get_fg_root() + "/Textures/" + "moon.rgb";
++
++ if ( (moon_texbuf = read_rgb_texture(tpath.c_str(), &width, &height))
++ == NULL )
++ {
++ // Try compressed
++ fg_tpath = tpath + ".gz";
++ if ( (moon_texbuf = read_rgb_texture(fg_tpath.c_str(), &width, &height))
++ == NULL )
++ {
++ FG_LOG( FG_GENERAL, FG_ALERT,
++ "Error in loading moon texture " << tpath );
++ exit(-1);
++ }
++ }
++
++ glTexImage2D( GL_TEXTURE_2D,
++ 0,
++ GL_RGB,
++ 256, 256,
++ 0,
++ GL_RGB, GL_UNSIGNED_BYTE,
++ moon_texbuf);
++
++ // setup the halo texture
++ FG_LOG( FG_GENERAL, FG_INFO, "Initializing Moon Texture");
++#ifdef GL_VERSION_1_1
++ xglGenTextures(1, &moon_halotexid);
++ xglBindTexture(GL_TEXTURE_2D, moon_halotexid);
++#elif GL_EXT_texture_object
++ xglGenTexturesEXT(1, &moon_halotexid);
++ xglBindTextureEXT(GL_TEXTURE_2D, moon_halotexid);
++#else
++# error port me
++#endif
++
++ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
++ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
++ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
++ setHalo();
++ glTexImage2D( GL_TEXTURE_2D,
++ 0,
++ GL_RGBA,
++ 256, 256,
++ 0,
++ GL_RGBA, GL_UNSIGNED_BYTE,
++ moon_halotexbuf);
++ moonObject = gluNewQuadric();
++}
++
++Moon::~Moon()
++{
++ //delete moonObject;
++ delete moon_texbuf;
++ delete moon_halotexbuf;
++}
++
++
++static int texWidth = 256; /* 64x64 is plenty */
++
++void Moon::setHalo()
++{
++ int texSize;
++ //void *textureBuf;
++ GLubyte *p;
++ int i,j;
++ double radius;
++
++ texSize = texWidth*texWidth;
++
++ moon_halotexbuf = new GLubyte[texSize*4];
++ if (!moon_halotexbuf)
++ return; // Ugly!
++
++ p = moon_halotexbuf;
++
++ radius = (double)(texWidth / 2);
++
++ for (i=0; i < texWidth; i++) {
++ for (j=0; j < texWidth; j++) {
++ double x, y, d;
++
++ x = fabs((double)(i - (texWidth / 2)));
++ y = fabs((double)(j - (texWidth / 2)));
++
++ d = sqrt((x * x) + (y * y));
++ if (d < radius)
++ {
++ double t = 1.0 - (d / radius); // t is 1.0 at center, 0.0 at edge */
++ // inverse square looks nice
++ *p = (int)((double)0xff * (t * t));
++ *(p+1) = (int)((double) 0xff * (t*t));
++ *(p+2) = (int)((double) 0xff * (t*t));
++ *(p+3) = 0x11;
++ }
++ else
++ {
++ *p = 0x00;
++ *(p+1) = 0x00;
++ *(p+2) = 0x00;
++ *(p+3) = 0x11;
++ }
++ p += 4;
++ }
++ }
++ //gluBuild2DMipmaps(GL_TEXTURE_2D, 1, texWidth, texWidth,
++ // GL_LUMINANCE,
++ // GL_UNSIGNED_BYTE, textureBuf);
++ //free(textureBuf);
++}
++
++
++/*****************************************************************************
++ * void Moon::updatePosition(fgTIME *t, Star *ourSun)
++ * this member function calculates the actual topocentric position (i.e.)
++ * the position of the moon as seen from the current position on the surface
++ * of the moon.
++ ****************************************************************************/
++void Moon::updatePosition(fgTIME *t, Star *ourSun)
++{
++ double
++ eccAnom, ecl, actTime,
++ xv, yv, v, r, xh, yh, zh, xg, yg, zg, xe, ye, ze,
++ Ls, Lm, D, F, mpar, gclat, rho, HA, g,
++ geoRa, geoDec;
++
++ fgAIRCRAFT *air;
++ FGInterface *f;
++
++ air = ¤t_aircraft;
++ f = air->fdm_state;
++
++ updateOrbElements(t);
++ actTime = fgCalcActTime(t);
++
++ // calculate the angle between ecliptic and equatorial coordinate system
++ // in Radians
++ ecl = ((DEG_TO_RAD * 23.4393) - (DEG_TO_RAD * 3.563E-7) * actTime);
++ eccAnom = fgCalcEccAnom(M, e); // Calculate the eccentric anomaly
++ xv = a * (cos(eccAnom) - e);
++ yv = a * (sqrt(1.0 - e*e) * sin(eccAnom));
++ v = atan2(yv, xv); // the moon's true anomaly
++ r = sqrt (xv*xv + yv*yv); // and its distance
++
++ // estimate the geocentric rectangular coordinates here
++ xh = r * (cos(N) * cos (v+w) - sin (N) * sin(v+w) * cos(i));
++ yh = r * (sin(N) * cos (v+w) + cos (N) * sin(v+w) * cos(i));
++ zh = r * (sin(v+w) * sin(i));
++
++ // calculate the ecliptic latitude and longitude here
++ lonEcl = atan2 (yh, xh);
++ latEcl = atan2(zh, sqrt(xh*xh + yh*yh));
++
++ /* Calculate a number of perturbatioin, i.e. disturbances caused by the
++ * gravitational infuence of the sun and the other major planets.
++ * The largest of these even have a name */
++ Ls = ourSun->getM() + ourSun->getw();
++ Lm = M + w + N;
++ D = Lm - Ls;
++ F = Lm - N;
++
++ lonEcl += DEG_TO_RAD * (-1.274 * sin (M - 2*D)
++ +0.658 * sin (2*D)
++ -0.186 * sin(ourSun->getM())
++ -0.059 * sin(2*M - 2*D)
++ -0.057 * sin(M - 2*D + ourSun->getM())
++ +0.053 * sin(M + 2*D)
++ +0.046 * sin(2*D - ourSun->getM())
++ +0.041 * sin(M - ourSun->getM())
++ -0.035 * sin(D)
++ -0.031 * sin(M + ourSun->getM())
++ -0.015 * sin(2*F - 2*D)
++ +0.011 * sin(M - 4*D)
++ );
++ latEcl += DEG_TO_RAD * (-0.173 * sin(F-2*D)
++ -0.055 * sin(M - F - 2*D)
++ -0.046 * sin(M + F - 2*D)
++ +0.033 * sin(F + 2*D)
++ +0.017 * sin(2*M + F)
++ );
++ r += (-0.58 * cos(M - 2*D)
++ -0.46 * cos(2*D)
++ );
++ FG_LOG(FG_GENERAL, FG_INFO, "Running moon update");
++ xg = r * cos(lonEcl) * cos(latEcl);
++ yg = r * sin(lonEcl) * cos(latEcl);
++ zg = r * sin(latEcl);
++
++ xe = xg;
++ ye = yg * cos(ecl) -zg * sin(ecl);
++ ze = yg * sin(ecl) +zg * cos(ecl);
++
++ geoRa = atan2(ye, xe);
++ geoDec = atan2(ze, sqrt(xe*xe + ye*ye));
++
++ // Given the moon's geocentric ra and dec, calculate its
++ // topocentric ra and dec. i.e. the position as seen from the
++ // surface of the earth, instead of the center of the earth
++
++ // First calculate the moon's parrallax, that is, the apparent size of the
++ // (equatorial) radius of the earth, as seen from the moon
++ mpar = asin ( 1 / r);
++ gclat = f->get_Latitude() - 0.003358 *
++ sin (2 * DEG_TO_RAD * f->get_Latitude() );
++ rho = 0.99883 + 0.00167 * cos(2 * DEG_TO_RAD * f->get_Latitude());
++ if (geoRa < 0)
++ geoRa += (2*FG_PI);
++
++ HA = t->lst - (3.8197186 * geoRa);
++ g = atan (tan(gclat) / cos ((HA / 3.8197186)));
++ rightAscension = geoRa - mpar * rho * cos(gclat) * sin(HA) / cos (geoDec);
++ declination = geoDec - mpar * rho * sin (gclat) * sin (g - geoDec) / sin(g);
++}
++
++
++/************************************************************************
++ * void Moon::newImage()
++ *
++ * This function regenerates a new visual image of the moon, which is added to
++ * solarSystem display list.
++ *
++ * Arguments: Right Ascension and declination
++ *
++ * return value: none
++ **************************************************************************/
++void Moon::newImage()
++{
++ fgLIGHT *l = &cur_light_params;
++ float moon_angle = l->moon_angle;
++
++ /*double x_2, x_4, x_8, x_10;
++ GLfloat ambient;
++ GLfloat amb[4];*/
++ int moonSize = 750;
++
++ GLfloat moonColor[4] = {0.85, 0.75, 0.35, 1.0};
++ GLfloat black[4] = {0.0, 0.0,0.0,1.0};
++ GLfloat white[4] = {1.0, 1.0,1.0,1.0};
++
++ if( moon_angle*RAD_TO_DEG < 100 )
++ {
++ /*
++ x_2 = moon_angle * moon_angle;
++ x_4 = x_2 * x_2;
++ x_8 = x_4 * x_4;
++ x_10 = x_8 * x_2;
++ ambient = (float)(0.4 * pow (1.1, - x_10 / 30.0));
++ if (ambient < 0.3) ambient = 0.3;
++ if (ambient > 1.0) ambient = 1.0;
++
++ amb[0] = ((ambient * 6.0) - 1.0); // minimum value = 0.8
++ amb[1] = ((ambient * 11.0) - 3.0); // minimum value = 0.3
++ amb[2] = ((ambient * 12.0) - 3.6); // minimum value = 0.0
++ amb[3] = 1.00;
++
++ if (amb[0] > 1.0) amb[0] = 1.0;
++ if (amb[1] > 1.0) amb[1] = 1.0;
++ if (amb[2] > 1.0) amb[2] = 1.0;
++ xglColor3fv(amb);
++ xglColor3f(1.0, 1.0, 1.0); */
++ xglPushMatrix();
++ {
++ //xglRotatef(-90, 0.0, 0.0, 1.0);
++ xglRotatef(((RAD_TO_DEG * rightAscension)- 90.0), 0.0, 0.0, 1.0);
++ xglRotatef((RAD_TO_DEG * declination), 1.0, 0.0, 0.0);
++
++ FG_LOG( FG_GENERAL, FG_INFO,
++ "Ra = (" << (RAD_TO_DEG *rightAscension)
++ << "), Dec= (" << (RAD_TO_DEG *declination) << ")" );
++ xglTranslatef(0.0, 58600.0, 0.0);
++
++ glEnable(GL_TEXTURE_2D); // TEXTURE ENABLED
++ glEnable(GL_BLEND); // BLEND ENABLED
++ glBlendFunc(GL_SRC_ALPHA, GL_ONE);
++ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
++ glBindTexture(GL_TEXTURE_2D, moon_halotexid);
++
++ glBegin(GL_QUADS);
++ glTexCoord2f(0.0f, 0.0f); glVertex3f(-5000, 0.0, -5000);
++ glTexCoord2f(1.0f, 0.0f); glVertex3f( 5000, 0.0, -5000);
++ glTexCoord2f(1.0f, 1.0f); glVertex3f( 5000, 0.0, 5000);
++ glTexCoord2f(0.0f, 1.0f); glVertex3f(-5000, 0.0, 5000);
++ glEnd();
++
++ xglEnable(GL_LIGHTING); // LIGHTING ENABLED
++ xglEnable( GL_LIGHT0 );
++ // set lighting parameters
++ xglLightfv(GL_LIGHT0, GL_AMBIENT, white );
++ xglLightfv(GL_LIGHT0, GL_DIFFUSE, white );
++ xglEnable( GL_CULL_FACE );
++ xglMaterialfv(GL_FRONT, GL_AMBIENT, black);
++ xglMaterialfv(GL_FRONT, GL_DIFFUSE, moonColor);
++
++ //glEnable(GL_TEXTURE_2D);
++ glBlendFunc(GL_ONE, GL_ONE);
++
++ //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
++ glBindTexture(GL_TEXTURE_2D, moon_texid);
++ //glDisable(GL_LIGHTING); // LIGHTING DISABLED
++
++ gluQuadricTexture(moonObject, GL_TRUE );
++ gluSphere(moonObject, moonSize, 12, 12 );
++ glDisable(GL_TEXTURE_2D); // TEXTURE DISABLED
++ glDisable(GL_BLEND); // BLEND DISABLED
++ }
++ xglPopMatrix();
++ glDisable(GL_LIGHTING); // LIGHTING DISABLED
++
++ }
++ else
++ {
++ }
++}
++
++
++
++
++
++
++
--- /dev/null
--- /dev/null
++/**************************************************************************
++ * moon.hxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution
++ * with the FlightGear project. Version 2 was written in August and
++ * September 1998. This code is based upon algorithms and data kindly
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se).
++ *
++ * 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$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++#ifndef _MOON_HXX_
++#define _MOON_HXX_
++
++#include <Aircraft/aircraft.hxx>
++#include <Include/fg_constants.h>
++#include <Main/views.hxx>
++#include <Time/fg_time.hxx>
++
++#include "celestialBody.hxx"
++#include "star.hxx"
++
++class Moon : public CelestialBody
++{
++private:
++ void TexInit(); // This should move to the constructor eventually.
++
++ GLUquadricObj *moonObject;
++ GLuint Sphere;
++ GLuint moon_texid;
++ GLuint moon_halotexid;
++ GLubyte *moon_texbuf;
++ GLubyte *moon_halotexbuf;
++
++ void setHalo();
++public:
++ Moon ( fgTIME *t);
++ ~Moon();
++ void updatePosition(fgTIME *t, Star *ourSun);
++ void newImage();
++};
++
++
++#endif // _MOON_HXX_
--- /dev/null
--- /dev/null
++/**************************************************************************
++ * neptune.cxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution
++ * with the FlightGear project. Version 2 was written in August and
++ * September 1998. This code is based upon algorithms and data kindly
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se).
++ *
++ * 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$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++#ifdef __BORLANDC__
++# define exception c_exception
++#endif
++#include <math.h>
++
++#include "neptune.hxx"
++
++/*************************************************************************
++ * Neptune::Neptune(fgTIME *t)
++ * Public constructor for class Neptune
++ * Argument: The current time.
++ * the hard coded orbital elements for Neptune are passed to
++ * CelestialBody::CelestialBody();
++ ************************************************************************/
++Neptune::Neptune(fgTIME *t) :
++ CelestialBody(131.7806, 3.0173000E-5,
++ 1.7700, -2.550E-7,
++ 272.8461, -6.027000E-6,
++ 30.058260, 3.313E-8,
++ 0.008606, 2.150E-9,
++ 260.2471, 0.00599514700, t)
++{
++}
++/*************************************************************************
++ * void Neptune::updatePosition(fgTIME *t, Star *ourSun)
++ *
++ * calculates the current position of Neptune, by calling the base class,
++ * CelestialBody::updatePosition(); The current magnitude is calculated using
++ * a Neptune specific equation
++ *************************************************************************/
++void Neptune::updatePosition(fgTIME *t, Star *ourSun)
++{
++ CelestialBody::updatePosition(t, ourSun);
++ magnitude = -6.90 + 5*log10 (r*R) + 0.001 *FV;
++}
--- /dev/null
--- /dev/null
++/**************************************************************************
++ * neptune.hxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution
++ * with the FlightGear project. Version 2 was written in August and
++ * September 1998. This code is based upon algorithms and data kindly
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se).
++ *
++ * 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$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++#ifndef _NEPTUNE_HXX_
++#define _NEPTUNE_HXX_
++
++#include <Time/fg_time.hxx>
++#include "celestialBody.hxx"
++#include "star.hxx"
++
++class Neptune : public CelestialBody
++{
++public:
++ Neptune ( fgTIME *t);
++ void updatePosition(fgTIME *t, Star *ourSun);
++};
++
++#endif // _NEPTUNE_HXX_
--- /dev/null
--- /dev/null
++/**************************************************************************
++ * pluto.hxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution
++ * with the FlightGear project. Version 2 was written in August and
++ * September 1998. This code is based upon algorithms and data kindly
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se).
++ *
++ * 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$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++#ifndef _PLUTO_HXX_
++#define _PLUTO_HXX_
++
++#include <Time/fg_time.hxx>
++#include "celestialBody.hxx"
++
++class Pluto : public CelestialBody
++{
++public:
++ Pluto ( fgTIME t);
++};
++
++#endif // _PLUTO_HXX_
--- /dev/null
--- /dev/null
++/**************************************************************************
++ * saturn.cxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution
++ * with the FlightGear project. Version 2 was written in August and
++ * September 1998. This code is based upon algorithms and data kindly
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se).
++ *
++ * 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$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++#ifdef __BORLANDC__
++# define exception c_exception
++#endif
++#include <math.h>
++
++#include "saturn.hxx"
++
++/*************************************************************************
++ * Saturn::Saturn(fgTIME *t)
++ * Public constructor for class Saturn
++ * Argument: The current time.
++ * the hard coded orbital elements for Saturn are passed to
++ * CelestialBody::CelestialBody();
++ ************************************************************************/
++Saturn::Saturn(fgTIME *t) :
++ CelestialBody(113.6634, 2.3898000E-5,
++ 2.4886, -1.081E-7,
++ 339.3939, 2.9766100E-5,
++ 9.5547500, 0.000000,
++ 0.055546, -9.499E-9,
++ 316.9670, 0.03344422820, t)
++{
++}
++
++/*************************************************************************
++ * void Saturn::updatePosition(fgTIME *t, Star *ourSun)
++ *
++ * calculates the current position of Saturn, by calling the base class,
++ * CelestialBody::updatePosition(); The current magnitude is calculated using
++ * a Saturn specific equation
++ *************************************************************************/
++void Saturn::updatePosition(fgTIME *t, Star *ourSun)
++{
++ CelestialBody::updatePosition(t, ourSun);
++
++ double actTime = fgCalcActTime(t);
++ double ir = 0.4897394;
++ double Nr = 2.9585076 + 6.6672E-7*actTime;
++ double B = asin (sin(declination) * cos(ir) -
++ cos(declination) * sin(ir) *
++ sin(rightAscension - Nr));
++ double ring_magn = -2.6 * sin(fabs(B)) + 1.2 * pow(sin(B), 2);
++ magnitude = -9.0 + 5*log10(r*R) + 0.044 * FV + ring_magn;
++}
++
--- /dev/null
--- /dev/null
++/**************************************************************************
++ * saturn.hxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution
++ * with the FlightGear project. Version 2 was written in August and
++ * September 1998. This code is based upon algorithms and data kindly
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se).
++ *
++ * 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$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++#ifndef _SATURN_HXX_
++#define _SATURN_HXX_
++
++#include <Time/fg_time.hxx>
++#include "celestialBody.hxx"
++#include "star.hxx"
++
++class Saturn : public CelestialBody
++{
++public:
++ Saturn ( fgTIME *t);
++ void updatePosition(fgTIME *t, Star *ourSun);
++};
++
++#endif // _SATURN_HXX_
++
++
++
++
++
++
++
--- /dev/null
--- /dev/null
++// sky.cxx -- model sky with an upside down "bowl"
++//
++// Written by Curtis Olson, started December 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$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++
++#include <math.h>
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#include <Aircraft/aircraft.hxx>
++#include <Debug/logstream.hxx>
++#include <FDM/flight.hxx>
++#include <Include/fg_constants.h>
++#include <Main/views.hxx>
++#include <Math/fg_random.h>
++#include <Time/event.hxx>
++#include <Time/fg_time.hxx>
++
++#include "sky.hxx"
++
++
++// in meters of course
++#define CENTER_ELEV 25000.0
++
++#define INNER_RADIUS 50000.0
++#define INNER_ELEV 20000.0
++
++#define MIDDLE_RADIUS 70000.0
++#define MIDDLE_ELEV 8000.0
++
++#define OUTER_RADIUS 80000.0
++#define OUTER_ELEV 0.0
++
++#define BOTTOM_RADIUS 50000.0
++#define BOTTOM_ELEV -2000.0
++
++
++static float inner_vertex[12][3];
++static float middle_vertex[12][3];
++static float outer_vertex[12][3];
++static float bottom_vertex[12][3];
++
++static float inner_color[12][4];
++static float middle_color[12][4];
++static float outer_color[12][4];
++
++
++// Calculate the sky structure vertices
++void fgSkyVerticesInit( void ) {
++ float theta;
++ int i;
++
++ FG_LOG(FG_ASTRO, FG_INFO, " Generating the sky dome vertices.");
++
++ for ( i = 0; i < 12; i++ ) {
++ theta = (i * 30.0) * DEG_TO_RAD;
++
++ inner_vertex[i][0] = cos(theta) * INNER_RADIUS;
++ inner_vertex[i][1] = sin(theta) * INNER_RADIUS;
++ inner_vertex[i][2] = INNER_ELEV;
++
++ // printf(" %.2f %.2f\n", cos(theta) * INNER_RADIUS,
++ // sin(theta) * INNER_RADIUS);
++
++ middle_vertex[i][0] = cos((double)theta) * MIDDLE_RADIUS;
++ middle_vertex[i][1] = sin((double)theta) * MIDDLE_RADIUS;
++ middle_vertex[i][2] = MIDDLE_ELEV;
++
++ outer_vertex[i][0] = cos((double)theta) * OUTER_RADIUS;
++ outer_vertex[i][1] = sin((double)theta) * OUTER_RADIUS;
++ outer_vertex[i][2] = OUTER_ELEV;
++
++ bottom_vertex[i][0] = cos((double)theta) * BOTTOM_RADIUS;
++ bottom_vertex[i][1] = sin((double)theta) * BOTTOM_RADIUS;
++ bottom_vertex[i][2] = BOTTOM_ELEV;
++ }
++}
++
++
++// (Re)calculate the sky colors at each vertex
++void fgSkyColorsInit( void ) {
++ fgLIGHT *l;
++ double sun_angle, diff;
++ double outer_param[3], outer_amt[3], outer_diff[3];
++ double middle_param[3], middle_amt[3], middle_diff[3];
++ int i, j;
++
++ l = &cur_light_params;
++
++ FG_LOG( FG_ASTRO, FG_INFO,
++ " Generating the sky colors for each vertex." );
++
++ // setup for the possibility of sunset effects
++ sun_angle = l->sun_angle * RAD_TO_DEG;
++ // fgPrintf( FG_ASTRO, FG_INFO,
++ // " Sun angle in degrees = %.2f\n", sun_angle);
++
++ if ( (sun_angle > 80.0) && (sun_angle < 100.0) ) {
++ // 0.0 - 0.4
++ outer_param[0] = (10.0 - fabs(90.0 - sun_angle)) / 20.0;
++ outer_param[1] = (10.0 - fabs(90.0 - sun_angle)) / 40.0;
++ outer_param[2] = -(10.0 - fabs(90.0 - sun_angle)) / 30.0;
++ // outer_param[2] = 0.0;
++
++ middle_param[0] = (10.0 - fabs(90.0 - sun_angle)) / 40.0;
++ middle_param[1] = (10.0 - fabs(90.0 - sun_angle)) / 80.0;
++ middle_param[2] = 0.0;
++
++ outer_diff[0] = outer_param[0] / 6.0;
++ outer_diff[1] = outer_param[1] / 6.0;
++ outer_diff[2] = outer_param[2] / 6.0;
++
++ middle_diff[0] = middle_param[0] / 6.0;
++ middle_diff[1] = middle_param[1] / 6.0;
++ middle_diff[2] = middle_param[2] / 6.0;
++ } else {
++ outer_param[0] = outer_param[1] = outer_param[2] = 0.0;
++ middle_param[0] = middle_param[1] = middle_param[2] = 0.0;
++
++ outer_diff[0] = outer_diff[1] = outer_diff[2] = 0.0;
++ middle_diff[0] = middle_diff[1] = middle_diff[2] = 0.0;
++ }
++ // printf(" outer_red_param = %.2f outer_red_diff = %.2f\n",
++ // outer_red_param, outer_red_diff);
++
++ // calculate transition colors between sky and fog
++ for ( j = 0; j < 3; j++ ) {
++ outer_amt[j] = outer_param[j];
++ middle_amt[j] = middle_param[j];
++ }
++
++ for ( i = 0; i < 6; i++ ) {
++ for ( j = 0; j < 3; j++ ) {
++ diff = l->sky_color[j] - l->fog_color[j];
++
++ // printf("sky = %.2f fog = %.2f diff = %.2f\n",
++ // l->sky_color[j], l->fog_color[j], diff);
++
++ inner_color[i][j] = l->sky_color[j] - diff * 0.3;
++ middle_color[i][j] = l->sky_color[j] - diff * 0.9 + middle_amt[j];
++ outer_color[i][j] = l->fog_color[j] + outer_amt[j];
++
++ if ( inner_color[i][j] > 1.00 ) { inner_color[i][j] = 1.00; }
++ if ( inner_color[i][j] < 0.10 ) { inner_color[i][j] = 0.10; }
++ if ( middle_color[i][j] > 1.00 ) { middle_color[i][j] = 1.00; }
++ if ( middle_color[i][j] < 0.10 ) { middle_color[i][j] = 0.10; }
++ if ( outer_color[i][j] > 1.00 ) { outer_color[i][j] = 1.00; }
++ if ( outer_color[i][j] < 0.10 ) { outer_color[i][j] = 0.10; }
++ }
++ inner_color[i][3] = middle_color[i][3] = outer_color[i][3] =
++ l->sky_color[3];
++
++ for ( j = 0; j < 3; j++ ) {
++ outer_amt[j] -= outer_diff[j];
++ middle_amt[j] -= middle_diff[j];
++ }
++
++ /*
++ printf("inner_color[%d] = %.2f %.2f %.2f %.2f\n", i, inner_color[i][0],
++ inner_color[i][1], inner_color[i][2], inner_color[i][3]);
++ printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i,
++ middle_color[i][0], middle_color[i][1], middle_color[i][2],
++ middle_color[i][3]);
++ printf("outer_color[%d] = %.2f %.2f %.2f %.2f\n", i,
++ outer_color[i][0], outer_color[i][1], outer_color[i][2],
++ outer_color[i][3]);
++ */
++ }
++
++ for ( j = 0; j < 3; j++ ) {
++ outer_amt[j] = 0.0;
++ middle_amt[j] = 0.0;
++ }
++
++ for ( i = 6; i < 12; i++ ) {
++
++ for ( j = 0; j < 3; j++ ) {
++ diff = l->sky_color[j] - l->fog_color[j];
++
++ // printf("sky = %.2f fog = %.2f diff = %.2f\n",
++ // l->sky_color[j], l->fog_color[j], diff);
++
++ inner_color[i][j] = l->sky_color[j] - diff * 0.3;
++ middle_color[i][j] = l->sky_color[j] - diff * 0.9 + middle_amt[j];
++ outer_color[i][j] = l->fog_color[j] + outer_amt[j];
++
++ if ( inner_color[i][j] > 1.00 ) { inner_color[i][j] = 1.00; }
++ if ( inner_color[i][j] < 0.10 ) { inner_color[i][j] = 0.10; }
++ if ( middle_color[i][j] > 1.00 ) { middle_color[i][j] = 1.00; }
++ if ( middle_color[i][j] < 0.10 ) { middle_color[i][j] = 0.10; }
++ if ( outer_color[i][j] > 1.00 ) { outer_color[i][j] = 1.00; }
++ if ( outer_color[i][j] < 0.15 ) { outer_color[i][j] = 0.15; }
++ }
++ inner_color[i][3] = middle_color[i][3] = outer_color[i][3] =
++ l->sky_color[3];
++
++ for ( j = 0; j < 3; j++ ) {
++ outer_amt[j] += outer_diff[j];
++ middle_amt[j] += middle_diff[j];
++ }
++
++ /*
++ printf("inner_color[%d] = %.2f %.2f %.2f %.2f\n", i, inner_color[i][0],
++ inner_color[i][1], inner_color[i][2], inner_color[i][3]);
++ printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i,
++ middle_color[i][0], middle_color[i][1], middle_color[i][2],
++ middle_color[i][3]);
++ printf("outer_color[%d] = %.2f %.2f %.2f %.2f\n", i,
++ outer_color[i][0], outer_color[i][1], outer_color[i][2],
++ outer_color[i][3]);
++ */
++ }
++}
++
++
++// Initialize the sky structure and colors
++void fgSkyInit( void ) {
++ FG_LOG( FG_ASTRO, FG_INFO, "Initializing the sky" );
++
++ fgSkyVerticesInit();
++
++ // regester fgSkyColorsInit() as an event to be run periodically
++ global_events.Register( "fgSkyColorsInit()", fgSkyColorsInit,
++ fgEVENT::FG_EVENT_READY, 30000);
++}
++
++
++// Draw the Sky
++void fgSkyRender( void ) {
++ FGInterface *f;
++ fgLIGHT *l;
++ float inner_color[4];
++ float middle_color[4];
++ float outer_color[4];
++ double diff;
++ int i;
++
++ f = current_aircraft.fdm_state;
++ l = &cur_light_params;
++
++ // printf("Rendering the sky.\n");
++
++ // calculate the proper colors
++ for ( i = 0; i < 3; i++ ) {
++ diff = l->sky_color[i] - l->adj_fog_color[i];
++
++ // printf("sky = %.2f fog = %.2f diff = %.2f\n",
++ // l->sky_color[j], l->adj_fog_color[j], diff);
++
++ inner_color[i] = l->sky_color[i] - diff * 0.3;
++ middle_color[i] = l->sky_color[i] - diff * 0.9;
++ outer_color[i] = l->adj_fog_color[i];
++ }
++ inner_color[3] = middle_color[3] = outer_color[3] = l->adj_fog_color[3];
++
++ xglPushMatrix();
++
++ // Translate to view position
++ Point3D zero_elev = current_view.get_cur_zero_elev();
++ xglTranslatef( zero_elev.x(), zero_elev.y(), zero_elev.z() );
++ // printf(" Translated to %.2f %.2f %.2f\n",
++ // zero_elev.x, zero_elev.y, zero_elev.z );
++
++ // Rotate to proper orientation
++ // printf(" lon = %.2f lat = %.2f\n", FG_Longitude * RAD_TO_DEG,
++ // FG_Latitude * RAD_TO_DEG);
++ xglRotatef( f->get_Longitude() * RAD_TO_DEG, 0.0, 0.0, 1.0 );
++ xglRotatef( 90.0 - f->get_Latitude() * RAD_TO_DEG, 0.0, 1.0, 0.0 );
++ xglRotatef( l->sun_rotation * RAD_TO_DEG, 0.0, 0.0, 1.0 );
++
++ // Draw inner/center section of sky*/
++ xglBegin( GL_TRIANGLE_FAN );
++ xglColor4fv(l->sky_color);
++ xglVertex3f(0.0, 0.0, CENTER_ELEV);
++ for ( i = 11; i >= 0; i-- ) {
++ xglColor4fv( inner_color );
++ xglVertex3fv( inner_vertex[i] );
++ }
++ xglColor4fv( inner_color );
++ xglVertex3fv( inner_vertex[11] );
++ xglEnd();
++
++ // Draw the middle ring
++ xglBegin( GL_TRIANGLE_STRIP );
++ for ( i = 0; i < 12; i++ ) {
++ xglColor4fv( middle_color );
++ // printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i,
++ // middle_color[i][0], middle_color[i][1], middle_color[i][2],
++ // middle_color[i][3]);
++ // xglColor4f(1.0, 0.0, 0.0, 1.0);
++ xglVertex3fv( middle_vertex[i] );
++ xglColor4fv( inner_color );
++ // printf("inner_color[%d] = %.2f %.2f %.2f %.2f\n", i,
++ // inner_color[i][0], inner_color[i][1], inner_color[i][2],
++ // inner_color[i][3]);
++ // xglColor4f(0.0, 0.0, 1.0, 1.0);
++ xglVertex3fv( inner_vertex[i] );
++ }
++ xglColor4fv( middle_color );
++ // xglColor4f(1.0, 0.0, 0.0, 1.0);
++ xglVertex3fv( middle_vertex[0] );
++ xglColor4fv( inner_color );
++ // xglColor4f(0.0, 0.0, 1.0, 1.0);
++ xglVertex3fv( inner_vertex[0] );
++ xglEnd();
++
++ // Draw the outer ring
++ xglBegin( GL_TRIANGLE_STRIP );
++ for ( i = 0; i < 12; i++ ) {
++ xglColor4fv( outer_color );
++ xglVertex3fv( outer_vertex[i] );
++ xglColor4fv( middle_color );
++ xglVertex3fv( middle_vertex[i] );
++ }
++ xglColor4fv( outer_color );
++ xglVertex3fv( outer_vertex[0] );
++ xglColor4fv( middle_color );
++ xglVertex3fv( middle_vertex[0] );
++ xglEnd();
++
++ // Draw the bottom skirt
++ xglBegin( GL_TRIANGLE_STRIP );
++ xglColor4fv( outer_color );
++ for ( i = 0; i < 12; i++ ) {
++ xglVertex3fv( bottom_vertex[i] );
++ xglVertex3fv( outer_vertex[i] );
++ }
++ xglVertex3fv( bottom_vertex[0] );
++ xglVertex3fv( outer_vertex[0] );
++ xglEnd();
++
++ xglPopMatrix();
++}
++
++
++// $Log$
++// Revision 1.21 1999/02/05 21:28:50 curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.20 1999/02/02 20:13:29 curt
++// MSVC++ portability changes by Bernie Bright:
++//
++// Lib/Serial/serial.[ch]xx: Initial Windows support - incomplete.
++// Simulator/Astro/stars.cxx: typo? included <stdio> instead of <cstdio>
++// Simulator/Cockpit/hud.cxx: Added Standard headers
++// Simulator/Cockpit/panel.cxx: Redefinition of default parameter
++// Simulator/Flight/flight.cxx: Replaced cout with FG_LOG. Deleted <stdio.h>
++// Simulator/Main/fg_init.cxx:
++// Simulator/Main/GLUTmain.cxx:
++// Simulator/Main/options.hxx: Shuffled <fg_serial.hxx> dependency
++// Simulator/Objects/material.hxx:
++// Simulator/Time/timestamp.hxx: VC++ friend kludge
++// Simulator/Scenery/tile.[ch]xx: Fixed using std::X declarations
++// Simulator/Main/views.hxx: Added a constant
++//
++// Revision 1.19 1999/02/01 21:33:26 curt
++// Renamed FlightGear/Simulator/Flight to FlightGear/Simulator/FDM since
++// Jon accepted my offer to do this and thought it was a good idea.
++//
++// Revision 1.18 1999/02/01 21:09:00 curt
++// Bug fix in vertex order of inner disk (fan) of the sky dome.
++//
++// Revision 1.17 1998/12/09 18:50:12 curt
++// Converted "class fgVIEW" to "class FGView" and updated to make data
++// members private and make required accessor functions.
++//
++// Revision 1.16 1998/12/05 15:54:03 curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.15 1998/12/03 01:15:36 curt
++// Converted fgFLIGHT to a class.
++// Tweaks for Sun portability.
++//
++// Revision 1.14 1998/11/06 21:17:39 curt
++// Converted to new logstream debugging facility. This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.13 1998/10/20 18:28:30 curt
++// Tweaked sunset/sunrise colors.
++//
++// Revision 1.12 1998/10/16 23:27:18 curt
++// C++-ifying.
++//
++// Revision 1.11 1998/10/16 00:52:19 curt
++// Converted to Point3D class.
++//
++// Revision 1.10 1998/08/29 13:07:16 curt
++// Rewrite of event manager thanks to Bernie Bright.
++//
++// Revision 1.9 1998/08/22 01:18:59 curt
++// Minor tweaks to avoid using unitialized memory.
++//
++// Revision 1.8 1998/08/12 21:40:44 curt
++// Sky now tracks adjusted fog color so it blends well with terrain.
++//
++// Revision 1.7 1998/07/22 21:39:21 curt
++// Lower skirt tracks adjusted fog color, not fog color.
++//
++// Revision 1.6 1998/05/23 14:07:14 curt
++// Use new C++ events class.
++//
++// Revision 1.5 1998/04/28 01:19:02 curt
++// Type-ified fgTIME and fgVIEW
++//
++// Revision 1.4 1998/04/26 05:10:01 curt
++// "struct fgLIGHT" -> "fgLIGHT" because fgLIGHT is typedef'd.
++//
++// Revision 1.3 1998/04/25 22:06:25 curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.2 1998/04/24 00:45:03 curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Fixed a bug when generating sky colors.
++//
++// Revision 1.1 1998/04/22 13:21:32 curt
++// C++ - ifing the code a bit.
++//
++// Revision 1.9 1998/04/03 21:52:50 curt
++// Converting to Gnu autoconf system.
++//
++// Revision 1.8 1998/03/09 22:47:25 curt
++// Incorporated Durk's updates.
++//
++// Revision 1.7 1998/02/19 13:05:49 curt
++// Incorporated some HUD tweaks from Michelle America.
++// Tweaked the sky's sunset/rise colors.
++// Other misc. tweaks.
++//
++// Revision 1.6 1998/02/07 15:29:32 curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.5 1998/01/27 00:47:48 curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.4 1998/01/26 15:54:28 curt
++// Added a "skirt" to try to help hide gaps between scenery and sky. This will
++// have to be revisited in the future.
++//
++// Revision 1.3 1998/01/19 19:26:59 curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.2 1998/01/19 18:40:17 curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.1 1998/01/07 03:16:19 curt
++// Moved from .../Src/Scenery/ to .../Src/Astro/
++//
++// Revision 1.11 1997/12/30 22:22:38 curt
++// Further integration of event manager.
++//
++// Revision 1.10 1997/12/30 20:47:53 curt
++// Integrated new event manager with subsystem initializations.
++//
++// Revision 1.9 1997/12/30 13:06:57 curt
++// A couple lighting tweaks ...
++//
++// Revision 1.8 1997/12/23 04:58:38 curt
++// Tweaked the sky coloring a bit to build in structures to allow finer rgb
++// control.
++//
++// Revision 1.7 1997/12/22 23:45:48 curt
++// First stab at sunset/sunrise sky glow effects.
++//
++// Revision 1.6 1997/12/22 04:14:34 curt
++// Aligned sky with sun so dusk/dawn effects can be correct relative to the sun.
++//
++// Revision 1.5 1997/12/19 23:34:59 curt
++// Lot's of tweaking with sky rendering and lighting.
++//
++// Revision 1.4 1997/12/19 16:45:02 curt
++// Working on scene rendering order and options.
++//
++// Revision 1.3 1997/12/18 23:32:36 curt
++// First stab at sky dome actually starting to look reasonable. :-)
++//
++// Revision 1.2 1997/12/18 04:07:03 curt
++// Worked on properly translating and positioning the sky dome.
++//
++// Revision 1.1 1997/12/17 23:14:30 curt
++// Initial revision.
++// Begin work on rendering the sky. (Rather than just using a clear screen.)
++//
++
--- /dev/null
--- /dev/null
++// sky.hxx -- model sky with an upside down "bowl"
++//
++// Written by Curtis Olson, started December 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$
++// (Log is kept at end of this file)
++
++
++#ifndef _SKY_HXX
++#define _SKY_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++
++// (Re)generate the display list
++void fgSkyInit( void );
++
++// (Re)calculate the sky colors at each vertex
++void fgSkyColorsInit( void );
++
++// Draw the Sky
++void fgSkyRender( void );
++
++
++#endif // _SKY_HXX
++
++
++// $Log$
++// Revision 1.2 1998/10/16 23:27:19 curt
++// C++-ifying.
++//
++// Revision 1.1 1998/04/22 13:21:33 curt
++// C++ - ifing the code a bit.
++//
++// Revision 1.4 1998/04/21 17:02:32 curt
++// Prepairing for C++ integration.
++//
++// Revision 1.3 1998/01/22 02:59:28 curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.2 1998/01/19 18:40:17 curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.1 1998/01/07 03:16:19 curt
++// Moved from .../Src/Scenery/ to .../Src/Astro/
++//
++// Revision 1.2 1997/12/22 23:45:49 curt
++// First stab at sunset/sunrise sky glow effects.
++//
++// Revision 1.1 1997/12/17 23:14:31 curt
++// Initial revision.
++// Begin work on rendering the sky. (Rather than just using a clear screen.)
++//
--- /dev/null
--- /dev/null
++/**************************************************************************
++ * solarsystem.cxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution
++ * with the FlightGear project. Version 2 was written in August and
++ * September 1998. This code is based upon algorithms and data kindly
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se).
++ *
++ * 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$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++
++#ifdef __BORLANDC__
++# define exception c_exception
++#endif
++#include <math.h>
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++#include <Debug/logstream.hxx>
++#include <Time/sunpos.hxx>
++#include <Time/moonpos.hxx>
++#include "solarsystem.hxx"
++
++/***************************************************************************
++ * default constructor for class SolarSystem:
++ * or course there can only be one way to create an entire solar system -:) )
++ * the fgTIME argument is needed to properly initialize the the current orbital
++ * elements
++ *************************************************************************/
++SolarSystem::SolarSystem(fgTIME *t)
++{
++ if (theSolarSystem)
++ {
++ FG_LOG( FG_GENERAL, FG_ALERT, "Error: only one solarsystem allowed" );
++ exit(-1);
++ }
++ theSolarSystem = this;
++ ourSun = new Star(t);
++ earthsMoon = new Moon(t);
++ mercury = new Mercury(t);
++ venus = new Venus(t);
++ mars = new Mars(t);
++ jupiter = new Jupiter(t);
++ saturn = new Saturn(t);
++ uranus = new Uranus(t);
++ neptune = new Neptune(t);
++
++ displayList = 0;
++};
++
++/**************************************************************************
++ * the destructor for class SolarSystem;
++ **************************************************************************/
++SolarSystem::~SolarSystem()
++{
++ delete ourSun;
++ delete earthsMoon;
++ delete mercury;
++ delete venus;
++ delete mars;
++ delete jupiter;
++ delete saturn;
++ delete uranus;
++ delete neptune;
++}
++/****************************************************************************
++ * void SolarSystem::rebuild()
++ *
++ * this member function updates the positions for the sun, moon, and planets,
++ * and then rebuilds the display list.
++ *
++ * arguments: none
++ * return value: none
++ ***************************************************************************/
++void SolarSystem::rebuild()
++{
++ //fgLIGHT *l = &cur_light_params;
++ fgTIME *t = &cur_time_params;
++ //float x, y, z;
++ //double sun_angle;
++ double ra, dec;
++ //double x_2, x_4, x_8, x_10;*/
++ double magnitude;
++ //GLfloat ambient;
++ //GLfloat amb[4];
++
++
++ glDisable(GL_LIGHTING);
++
++
++ // Step 1: update all the positions
++ ourSun->updatePosition(t);
++ earthsMoon->updatePosition(t, ourSun);
++ mercury->updatePosition(t, ourSun);
++ venus->updatePosition(t, ourSun);
++ mars->updatePosition(t, ourSun);
++ jupiter->updatePosition(t, ourSun);
++ saturn->updatePosition(t, ourSun);
++ uranus->updatePosition(t, ourSun);
++ neptune->updatePosition(t, ourSun);
++
++ fgUpdateSunPos(); // get the right sun angle (especially important when
++ // running for the first time).
++ fgUpdateMoonPos();
++
++ if (displayList)
++ xglDeleteLists(displayList, 1);
++
++ displayList = xglGenLists(1);
++
++ // Step 2: rebuild the display list
++ xglNewList( displayList, GL_COMPILE);
++ {
++ // Step 2a: Add the moon...
++ // Not that it is preferred to draw the moon first, and the sun next, in order to mime a
++ // solar eclipse. This is yet untested though...
++
++ earthsMoon->newImage();
++ // Step 2b: Add the sun
++ //xglPushMatrix();
++ //{
++ ourSun->newImage();
++ //}
++ //xglPopMatrix();
++ // Step 2c: Add the planets
++ xglBegin(GL_POINTS);
++ mercury->getPos(&ra, &dec, &magnitude);addPlanetToList(ra, dec, magnitude);
++ venus ->getPos(&ra, &dec, &magnitude);addPlanetToList(ra, dec, magnitude);
++ mars ->getPos(&ra, &dec, &magnitude);addPlanetToList(ra, dec, magnitude);
++ jupiter->getPos(&ra, &dec, &magnitude);addPlanetToList(ra, dec, magnitude);
++ saturn ->getPos(&ra, &dec, &magnitude);addPlanetToList(ra, dec, magnitude);
++ uranus ->getPos(&ra, &dec, &magnitude);addPlanetToList(ra, dec, magnitude);
++ neptune->getPos(&ra, &dec, &magnitude);addPlanetToList(ra, dec, magnitude);
++ xglEnd();
++ xglEnable(GL_LIGHTING);
++ }
++ xglEndList();
++}
++
++/*****************************************************************************
++ * double SolarSystem::scaleMagnitude(double magn)
++ * This private member function rescales the original magnitude, as used in the
++ * astronomical sense of the word, into a value used by OpenGL to draw a
++ * convincing Star or planet
++ *
++ * Argument: the astronomical magnitude
++ *
++ * return value: the rescaled magnitude
++ ****************************************************************************/
++double SolarSystem::scaleMagnitude(double magn)
++{
++ double magnitude = (0.0 - magn) / 5.0 + 1.0;
++ magnitude = magnitude * 0.7 + (3 * 0.1);
++ if (magnitude > 1.0) magnitude = 1.0;
++ if (magnitude < 0.0) magnitude = 0.0;
++ return magnitude;
++}
++
++/***************************************************************************
++ * void SolarSytem::addPlanetToList(double ra, double dec, double magn);
++ *
++ * This private member function first causes the magnitude to be properly
++ * rescaled, and then adds the planet to the display list.
++ *
++ * arguments: Right Ascension, declination, and magnitude
++ *
++ * return value: none
++ **************************************************************************/
++void SolarSystem::addPlanetToList(double ra, double dec, double magn)
++{
++ double
++ magnitude = scaleMagnitude ( magn );
++
++ fgLIGHT *l = &cur_light_params;
++
++ if ((double) (l->sun_angle - FG_PI_2) >
++ ((magnitude - 1.0) * - 20 * DEG_TO_RAD))
++ {
++ xglColor3f (magnitude, magnitude, magnitude);
++ xglVertex3f( 50000.0 * cos (ra) * cos (dec),
++ 50000.0 * sin (ra) * cos (dec),
++ 50000.0 * sin (dec));
++ }
++}
++
++
++SolarSystem* SolarSystem::theSolarSystem = 0;
++
++/******************************************************************************
++ * void solarSystemRebuild()
++ * this a just a wrapper function, provided for use as an interface to the
++ * event manager
++ *****************************************************************************/
++void solarSystemRebuild()
++{
++ SolarSystem::theSolarSystem->rebuild();
++}
--- /dev/null
--- /dev/null
++/**************************************************************************
++ * solarsystem.hxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution
++ * with the FlightGear project. Version 2 was written in August and
++ * September 1998. This code is based upon algorithms and data kindly
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se).
++ *
++ * 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$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++#ifndef _SOLARSYSTEM_H_
++#define _SOLARSYSTEM_H_
++
++#include <Time/light.hxx>
++#include <Time/fg_time.hxx>
++#include <Main/views.hxx>
++
++#include "star.hxx"
++#include "moon.hxx"
++#include "mercury.hxx"
++#include "venus.hxx"
++#include "mars.hxx"
++#include "jupiter.hxx"
++#include "saturn.hxx"
++#include "uranus.hxx"
++#include "neptune.hxx"
++#include "pluto.hxx"
++
++
++class SolarSystem
++{
++private:
++ Star* ourSun;
++ Moon* earthsMoon;
++ Mercury* mercury;
++ Venus* venus;
++ Mars* mars;
++ Jupiter* jupiter;
++ Saturn* saturn;
++ Uranus* uranus;
++ Neptune* neptune;
++ //Pluto* pluto;
++
++ GLint displayList;
++ double scaleMagnitude(double magn);
++ void addPlanetToList(double ra, double dec, double magn);
++
++
++public:
++ SolarSystem(fgTIME *t);
++ CelestialBody *getSun();
++ CelestialBody *getMoon();
++ ~SolarSystem();
++
++ static SolarSystem *theSolarSystem; // thanks to Bernie Bright!
++ void rebuild();
++ friend void solarSystemRebuild();
++ void draw();
++};
++
++inline CelestialBody* SolarSystem::getSun()
++{
++ return ourSun;
++}
++
++inline CelestialBody* SolarSystem::getMoon()
++{
++ return earthsMoon;
++}
++
++inline void SolarSystem::draw()
++{
++ xglCallList(displayList);
++}
++
++extern void solarSystemRebuild();
++
++#endif // _SOLARSYSTEM_H_
--- /dev/null
--- /dev/null
++/**************************************************************************
++ * star.cxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution
++ * with the FlightGear project. Version 2 was written in August and
++ * September 1998. This code is based upon algorithms and data kindly
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se).
++ *
++ * 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$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++#ifdef __BORLANDC__
++# define exception c_exception
++#endif
++#include <math.h>
++#include <Time/sunpos.hxx>
++#include <Debug/logstream.hxx>
++#include <Time/light.hxx>
++#include "star.hxx"
++
++/*************************************************************************
++ * Star::Star(fgTIME *t)
++ * Public constructor for class Star
++ * Argument: The current time.
++ * the hard coded orbital elements our sun are passed to
++ * CelestialBody::CelestialBody();
++ * note that the word sun is avoided, in order to prevent some compilation
++ * problems on sun systems
++ ************************************************************************/
++Star::Star(fgTIME *t) :
++ CelestialBody (0.000000, 0.0000000000,
++ 0.0000, 0.00000,
++ 282.9404, 4.7093500E-5,
++ 1.0000000, 0.000000,
++ 0.016709, -1.151E-9,
++ 356.0470, 0.98560025850, t)
++{
++
++ FG_LOG( FG_GENERAL, FG_INFO, "Initializing Sun Texture");
++#ifdef GL_VERSION_1_1
++ xglGenTextures(1, &sun_texid);
++ xglBindTexture(GL_TEXTURE_2D, sun_texid);
++#elif GL_EXT_texture_object
++ xglGenTexturesEXT(1, &sun_texid);
++ xglBindTextureEXT(GL_TEXTURE_2D, sun_texid);
++#else
++# error port me
++#endif
++
++ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
++ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
++ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
++ setTexture();
++ glTexImage2D( GL_TEXTURE_2D,
++ 0,
++ GL_RGBA,
++ 256, 256,
++ 0,
++ GL_RGBA, GL_UNSIGNED_BYTE,
++ sun_texbuf);
++
++ SunObject = gluNewQuadric();
++ if(SunObject == NULL)
++ {
++ printf("gluNewQuadric(SunObject) failed !\n");
++ exit(0);
++ }
++
++ //SunList = 0;
++ distance = 0.0;
++}
++
++Star::~Star()
++{
++ //delete SunObject;
++ delete [] sun_texbuf;
++}
++
++
++
++static int texWidth = 256; /* 64x64 is plenty */
++
++void Star::setTexture()
++{
++ int texSize;
++ //void *textureBuf;
++ GLubyte *p;
++ int i,j;
++ double radius;
++
++ texSize = texWidth*texWidth;
++
++ sun_texbuf = new GLubyte[texSize*4];
++ if (!sun_texbuf)
++ return; // Ugly!
++
++ p = sun_texbuf;
++
++ radius = (double)(texWidth / 2);
++
++ for (i=0; i < texWidth; i++) {
++ for (j=0; j < texWidth; j++) {
++ double x, y, d;
++
++ x = fabs((double)(i - (texWidth / 2)));
++ y = fabs((double)(j - (texWidth / 2)));
++
++ d = sqrt((x * x) + (y * y));
++ if (d < radius)
++ {
++ double t = 1.0 - (d / radius); // t is 1.0 at center, 0.0 at edge */
++ // inverse square looks nice
++ *p = (int)((double)0xff * (t * t));
++ *(p+1) = (int)((double) 0xff * (t*t));
++ *(p+2) = (int)((double) 0xff * (t*t));
++ *(p+3) = (int)((double) 0xff * (t*t));
++ }
++ else
++ {
++ *p = 0x00;
++ *(p+1) = 0x00;
++ *(p+2) = 0x00;
++ *(p+3) = 0x00;
++ }
++ p += 4;
++ }
++ }
++ //gluBuild2DMipmaps(GL_TEXTURE_2D, 1, texWidth, texWidth,
++ // GL_LUMINANCE,
++ // GL_UNSIGNED_BYTE, textureBuf);
++ //free(textureBuf);
++}
++/*************************************************************************
++ * void Jupiter::updatePosition(fgTIME *t, Star *ourSun)
++ *
++ * calculates the current position of our sun.
++ *************************************************************************/
++void Star::updatePosition(fgTIME *t)
++{
++ double
++ actTime, eccAnom,
++ xv, yv, v, r,
++ xe, ye, ze, ecl;
++
++ updateOrbElements(t);
++
++ actTime = fgCalcActTime(t);
++ ecl = DEG_TO_RAD * (23.4393 - 3.563E-7 * actTime); // Angle in Radians
++ eccAnom = fgCalcEccAnom(M, e); // Calculate the eccentric Anomaly (also known as solving Kepler's equation)
++
++ xv = cos(eccAnom) - e;
++ yv = sqrt (1.0 - e*e) * sin(eccAnom);
++ v = atan2 (yv, xv); // the sun's true anomaly
++ distance = r = sqrt (xv*xv + yv*yv); // and its distance
++
++ lonEcl = v + w; // the sun's true longitude
++ latEcl = 0;
++
++ // convert the sun's true longitude to ecliptic rectangular
++ // geocentric coordinates (xs, ys)
++ xs = r * cos (lonEcl);
++ ys = r * sin (lonEcl);
++
++ // convert ecliptic coordinates to equatorial rectangular
++ // geocentric coordinates
++
++ xe = xs;
++ ye = ys * cos (ecl);
++ ze = ys * sin (ecl);
++
++ // And finally, calculate right ascension and declination
++ rightAscension = atan2 (ye, xe);
++ declination = atan2 (ze, sqrt (xe*xe + ye*ye));
++}
++
++void Star::newImage(void)
++{
++ /*static float stars[3];
++ stars[0] = 0.0;
++ stars[1] = 0.0;
++ stars[2] = 1.0;*/
++
++ fgLIGHT *l = &cur_light_params;
++ float sun_angle = l->sun_angle;
++
++ if( sun_angle*RAD_TO_DEG < 100 ) { // else no need to draw sun
++
++
++ double x_2, x_4, x_8, x_10;
++ GLfloat ambient;
++ GLfloat amb[4];
++ int sun_size = 750;
++
++ // daily variation sun gets larger near horizon
++ /*if(sun_angle*RAD_TO_DEG > 84.0 && sun_angle*RAD_TO_DEG < 95)
++ {
++ double sun_grow = 9*fabs(94-sun_angle*RAD_TO_DEG);
++ sun_size = (int)(sun_size + sun_size * cos(sun_grow*DEG_TO_RAD));
++ }*/
++ x_2 = sun_angle * sun_angle;
++ x_4 = x_2 * x_2;
++ x_8 = x_4 * x_4;
++ x_10 = x_8 * x_2;
++ ambient = (float)(0.4 * pow (1.1, - x_10 / 30.0));
++ if (ambient < 0.3) ambient = 0.3;
++ if (ambient > 1.0) ambient = 1.0;
++
++ amb[0] = ((ambient * 6.0) - 1.0); // minimum value = 0.8
++ amb[1] = ((ambient * 11.0) - 3.0); // minimum value = 0.3
++ amb[2] = ((ambient * 12.0) - 3.6); // minimum value = 0.0
++ amb[3] = 1.00;
++
++ if (amb[0] > 1.0) amb[0] = 1.0;
++ if (amb[1] > 1.0) amb[1] = 1.0;
++ if (amb[2] > 1.0) amb[2] = 1.0;
++ xglColor3fv(amb);
++ glPushMatrix();
++ {
++ xglRotatef(((RAD_TO_DEG * rightAscension)- 90.0), 0.0, 0.0, 1.0);
++ xglRotatef((RAD_TO_DEG * declination), 1.0, 0.0, 0.0);
++ xglTranslatef(0,60000,0);
++
++ glEnable(GL_TEXTURE_2D); // TEXTURE ENABLED
++ glEnable(GL_BLEND); // BLEND ENABLED
++
++ //glEnable(GL_TEXTURE_2D);
++ //glEnable(GL_BLEND);
++ //glDisable(GL_LIGHTING);
++ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
++ //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
++ glBindTexture(GL_TEXTURE_2D, sun_texid);
++
++ glBegin(GL_QUADS);
++ glTexCoord2f(0.0f, 0.0f); glVertex3f(-5000, 0.0, -5000);
++ glTexCoord2f(1.0f, 0.0f); glVertex3f( 5000, 0.0, -5000);
++ glTexCoord2f(1.0f, 1.0f); glVertex3f( 5000, 0.0, 5000);
++ glTexCoord2f(0.0f, 1.0f); glVertex3f(-5000, 0.0, 5000);
++ glEnd();
++ }
++ glPopMatrix();
++ xglDisable(GL_TEXTURE_2D);
++ glDisable(GL_BLEND);
++ glPushMatrix();
++ {
++ xglRotatef(((RAD_TO_DEG * rightAscension)- 90.0), 0.0, 0.0, 1.0);
++ xglRotatef((RAD_TO_DEG * declination), 1.0, 0.0, 0.0);
++ xglTranslatef(0,58600,0);
++ gluSphere( SunObject, sun_size, 10, 10 );
++ }
++ glPopMatrix();
++ glDisable(GL_TEXTURE_2D); // TEXTURE DISABLED
++ glDisable(GL_BLEND); // BLEND DISABLED
++ }
++}
++
++
++
++
--- /dev/null
--- /dev/null
++/**************************************************************************
++ * star.hxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution
++ * with the FlightGear project. Version 2 was written in August and
++ * September 1998. This code is based upon algorithms and data kindly
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se).
++ *
++ * 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$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++#ifndef _STAR_HXX_
++#define _STAR_HXX_
++
++#include <Time/fg_time.hxx>
++#include "celestialBody.hxx"
++
++
++class Star : public CelestialBody
++{
++private:
++ //double longitude; // the sun's true longitude - this is depreciated by
++ // CelestialBody::lonEcl
++ double xs, ys; // the sun's rectangular geocentric coordinates
++ double distance; // the sun's distance to the earth
++ GLUquadricObj *SunObject;
++ GLuint sun_texid;
++ GLubyte *sun_texbuf;
++
++ void setTexture();
++public:
++ Star (fgTIME *t);
++ ~Star();
++ void updatePosition(fgTIME *t);
++ double getM();
++ double getw();
++ //double getLon();
++ double getxs();
++ double getys();
++ double getDistance();
++ void newImage();
++};
++
++
++
++inline double Star::getM()
++{
++ return M;
++}
++
++inline double Star::getw()
++{
++ return w;
++}
++
++inline double Star::getxs()
++{
++ return xs;
++}
++
++inline double Star::getys()
++{
++ return ys;
++}
++
++inline double Star::getDistance()
++{
++ return distance;
++}
++
++
++#endif // _STAR_HXX_
++
++
++
++
++
++
++
++
++
++
++
++
++
++
--- /dev/null
--- /dev/null
++// stars.cxx -- data structures and routines for managing and rendering stars.
++//
++// Written by Curtis Olson, started August 1997.
++//
++// Copyright (C) 1997 Curtis L. Olson - curt@me.umn.edu
++//
++// 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$
++// (Log is kept at end of this file)
++//*************************************************************************/
++
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++
++#include "Include/compiler.h"
++#ifdef FG_HAVE_STD_INCLUDES
++# include <cmath>
++# include <cstdio>
++# include <cstring>
++# include <ctime>
++#else
++# include <math.h>
++# include <stdio.h>
++# include <string.h>
++# include <time.h>
++#endif
++
++#include <string>
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#include <Aircraft/aircraft.hxx>
++#include <Debug/logstream.hxx>
++#include <Include/fg_constants.h>
++#include <Misc/fgstream.hxx>
++#include <Main/options.hxx>
++#include <Main/views.hxx>
++#include <Misc/stopwatch.hxx>
++#include <Time/fg_time.hxx>
++#include "Misc/stopwatch.hxx"
++
++#include "stars.hxx"
++
++FG_USING_STD(getline);
++
++#define EpochStart (631065600)
++#define DaysSinceEpoch(secs) (((secs)-EpochStart)*(1.0/(24*3600)))
++#define FG_MAX_STARS 3500
++
++// Define four structures, each with varying amounts of stars
++static GLint stars[FG_STAR_LEVELS];
++
++
++// Initialize the Star Management Subsystem
++int fgStarsInit( void ) {
++ Point3D starlist[FG_MAX_STARS];
++ // struct CelestialCoord pltPos;
++ double right_ascension, declination, magnitude;
++ double min_magnitude[FG_STAR_LEVELS];
++ // double ra_save, decl_save;
++ // double ra_save1, decl_save1;
++ int i, j, starcount, count;
++
++ FG_LOG( FG_ASTRO, FG_INFO, "Initializing stars" );
++
++ if ( FG_STAR_LEVELS < 4 ) {
++ FG_LOG( FG_ASTRO, FG_ALERT, "Big whups in stars.cxx" );
++ exit(-1);
++ }
++
++ // build the full path name to the stars data base file
++ string path = current_options.get_fg_root() + "/Astro/stars" + ".gz";
++
++ FG_LOG( FG_ASTRO, FG_INFO, " Loading stars from " << path );
++
++ fg_gzifstream in( path );
++ if ( ! in ) {
++ FG_LOG( FG_ASTRO, FG_ALERT, "Cannot open star file: " << path );
++ exit(-1);
++ }
++
++ starcount = 0;
++
++ StopWatch timer;
++ timer.start();
++
++ // read in each line of the file
++ while ( ! in.eof() && starcount < FG_MAX_STARS )
++ {
++ in >> skipcomment;
++ string name;
++ getline( in, name, ',' );
++ in >> starlist[starcount];
++ ++starcount;
++ }
++
++ timer.stop();
++ FG_LOG( FG_ASTRO, FG_INFO,
++ "Loaded " << starcount << " stars in "
++ << timer.elapsedSeconds() << " seconds" );
++
++ min_magnitude[0] = 4.2;
++ min_magnitude[1] = 3.6;
++ min_magnitude[2] = 3.0;
++ min_magnitude[3] = 2.4;
++ min_magnitude[4] = 1.8;
++ min_magnitude[5] = 1.2;
++ min_magnitude[6] = 0.6;
++ min_magnitude[7] = 0.0;
++
++ // build the various star display lists
++ for ( i = 0; i < FG_STAR_LEVELS; i++ ) {
++
++ stars[i] = xglGenLists(1);
++ xglNewList( stars[i], GL_COMPILE );
++ xglBegin( GL_POINTS );
++
++ count = 0;
++
++ for ( j = 0; j < starcount; j++ ) {
++ magnitude = starlist[j].z();
++ // printf("magnitude = %.2f\n", magnitude);
++
++ if ( magnitude < min_magnitude[i] ) {
++ right_ascension = starlist[j].x();
++ declination = starlist[j].y();
++
++ count++;
++
++ // scale magnitudes to (0.0 - 1.0)
++ magnitude = (0.0 - magnitude) / 5.0 + 1.0;
++
++ // scale magnitudes again so they look ok
++ if ( magnitude > 1.0 ) { magnitude = 1.0; }
++ if ( magnitude < 0.0 ) { magnitude = 0.0; }
++ // magnitude =
++ // magnitude * 0.7 + (((FG_STAR_LEVELS - 1) - i) * 0.042);
++
++ magnitude = magnitude * 0.9 +
++ (((FG_STAR_LEVELS - 1) - i) * 0.014);
++ // printf(" Found star: %d %s, %.3f %.3f %.3f\n", count,
++ // name, right_ascension, declination, magnitude);
++
++ xglColor3f( magnitude, magnitude, magnitude );
++ //xglColor3f(0,0,0);*/
++ xglVertex3f( 50000.0*cos(right_ascension)*cos(declination),
++ 50000.0*sin(right_ascension)*cos(declination),
++ 50000.0*sin(declination) );
++ }
++ } // while
++
++ xglEnd();
++
++ /*
++ xglBegin(GL_LINE_LOOP);
++ xglColor3f(1.0, 0.0, 0.0);
++ xglVertex3f( 50000.0 * cos(ra_save-0.2) * cos(decl_save-0.2),
++ 50000.0 * sin(ra_save-0.2) * cos(decl_save-0.2),
++ 50000.0 * sin(decl_save-0.2) );
++ xglVertex3f( 50000.0 * cos(ra_save+0.2) * cos(decl_save-0.2),
++ 50000.0 * sin(ra_save+0.2) * cos(decl_save-0.2),
++ 50000.0 * sin(decl_save-0.2) );
++ xglVertex3f( 50000.0 * cos(ra_save+0.2) * cos(decl_save+0.2),
++ 50000.0 * sin(ra_save+0.2) * cos(decl_save+0.2),
++ 50000.0 * sin(decl_save+0.2) );
++ xglVertex3f( 50000.0 * cos(ra_save-0.2) * cos(decl_save+0.2),
++ 50000.0 * sin(ra_save-0.2) * cos(decl_save+0.2),
++ 50000.0 * sin(decl_save+0.2) );
++ xglEnd();
++ */
++
++ /*
++ xglBegin(GL_LINE_LOOP);
++ xglColor3f(0.0, 1.0, 0.0);
++ xglVertex3f( 50000.0 * cos(ra_save1-0.2) * cos(decl_save1-0.2),
++ 50000.0 * sin(ra_save1-0.2) * cos(decl_save1-0.2),
++ 50000.0 * sin(decl_save1-0.2) );
++ xglVertex3f( 50000.0 * cos(ra_save1+0.2) * cos(decl_save1-0.2),
++ 50000.0 * sin(ra_save1+0.2) * cos(decl_save1-0.2),
++ 50000.0 * sin(decl_save1-0.2) );
++ xglVertex3f( 50000.0 * cos(ra_save1+0.2) * cos(decl_save1+0.2),
++ 50000.0 * sin(ra_save1+0.2) * cos(decl_save1+0.2),
++ 50000.0 * sin(decl_save1+0.2) );
++ xglVertex3f( 50000.0 * cos(ra_save1-0.2) * cos(decl_save1+0.2),
++ 50000.0 * sin(ra_save1-0.2) * cos(decl_save1+0.2),
++ 50000.0 * sin(decl_save1+0.2) );
++ xglEnd();
++ */
++
++ xglEndList();
++
++ FG_LOG( FG_ASTRO, FG_INFO,
++ " Loading " << count << " stars brighter than "
++ << min_magnitude[i] );
++ }
++
++ return 1; // OK, we got here because initialization worked.
++}
++
++
++// Draw the Stars
++void fgStarsRender( void ) {
++ FGInterface *f;
++ fgLIGHT *l;
++ fgTIME *t;
++ int i;
++
++ f = current_aircraft.fdm_state;
++ l = &cur_light_params;
++ t = &cur_time_params;
++
++ // FG_PI_2 + 0.1 is about 6 degrees after sundown and before sunrise
++
++ // t->sun_angle = 3.0; // to force stars to be drawn (for testing)
++
++ // render the stars
++ if ( l->sun_angle > (FG_PI_2 + 5 * DEG_TO_RAD ) ) {
++ // determine which star structure to draw
++ if ( l->sun_angle > (FG_PI_2 + 10.0 * DEG_TO_RAD ) ) {
++ i = 0;
++ } else if ( l->sun_angle > (FG_PI_2 + 8.8 * DEG_TO_RAD ) ) {
++ i = 1;
++ } else if ( l->sun_angle > (FG_PI_2 + 7.5 * DEG_TO_RAD ) ) {
++ i = 2;
++ } else if ( l->sun_angle > (FG_PI_2 + 7.0 * DEG_TO_RAD ) ) {
++ i = 3;
++ } else if ( l->sun_angle > (FG_PI_2 + 6.5 * DEG_TO_RAD ) ) {
++ i = 4;
++ } else if ( l->sun_angle > (FG_PI_2 + 6.0 * DEG_TO_RAD ) ) {
++ i = 5;
++ } else if ( l->sun_angle > (FG_PI_2 + 5.5 * DEG_TO_RAD ) ) {
++ i = 6;
++ } else {
++ i = 7;
++ }
++
++ // printf("RENDERING STARS = %d (night)\n", i);
++
++ xglCallList(stars[i]);
++ } else {
++ // printf("not RENDERING STARS (day)\n");
++ }
++}
++
++
++// $Log$
++// Revision 1.27 1999/02/05 21:28:52 curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.26 1999/02/02 20:13:30 curt
++// MSVC++ portability changes by Bernie Bright:
++//
++// Lib/Serial/serial.[ch]xx: Initial Windows support - incomplete.
++// Simulator/Astro/stars.cxx: typo? included <stdio> instead of <cstdio>
++// Simulator/Cockpit/hud.cxx: Added Standard headers
++// Simulator/Cockpit/panel.cxx: Redefinition of default parameter
++// Simulator/Flight/flight.cxx: Replaced cout with FG_LOG. Deleted <stdio.h>
++// Simulator/Main/fg_init.cxx:
++// Simulator/Main/GLUTmain.cxx:
++// Simulator/Main/options.hxx: Shuffled <fg_serial.hxx> dependency
++// Simulator/Objects/material.hxx:
++// Simulator/Time/timestamp.hxx: VC++ friend kludge
++// Simulator/Scenery/tile.[ch]xx: Fixed using std::X declarations
++// Simulator/Main/views.hxx: Added a constant
++//
++// Revision 1.25 1998/12/09 18:50:15 curt
++// Converted "class fgVIEW" to "class FGView" and updated to make data
++// members private and make required accessor functions.
++//
++// Revision 1.24 1998/12/05 15:54:04 curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.23 1998/11/23 21:48:28 curt
++// Borland portability tweaks.
++//
++// Revision 1.22 1998/11/07 19:07:07 curt
++// Enable release builds using the --without-logging option to the configure
++// script. Also a couple log message cleanups, plus some C to C++ comment
++// conversion.
++//
++// Revision 1.21 1998/11/06 21:17:42 curt
++// Converted to new logstream debugging facility. This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.20 1998/11/06 14:47:02 curt
++// Changes to track Bernie's updates to fgstream.
++//
++// Revision 1.19 1998/10/16 23:27:21 curt
++// C++-ifying.
++//
++// Revision 1.18 1998/10/16 00:52:20 curt
++// Converted to Point3D class.
++//
++// Revision 1.17 1998/09/24 15:36:19 curt
++// Converted to c++ style comments.
++//
++// Revision 1.16 1998/09/24 15:25:24 curt
++// Miscellaneous tweaks.
++//
++//
++// Revision 1.15 1998/09/17 18:25:12 curt
++// Fixed output message.
++//
++// Revision 1.14 1998/09/15 04:26:22 curt
++// New textured moon and rewritten/restructured Astro code contributed by Durk
++// Talsma.
++//
++// Revision 1.13 1998/09/01 19:03:04 curt
++// Changes contributed by Bernie Bright <bbright@c031.aone.net.au>
++// - The new classes in libmisc.tgz define a stream interface into zlib.
++// I've put these in a new directory, Lib/Misc. Feel free to rename it
++// to something more appropriate. However you'll have to change the
++// include directives in all the other files. Additionally you'll have
++// add the library to Lib/Makefile.am and Simulator/Main/Makefile.am.
++//
++// The StopWatch class in Lib/Misc requires a HAVE_GETRUSAGE autoconf
++// test so I've included the required changes in config.tgz.
++//
++// There are a fair few changes to Simulator/Objects as I've moved
++// things around. Loading tiles is quicker but thats not where the delay
++// is. Tile loading takes a few tenths of a second per file on a P200
++// but it seems to be the post-processing that leads to a noticeable
++// blip in framerate. I suppose its time to start profiling to see where
++// the delays are.
++//
++// I've included a brief description of each archives contents.
++//
++// Lib/Misc/
++// zfstream.cxx
++// zfstream.hxx
++// C++ stream interface into zlib.
++// Taken from zlib-1.1.3/contrib/iostream/.
++// Minor mods for STL compatibility.
++// There's no copyright associated with these so I assume they're
++// covered by zlib's.
++//
++// fgstream.cxx
++// fgstream.hxx
++// FlightGear input stream using gz_ifstream. Tries to open the
++// given filename. If that fails then filename is examined and a
++// ".gz" suffix is removed or appended and that file is opened.
++//
++// stopwatch.hxx
++// A simple timer for benchmarking. Not used in production code.
++// Taken from the Blitz++ project. Covered by GPL.
++//
++// strutils.cxx
++// strutils.hxx
++// Some simple string manipulation routines.
++//
++// Simulator/Airports/
++// Load airports database using fgstream.
++// Changed fgAIRPORTS to use set<> instead of map<>.
++// Added bool fgAIRPORTS::search() as a neater way doing the lookup.
++// Returns true if found.
++//
++// Simulator/Astro/
++// Modified fgStarsInit() to load stars database using fgstream.
++//
++// Simulator/Objects/
++// Modified fgObjLoad() to use fgstream.
++// Modified fgMATERIAL_MGR::load_lib() to use fgstream.
++// Many changes to fgMATERIAL.
++// Some changes to fgFRAGMENT but I forget what!
++//
++// Revision 1.12 1998/08/27 17:02:01 curt
++// Contributions from Bernie Bright <bbright@c031.aone.net.au>
++// - use strings for fg_root and airport_id and added methods to return
++// them as strings,
++// - inlined all access methods,
++// - made the parsing functions private methods,
++// - deleted some unused functions.
++// - propogated some of these changes out a bit further.
++//
++// Revision 1.11 1998/08/25 20:53:29 curt
++// Shuffled $FG_ROOT file layout.
++//
++// Revision 1.10 1998/08/10 20:33:09 curt
++// Rewrote star loading and rendering to:
++// 1. significantly improve load speed
++// 2. transition from no stars to stars through eight stages.
++//
++// Revision 1.9 1998/08/06 12:45:20 curt
++// Modified to bring in stars in 8 increments based on magnitude, not number
++// of stars.
++//
++// Revision 1.8 1998/07/13 21:00:10 curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.7 1998/05/29 20:35:42 curt
++// Added zlib support for reading in compressed data files.
++//
++// Revision 1.6 1998/05/13 18:25:35 curt
++// Root path info moved to fgOPTIONS.
++//
++// Revision 1.5 1998/04/28 01:19:03 curt
++// Type-ified fgTIME and fgVIEW
++//
++// Revision 1.4 1998/04/26 05:10:02 curt
++// "struct fgLIGHT" -> "fgLIGHT" because fgLIGHT is typedef'd.
++//
++// Revision 1.3 1998/04/25 22:06:26 curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.2 1998/04/24 00:45:03 curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Fixed a bug when generating sky colors.
++//
++// Revision 1.1 1998/04/22 13:21:34 curt
++// C++ - ifing the code a bit.
++//
++// Revision 1.11 1998/04/18 04:13:58 curt
++// Moved fg_debug.c to it's own library.
++//
++// Revision 1.10 1998/04/03 21:52:51 curt
++// Converting to Gnu autoconf system.
++//
++// Revision 1.9 1998/03/14 00:27:12 curt
++// Updated fgGENERAL to a "type" of struct.
++//
++// Revision 1.8 1998/02/12 21:59:38 curt
++// Incorporated code changes contributed by Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.7 1998/02/09 15:07:48 curt
++// Minor tweaks.
++//
++// Revision 1.6 1998/02/02 20:53:23 curt
++// To version 0.29
++//
++// Revision 1.5 1998/01/27 18:35:53 curt
++// Minor tweaks.
++//
++// Revision 1.4 1998/01/27 00:47:49 curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.3 1998/01/19 19:26:59 curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.2 1998/01/19 18:40:18 curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.1 1998/01/07 03:16:20 curt
++// Moved from .../Src/Scenery/ to .../Src/Astro/
++//
++// Revision 1.24 1997/12/30 22:22:39 curt
++// Further integration of event manager.
++//
++// Revision 1.23 1997/12/30 20:47:53 curt
++// Integrated new event manager with subsystem initializations.
++//
++// Revision 1.22 1997/12/30 16:36:53 curt
++// Merged in Durk's changes ...
++//
++// Revision 1.21 1997/12/19 23:35:00 curt
++// Lot's of tweaking with sky rendering and lighting.
++//
++// Revision 1.20 1997/12/15 23:55:03 curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.19 1997/12/12 19:53:00 curt
++// Working on lightling and material properties.
++//
++// Revision 1.18 1997/12/10 22:37:52 curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.17 1997/12/09 04:25:33 curt
++// Working on adding a global lighting params structure.
++//
++// Revision 1.16 1997/11/25 19:25:38 curt
++// Changes to integrate Durk's moon/sun code updates + clean up.
++//
++// Revision 1.15 1997/10/30 12:38:45 curt
++// Working on new scenery subsystem.
++//
++// Revision 1.14 1997/10/28 21:00:22 curt
++// Changing to new terrain format.
++//
++// Revision 1.13 1997/10/25 03:18:28 curt
++// Incorporated sun, moon, and planet position and rendering code contributed
++// by Durk Talsma.
++//
++// Revision 1.12 1997/09/23 00:29:43 curt
++// Tweaks to get things to compile with gcc-win32.
++//
++// Revision 1.11 1997/09/22 14:44:21 curt
++// Continuing to try to align stars correctly.
++//
++// Revision 1.10 1997/09/20 03:34:32 curt
++// Still trying to get those durned stars aligned properly.
++//
++// Revision 1.9 1997/09/18 16:20:09 curt
++// At dusk/dawn add/remove stars in stages.
++//
++// Revision 1.8 1997/09/16 22:14:52 curt
++// Tweaked time of day lighting equations. Don't draw stars during the day.
++//
++// Revision 1.7 1997/09/16 15:50:31 curt
++// Working on star alignment and time issues.
++//
++// Revision 1.6 1997/09/05 14:17:31 curt
++// More tweaking with stars.
++//
++// Revision 1.5 1997/09/05 01:35:59 curt
++// Working on getting stars right.
++//
++// Revision 1.4 1997/09/04 02:17:38 curt
++// Shufflin' stuff.
++//
++// Revision 1.3 1997/08/29 17:55:28 curt
++// Worked on properly aligning the stars.
++//
++// Revision 1.2 1997/08/27 21:32:30 curt
++// Restructured view calculation code. Added stars.
++//
++// Revision 1.1 1997/08/27 03:34:48 curt
++// Initial revision.
++
++
--- /dev/null
--- /dev/null
++// stars.hxx -- data structures and routines for managing and rendering stars.
++//
++// Written by Curtis Olson, started August 1997.
++//
++// Copyright (C) 1997 Curtis L. Olson - curt@me.umn.edu
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#ifndef _STARS_HXX
++#define _STARS_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++#include <Time/fg_time.hxx>
++
++#define FG_STAR_LEVELS 8 // how many star transitions
++
++// Initialize the Star Management Subsystem
++int fgStarsInit( void );
++
++// Draw the Stars
++void fgStarsRender( void );
++
++// [no longer used?] extern struct OrbElements pltOrbElements[9];
++extern fgTIME cur_time_params;
++
++
++#endif // _STARS_HXX
++
++
++// $Log$
++// Revision 1.8 1999/01/19 20:57:00 curt
++// MacOS portability changes contributed by "Robert Puyol" <puyol@abvent.fr>
++//
++// Revision 1.7 1998/09/24 15:36:20 curt
++// Converted to c++ style comments.
++//
++// Revision 1.6 1998/09/24 15:25:26 curt
++// Miscellaneous tweaks.
++//
++//
++// Revision 1.5 1998/09/17 18:25:13 curt
++// Fixed output message.
++//
++// Revision 1.4 1998/09/15 04:26:23 curt
++// New textured moon and rewritten/restructured Astro code contributed by Durk
++// Talsma.
++//
++// Revision 1.3 1998/08/06 12:45:20 curt
++// Modified to bring in stars in 8 increments based on magnitude, not number
++// of stars.
++//
++// Revision 1.2 1998/04/28 01:19:03 curt
++// Type-ified fgTIME and fgVIEW
++//
++// Revision 1.1 1998/04/22 13:21:35 curt
++// C++ - ifing the code a bit.
++//
++// Revision 1.5 1998/04/21 17:02:33 curt
++// Prepairing for C++ integration.
++//
++// Revision 1.4 1998/02/12 21:59:39 curt
++// Incorporated code changes contributed by Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.3 1998/01/22 02:59:28 curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.2 1998/01/19 18:40:18 curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.1 1998/01/07 03:16:20 curt
++// Moved from .../Src/Scenery/ to .../Src/Astro/
++//
++// Revision 1.6 1997/10/25 03:18:29 curt
++// Incorporated sun, moon, and planet position and rendering code contributed
++// by Durk Talsma.
++//
++// Revision 1.5 1997/09/18 16:20:09 curt
++// At dusk/dawn add/remove stars in stages.
++//
++// Revision 1.4 1997/09/05 01:36:00 curt
++// Working on getting stars right.
++//
++// Revision 1.3 1997/08/29 17:55:28 curt
++// Worked on properly aligning the stars.
++//
++// Revision 1.2 1997/08/27 21:32:30 curt
++// Restructured view calculation code. Added stars.
++//
++// Revision 1.1 1997/08/27 03:34:50 curt
++// Initial revision.
++//
++
--- /dev/null
--- /dev/null
++/**************************************************************************
++ * uranus.cxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution
++ * with the FlightGear project. Version 2 was written in August and
++ * September 1998. This code is based upon algorithms and data kindly
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se).
++ *
++ * 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$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++#ifdef __BORLANDC__
++# define exception c_exception
++#endif
++#include <math.h>
++
++#include "uranus.hxx"
++
++/*************************************************************************
++ * Uranus::Uranus(fgTIME *t)
++ * Public constructor for class Uranus
++ * Argument: The current time.
++ * the hard coded orbital elements for Uranus are passed to
++ * CelestialBody::CelestialBody();
++ ************************************************************************/
++Uranus::Uranus(fgTIME *t) :
++ CelestialBody(74.00050, 1.3978000E-5,
++ 0.7733, 1.900E-8,
++ 96.66120, 3.0565000E-5,
++ 19.181710, -1.55E-8,
++ 0.047318, 7.450E-9,
++ 142.5905, 0.01172580600, t)
++{
++}
++
++/*************************************************************************
++ * void Uranus::updatePosition(fgTIME *t, Star *ourSun)
++ *
++ * calculates the current position of Uranus, by calling the base class,
++ * CelestialBody::updatePosition(); The current magnitude is calculated using
++ * a Uranus specific equation
++ *************************************************************************/
++void Uranus::updatePosition(fgTIME *t, Star *ourSun)
++{
++ CelestialBody::updatePosition(t, ourSun);
++ magnitude = -7.15 + 5*log10( r*R) + 0.001 * FV;
++}
--- /dev/null
--- /dev/null
++/**************************************************************************
++ * uranus.hxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution
++ * with the FlightGear project. Version 2 was written in August and
++ * September 1998. This code is based upon algorithms and data kindly
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se).
++ *
++ * 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$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++#ifndef _URANUS_HXX_
++#define _URANUS_HXX_
++
++#include <Time/fg_time.hxx>
++#include "celestialBody.hxx"
++#include "star.hxx"
++
++class Uranus : public CelestialBody
++{
++public:
++ Uranus ( fgTIME *t);
++ void updatePosition(fgTIME *t, Star *ourSun);
++};
++
++#endif // _URANUS_HXX_
--- /dev/null
--- /dev/null
++/**************************************************************************
++ * venus.cxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution
++ * with the FlightGear project. Version 2 was written in August and
++ * September 1998. This code is based upon algorithms and data kindly
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se).
++ *
++ * 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$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++#ifdef __BORLANDC__
++# define exception c_exception
++#endif
++#include <math.h>
++
++#include "venus.hxx"
++
++/*************************************************************************
++ * Venus::Venus(fgTIME *t)
++ * Public constructor for class Venus
++ * Argument: The current time.
++ * the hard coded orbital elements for Venus are passed to
++ * CelestialBody::CelestialBody();
++ ************************************************************************/
++Venus::Venus(fgTIME *t) :
++ CelestialBody(76.67990, 2.4659000E-5,
++ 3.3946, 2.75E-8,
++ 54.89100, 1.3837400E-5,
++ 0.7233300, 0.000000,
++ 0.006773, -1.302E-9,
++ 48.00520, 1.60213022440, t)
++{
++}
++
++/*************************************************************************
++ * void Venus::updatePosition(fgTIME *t, Star *ourSun)
++ *
++ * calculates the current position of Venus, by calling the base class,
++ * CelestialBody::updatePosition(); The current magnitude is calculated using
++ * a Venus specific equation
++ *************************************************************************/
++void Venus::updatePosition(fgTIME *t, Star *ourSun)
++{
++ CelestialBody::updatePosition(t, ourSun);
++ magnitude = -4.34 + 5*log10( r*R ) + 0.013 * FV + 4.2E-07 * pow(FV,3);
++}
--- /dev/null
--- /dev/null
++/**************************************************************************
++ * venus.hxx
++ * Written by Durk Talsma. Originally started October 1997, for distribution
++ * with the FlightGear project. Version 2 was written in August and
++ * September 1998. This code is based upon algorithms and data kindly
++ * provided by Mr. Paul Schlyter. (pausch@saaf.se).
++ *
++ * 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$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++#ifndef _VENUS_HXX_
++#define _VENUS_HXX_
++
++#include <Time/fg_time.hxx>
++#include "celestialBody.hxx"
++#include "star.hxx"
++
++class Venus : public CelestialBody
++{
++public:
++ Venus ( fgTIME *t);
++ void updatePosition(fgTIME *t, Star *ourSun);
++};
++
++#endif // _VENUS_HXX_
--- /dev/null
--- /dev/null
++noinst_LIBRARIES = libAutopilot.a
++
++libAutopilot_a_SOURCES = autopilot.cxx autopilot.hxx
++
++INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib -I$(top_builddir)/Simulator
--- /dev/null
--- /dev/null
++// autopilot.cxx -- autopilot subsystem
++//
++// Written by Jeff Goeke-Smith, started April 1998.
++//
++// Copyright (C) 1998 Jeff Goeke-Smith, jgoeke@voyager.net
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#include <assert.h>
++#include <stdlib.h>
++
++#include <Scenery/scenery.hxx>
++
++#include "autopilot.hxx"
++
++#include <Include/fg_constants.h>
++#include <Debug/logstream.hxx>
++#include <Main/options.hxx>
++
++
++// The below routines were copied right from hud.c ( I hate reinventing
++// the wheel more than necessary)
++
++// The following routines obtain information concerntin the aircraft's
++// current state and return it to calling instrument display routines.
++// They should eventually be member functions of the aircraft.
++//
++
++
++static double get_speed( void )
++{
++ return( current_aircraft.fdm_state->get_V_equiv_kts() );
++}
++
++static double get_aoa( void )
++{
++ return( current_aircraft.fdm_state->get_Gamma_vert_rad() * RAD_TO_DEG );
++}
++
++static double fgAPget_roll( void )
++{
++ return( current_aircraft.fdm_state->get_Phi() * RAD_TO_DEG );
++}
++
++static double get_pitch( void )
++{
++ return( current_aircraft.fdm_state->get_Theta() );
++}
++
++double fgAPget_heading( void )
++{
++ return( current_aircraft.fdm_state->get_Psi() * RAD_TO_DEG );
++}
++
++static double fgAPget_altitude( void )
++{
++ return( current_aircraft.fdm_state->get_Altitude() * FEET_TO_METER );
++}
++
++static double fgAPget_climb( void )
++{
++ // return in meters per minute
++ return( current_aircraft.fdm_state->get_Climb_Rate() * FEET_TO_METER * 60 );
++}
++
++static double get_sideslip( void )
++{
++ return( current_aircraft.fdm_state->get_Beta() );
++}
++
++static double fgAPget_agl( void )
++{
++ double agl;
++
++ agl = current_aircraft.fdm_state->get_Altitude() * FEET_TO_METER
++ - scenery.cur_elev;
++
++ return( agl );
++}
++
++// End of copied section. ( thanks for the wheel :-)
++
++// Local Prototype section
++
++double LinearExtrapolate( double x,double x1, double y1, double x2, double y2);
++double NormalizeDegrees( double Input);
++
++// End Local ProtoTypes
++
++fgAPDataPtr APDataGlobal; // global variable holding the AP info
++ // I want this gone. Data should be in aircraft structure
++
++
++bool fgAPHeadingEnabled( void )
++{
++ fgAPDataPtr APData;
++
++ APData = APDataGlobal;
++
++ // heading hold enabled?
++ return APData->heading_hold;
++}
++
++bool fgAPAltitudeEnabled( void )
++{
++ fgAPDataPtr APData;
++
++ APData = APDataGlobal;
++
++ // altitude hold or terrain follow enabled?
++ return APData->altitude_hold || APData->terrain_follow ;
++}
++
++bool fgAPAutoThrottleEnabled( void )
++{
++ fgAPDataPtr APData;
++
++ APData = APDataGlobal;
++
++ // autothrottle enabled?
++ return APData->auto_throttle;
++}
++
++void fgAPAltitudeAdjust( double inc )
++{
++ // Remove at a later date
++ fgAPDataPtr APData;
++ APData = APDataGlobal;
++ // end section
++
++ double target_alt, target_agl;
++
++ if ( current_options.get_units() == fgOPTIONS::FG_UNITS_FEET ) {
++ target_alt = APData->TargetAltitude * METER_TO_FEET;
++ target_agl = APData->TargetAGL * METER_TO_FEET;
++ } else {
++ target_alt = APData->TargetAltitude;
++ target_agl = APData->TargetAGL;
++ }
++
++ target_alt = (int)(target_alt / inc) * inc + inc;
++ target_agl = (int)(target_agl / inc) * inc + inc;
++
++ if ( current_options.get_units() == fgOPTIONS::FG_UNITS_FEET ) {
++ target_alt *= FEET_TO_METER;
++ target_agl *= FEET_TO_METER;
++ }
++
++ APData->TargetAltitude = target_alt;
++ APData->TargetAGL = target_agl;
++}
++
++void fgAPHeadingAdjust( double inc )
++{
++ fgAPDataPtr APData;
++ APData = APDataGlobal;
++
++ double target = (int)(APData->TargetHeading / inc) * inc + inc;
++
++ APData->TargetHeading = NormalizeDegrees(target);
++}
++
++void fgAPAutoThrottleAdjust( double inc )
++{
++ fgAPDataPtr APData;
++ APData = APDataGlobal;
++
++ double target = (int)(APData->TargetSpeed / inc) * inc + inc;
++
++ APData->TargetSpeed = target;
++}
++
++void fgAPInit( fgAIRCRAFT *current_aircraft )
++{
++ fgAPDataPtr APData ;
++
++ FG_LOG( FG_AUTOPILOT, FG_INFO, "Init AutoPilot Subsystem" );
++
++ APData = (fgAPDataPtr)calloc(sizeof(fgAPData),1);
++
++ if (APData == NULL) {
++ // I couldn't get the mem. Dying
++ FG_LOG( FG_AUTOPILOT, FG_ALERT, "No ram for Autopilot. Dying.");
++ exit(-1);
++ }
++
++ APData->heading_hold = false ; // turn the heading hold off
++ APData->altitude_hold = false ; // turn the altitude hold off
++
++ APData->TargetHeading = 0.0; // default direction, due north
++ APData->TargetAltitude = 3000; // default altitude in meters
++ APData->alt_error_accum = 0.0;
++
++ // These eventually need to be read from current_aircaft somehow.
++
++#if 0
++ // Original values
++ // the maximum roll, in Deg
++ APData->MaxRoll = 7;
++ // the deg from heading to start rolling out at, in Deg
++ APData->RollOut = 30;
++ // how far can I move the aleron from center.
++ APData->MaxAileron= .1;
++ // Smoothing distance for alerion control
++ APData->RollOutSmooth = 10;
++#endif
++
++ // the maximum roll, in Deg
++ APData->MaxRoll = 20;
++
++ // the deg from heading to start rolling out at, in Deg
++ APData->RollOut = 20;
++
++ // how far can I move the aleron from center.
++ APData->MaxAileron= .2;
++
++ // Smoothing distance for alerion control
++ APData->RollOutSmooth = 10;
++
++ //Remove at a later date
++ APDataGlobal = APData;
++
++};
++
++int fgAPRun( void )
++{
++ // Remove the following lines when the calling funcitons start
++ // passing in the data pointer
++
++ fgAPDataPtr APData;
++
++ APData = APDataGlobal;
++ // end section
++
++ // heading hold enabled?
++ if ( APData->heading_hold == true ) {
++ double RelHeading;
++ double TargetRoll;
++ double RelRoll;
++ double AileronSet;
++
++ RelHeading =
++ NormalizeDegrees( APData->TargetHeading - fgAPget_heading());
++ // figure out how far off we are from desired heading
++
++ // Now it is time to deterime how far we should be rolled.
++ FG_LOG( FG_AUTOPILOT, FG_DEBUG, "RelHeading: " << RelHeading );
++
++
++ // Check if we are further from heading than the roll out point
++ if ( fabs(RelHeading) > APData->RollOut ) {
++ // set Target Roll to Max in desired direction
++ if (RelHeading < 0 ) {
++ TargetRoll = 0-APData->MaxRoll;
++ } else {
++ TargetRoll = APData->MaxRoll;
++ }
++ } else {
++ // We have to calculate the Target roll
++
++ // This calculation engine thinks that the Target roll
++ // should be a line from (RollOut,MaxRoll) to (-RollOut,
++ // -MaxRoll) I hope this works well. If I get ambitious
++ // some day this might become a fancier curve or
++ // something.
++
++ TargetRoll = LinearExtrapolate( RelHeading, -APData->RollOut,
++ -APData->MaxRoll, APData->RollOut,
++ APData->MaxRoll );
++ }
++
++ // Target Roll has now been Found.
++
++ // Compare Target roll to Current Roll, Generate Rel Roll
++
++ FG_LOG( FG_COCKPIT, FG_BULK, "TargetRoll: " << TargetRoll );
++
++ RelRoll = NormalizeDegrees(TargetRoll - fgAPget_roll());
++
++ // Check if we are further from heading than the roll out smooth point
++ if ( fabs(RelRoll) > APData->RollOutSmooth ) {
++ // set Target Roll to Max in desired direction
++ if (RelRoll < 0 ) {
++ AileronSet = 0-APData->MaxAileron;
++ } else {
++ AileronSet = APData->MaxAileron;
++ }
++ } else {
++ AileronSet = LinearExtrapolate( RelRoll, -APData->RollOutSmooth,
++ -APData->MaxAileron,
++ APData->RollOutSmooth,
++ APData->MaxAileron );
++ }
++
++ controls.set_aileron( AileronSet );
++ controls.set_rudder( 0.0 );
++ }
++
++ // altitude hold or terrain follow enabled?
++ if ( APData->altitude_hold || APData->terrain_follow ) {
++ double speed, max_climb, error;
++ double prop_error, int_error;
++ double prop_adj, int_adj, total_adj;
++
++ if ( APData->altitude_hold ) {
++ // normal altitude hold
++ APData->TargetClimbRate =
++ (APData->TargetAltitude - fgAPget_altitude()) * 8.0;
++ } else if ( APData->terrain_follow ) {
++ // brain dead ground hugging with no look ahead
++ APData->TargetClimbRate =
++ ( APData->TargetAGL - fgAPget_agl() ) * 16.0;
++ } else {
++ // just try to zero out rate of climb ...
++ APData->TargetClimbRate = 0.0;
++ }
++
++ speed = get_speed();
++
++ if ( speed < 90.0 ) {
++ max_climb = 0.0;
++ } else if ( speed < 100.0 ) {
++ max_climb = (speed - 90.0) * 20;
++ } else {
++ max_climb = ( speed - 100.0 ) * 4.0 + 200.0;
++ }
++
++ if ( APData->TargetClimbRate > max_climb ) {
++ APData->TargetClimbRate = max_climb;
++ }
++
++ if ( APData->TargetClimbRate < -400.0 ) {
++ APData->TargetClimbRate = -400.0;
++ }
++
++ error = fgAPget_climb() - APData->TargetClimbRate;
++
++ // accumulate the error under the curve ... this really should
++ // be *= delta t
++ APData->alt_error_accum += error;
++
++ // calculate integral error, and adjustment amount
++ int_error = APData->alt_error_accum;
++ // printf("error = %.2f int_error = %.2f\n", error, int_error);
++ int_adj = int_error / 8000.0;
++
++ // caclulate proportional error
++ prop_error = error;
++ prop_adj = prop_error / 2000.0;
++
++ total_adj = 0.9 * prop_adj + 0.1 * int_adj;
++ if ( total_adj > 0.6 ) { total_adj = 0.6; }
++ if ( total_adj < -0.2 ) { total_adj = -0.2; }
++
++ controls.set_elevator( total_adj );
++ }
++
++ // auto throttle enabled?
++ if ( APData->auto_throttle ) {
++ double error;
++ double prop_error, int_error;
++ double prop_adj, int_adj, total_adj;
++
++ error = APData->TargetSpeed - get_speed();
++
++ // accumulate the error under the curve ... this really should
++ // be *= delta t
++ APData->speed_error_accum += error;
++ if ( APData->speed_error_accum > 2000.0 ) {
++ APData->speed_error_accum = 2000.0;
++ }
++ if ( APData->speed_error_accum < -2000.0 ) {
++ APData->speed_error_accum = -2000.0;
++ }
++
++ // calculate integral error, and adjustment amount
++ int_error = APData->speed_error_accum;
++
++ // printf("error = %.2f int_error = %.2f\n", error, int_error);
++ int_adj = int_error / 200.0;
++
++ // caclulate proportional error
++ prop_error = error;
++ prop_adj = 0.5 + prop_error / 50.0;
++
++ total_adj = 0.9 * prop_adj + 0.1 * int_adj;
++ if ( total_adj > 1.0 ) { total_adj = 1.0; }
++ if ( total_adj < 0.0 ) { total_adj = 0.0; }
++
++ controls.set_throttle( FGControls::ALL_ENGINES, total_adj );
++ }
++
++ /*
++ if (APData->Mode == 2) // Glide slope hold
++ {
++ double RelSlope;
++ double RelElevator;
++
++ // First, calculate Relative slope and normalize it
++ RelSlope = NormalizeDegrees( APData->TargetSlope - get_pitch());
++
++ // Now calculate the elevator offset from current angle
++ if ( abs(RelSlope) > APData->SlopeSmooth )
++ {
++ if ( RelSlope < 0 ) // set RelElevator to max in the correct direction
++ RelElevator = -APData->MaxElevator;
++ else
++ RelElevator = APData->MaxElevator;
++ }
++
++ else
++ RelElevator = LinearExtrapolate(RelSlope,-APData->SlopeSmooth,-APData->MaxElevator,APData->SlopeSmooth,APData->MaxElevator);
++
++ // set the elevator
++ fgElevMove(RelElevator);
++
++ }
++ */
++
++ // Ok, we are done
++ return 0;
++
++}
++
++/*
++void fgAPSetMode( int mode)
++{
++ //Remove the following line when the calling funcitons start passing in the data pointer
++ fgAPDataPtr APData;
++
++ APData = APDataGlobal;
++ // end section
++
++ fgPrintf( FG_COCKPIT, FG_INFO, "APSetMode : %d\n", mode );
++
++ APData->Mode = mode; // set the new mode
++}
++*/
++
++void fgAPToggleHeading( void )
++{
++ // Remove at a later date
++ fgAPDataPtr APData;
++
++ APData = APDataGlobal;
++ // end section
++
++ if ( APData->heading_hold ) {
++ // turn off heading hold
++ APData->heading_hold = false;
++ } else {
++ // turn on heading hold, lock at current heading
++ APData->heading_hold = true;
++ APData->TargetHeading = fgAPget_heading();
++ }
++
++ FG_LOG( FG_COCKPIT, FG_INFO, " fgAPSetHeading: ("
++ << APData->heading_hold << ") " << APData->TargetHeading );
++}
++
++
++void fgAPToggleAltitude( void )
++{
++ // Remove at a later date
++ fgAPDataPtr APData;
++
++ APData = APDataGlobal;
++ // end section
++
++ if ( APData->altitude_hold ) {
++ // turn off altitude hold
++ APData->altitude_hold = false;
++ } else {
++ // turn on altitude hold, lock at current altitude
++ APData->altitude_hold = true;
++ APData->terrain_follow = false;
++ APData->TargetAltitude = fgAPget_altitude();
++ APData->alt_error_accum = 0.0;
++ // alt_error_queue.erase( alt_error_queue.begin(),
++ // alt_error_queue.end() );
++ }
++
++ FG_LOG( FG_COCKPIT, FG_INFO, " fgAPSetAltitude: ("
++ << APData->altitude_hold << ") " << APData->TargetAltitude );
++}
++
++
++void fgAPToggleAutoThrottle ( void )
++{
++ // Remove at a later date
++ fgAPDataPtr APData;
++
++ APData = APDataGlobal;
++ // end section
++
++ if ( APData->auto_throttle ) {
++ // turn off altitude hold
++ APData->auto_throttle = false;
++ } else {
++ // turn on terrain follow, lock at current agl
++ APData->auto_throttle = true;
++ APData->TargetSpeed = get_speed();
++ APData->speed_error_accum = 0.0;
++ }
++
++ FG_LOG( FG_COCKPIT, FG_INFO, " fgAPSetAutoThrottle: ("
++ << APData->auto_throttle << ") " << APData->TargetSpeed );
++}
++
++void fgAPToggleTerrainFollow( void )
++{
++ // Remove at a later date
++ fgAPDataPtr APData;
++
++ APData = APDataGlobal;
++ // end section
++
++ if ( APData->terrain_follow ) {
++ // turn off altitude hold
++ APData->terrain_follow = false;
++ } else {
++ // turn on terrain follow, lock at current agl
++ APData->terrain_follow = true;
++ APData->altitude_hold = false;
++ APData->TargetAGL = fgAPget_agl();
++ APData->alt_error_accum = 0.0;
++ }
++
++ FG_LOG( FG_COCKPIT, FG_INFO, " fgAPSetTerrainFollow: ("
++ << APData->terrain_follow << ") " << APData->TargetAGL );
++}
++
++double LinearExtrapolate( double x,double x1,double y1,double x2,double y2)
++{
++ // This procedure extrapolates the y value for the x posistion on a line defined by x1,y1; x2,y2
++ //assert(x1 != x2); // Divide by zero error. Cold abort for now
++
++ double m, b, y; // the constants to find in y=mx+b
++
++ m=(y2-y1)/(x2-x1); // calculate the m
++
++ b= y1- m * x1; // calculate the b
++
++ y = m * x + b; // the final calculation
++
++ return (y);
++
++};
++
++double NormalizeDegrees(double Input)
++{
++ // normalize the input to the range (-180,180]
++ // Input should not be greater than -360 to 360. Current rules send the output to an undefined state.
++ if (Input > 180)
++ Input -= 360;
++ if (Input <= -180)
++ Input += 360;
++
++ return (Input);
++};
++
++
++// $Log$
++// Revision 1.15 1999/02/12 23:22:35 curt
++// Allow auto-throttle adjustment while active.
++//
++// Revision 1.14 1999/02/12 22:17:14 curt
++// Changes contributed by Norman Vine to allow adjustment of the autopilot
++// while it is activated.
++//
--- /dev/null
--- /dev/null
++// autopilot.hxx -- autopilot defines and prototypes (very alpha)
++//
++// Written by Jeff Goeke-Smith, started April 1998.
++//
++// Copyright (C) 1998 Jeff Goeke-Smith - jgoeke@voyager.net
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#ifndef _AUTOPILOT_HXX
++#define _AUTOPILOT_HXX
++
++
++#include <Aircraft/aircraft.hxx>
++#include <FDM/flight.hxx>
++#include <Controls/controls.hxx>
++
++
++// Structures
++typedef struct {
++ bool heading_hold; // the current state of the heading hold
++ bool altitude_hold; // the current state of the altitude hold
++ bool terrain_follow; // the current state of the terrain follower
++ bool auto_throttle; // the current state of the auto throttle
++
++ double TargetHeading; // the heading the AP should steer to.
++ double TargetAltitude; // altitude to hold
++ double TargetAGL; // the terrain separation
++ double TargetClimbRate; // climb rate to shoot for
++ double TargetSpeed; // speed to shoot for
++ double alt_error_accum; // altitude error accumulator
++ double speed_error_accum; // speed error accumulator
++
++ double TargetSlope; // the glide slope hold value
++
++ double MaxRoll ; // the max the plane can roll for the turn
++ double RollOut; // when the plane should roll out
++ // measured from Heading
++ double MaxAileron; // how far to move the aleroin from center
++ double RollOutSmooth; // deg to use for smoothing Aileron Control
++ double MaxElevator; // the maximum elevator allowed
++ double SlopeSmooth; // smoothing angle for elevator
++
++} fgAPData, *fgAPDataPtr ;
++
++
++// Defines
++#define AP_CURRENT_HEADING -1
++
++
++// prototypes
++void fgAPInit( fgAIRCRAFT *current_aircraft );
++int fgAPRun( void );
++void fgAPToggleHeading( void );
++void fgAPToggleAltitude( void );
++void fgAPToggleTerrainFollow( void );
++void fgAPToggleAutoThrottle( void );
++
++bool fgAPAltitudeEnabled( void );
++bool fgAPHeadingEnabled( void );
++bool fgAPAutoThrottleEnabled( void );
++void fgAPAltitudeAdjust( double inc );
++void fgAPHeadingAdjust( double inc );
++void fgAPAutoThrottleAdjust( double inc );
++
++
++#endif // _AUTOPILOT_HXX
++
++
++// $Log$
++// Revision 1.9 1999/02/12 23:22:36 curt
++// Allow auto-throttle adjustment while active.
++//
++// Revision 1.8 1999/02/12 22:17:15 curt
++// Changes contributed by Norman Vine to allow adjustment of the autopilot
++// while it is activated.
++//
--- /dev/null
--- /dev/null
++# The "checkoutlist" file is used to support additional version controlled
++# administrative files in $CVSROOT/CVSROOT, such as template files.
++#
++# The first entry on a line is a filename which will be checked out from
++# the corresponding RCS file in the $CVSROOT/CVSROOT directory.
++# The remainder of the line is an error message to use if the file cannot
++# be checked out.
++#
++# File format:
++#
++# [<whitespace>]<filename><whitespace><error message><end-of-line>
++#
++# comment lines begin with '#'
--- /dev/null
--- /dev/null
++# The "commitinfo" file is used to control pre-commit checks.
++# The filter on the right is invoked with the repository and a list
++# of files to check. A non-zero exit of the filter program will
++# cause the commit to be aborted.
++#
++# The first entry on a line is a regular expression which is tested
++# against the directory that the change is being committed to, relative
++# to the $CVSROOT. For the first match that is found, then the remainder
++# of the line is the name of the filter to run.
++#
++# If the repository name does not match any of the regular expressions in this
++# file, the "DEFAULT" line is used, if it is specified.
++#
++# If the name "ALL" appears as a regular expression it is always used
++# in addition to the first matching regex or "DEFAULT".
--- /dev/null
--- /dev/null
++# This file describes wrappers and other binary files to CVS.
++#
++# Wrappers are the concept where directories of files are to be
++# treated as a single file. The intended use is to wrap up a wrapper
++# into a single tar such that the tar archive can be treated as a
++# single binary file in CVS.
++#
++# To solve the problem effectively, it was also necessary to be able to
++# prevent rcsmerge from merging these files.
++#
++# Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers)
++#
++# wildcard [option value][option value]...
++#
++# where option is one of
++# -f from cvs filter value: path to filter
++# -t to cvs filter value: path to filter
++# -m update methodology value: MERGE or COPY
++#
++# and value is a single-quote delimited value.
++#
++# For example:
--- /dev/null
--- /dev/null
++# The "editinfo" file is used to allow verification of logging
++# information. It works best when a template (as specified in the
++# rcsinfo file) is provided for the logging procedure. Given a
++# template with locations for, a bug-id number, a list of people who
++# reviewed the code before it can be checked in, and an external
++# process to catalog the differences that were code reviewed, the
++# following test can be applied to the code:
++#
++# Making sure that the entered bug-id number is correct.
++# Validating that the code that was reviewed is indeed the code being
++# checked in (using the bug-id number or a seperate review
++# number to identify this particular code set.).
++#
++# If any of the above test failed, then the commit would be aborted.
++#
++# Actions such as mailing a copy of the report to each reviewer are
++# better handled by an entry in the loginfo file.
++#
++# One thing that should be noted is the the ALL keyword is not
++# supported. There can be only one entry that matches a given
++# repository.
--- /dev/null
--- /dev/null
++# The "loginfo" file is used to control where "cvs commit" log information is
++# sent. The first entry on a line is a regular expression which is tested
++# against the directory that the change is being made to, relative to the
++# $CVSROOT. For the first match that is found, the remainder of the line is a
++# filter program that should expect log information on its standard input
++#
++# If the repository name does not match any of the regular expressions in the
++# first field of this file, the "DEFAULT" line is used, if it is specified.
++#
++# If the name "ALL" appears as a regular expression it is always used
++# in addition to the first matching regex or "DEFAULT".
++#
++# The filter program may use one and only one "%s" modifier (ala printf). If
++# such a "%s" is specified in the filter program, a brief title is included
++# (as one argument, enclosed in single quotes) showing the relative directory
++# name and listing the modified file names.
++#
++# For example:
++#DEFAULT (echo ""; who am i; echo %s; date; cat) >> $CVSROOT/CVSROOT/commitlog
--- /dev/null
--- /dev/null
++# Three different line formats are valid:
++# key -a aliases...
++# key [options] directory
++# key [options] directory files...
++#
++# Where "options" are composed of:
++# -i prog Run "prog" on "cvs commit" from top-level of module.
++# -o prog Run "prog" on "cvs checkout" of module.
++# -e prog Run "prog" on "cvs export" of module.
++# -t prog Run "prog" on "cvs rtag" of module.
++# -u prog Run "prog" on "cvs update" of module.
++# -d dir Place module in directory "dir" instead of module name.
++# -l Top-level directory only -- do not recurse.
++#
++# NOTE: If you change any of the "Run" options above, you'll have to
++# release and re-checkout any working directories of these modules.
++#
++# And "directory" is a path to a directory relative to $CVSROOT.
++#
++# The "-a" option specifies an alias. An alias is interpreted as if
++# everything on the right of the "-a" had been typed on the command line.
++#
++# You can encode a module within a module by using the special '&'
++# character to interpose another module into the current module. This
++# can be useful for creating a module that consists of many directories
++# spread out over the entire source repository.
--- /dev/null
--- /dev/null
++# The "notify" file controls where notifications from watches set by
++# "cvs watch add" or "cvs edit" are sent. The first entry on a line is
++# a regular expression which is tested against the directory that the
++# change is being made to, relative to the $CVSROOT. If it matches,
++# then the remainder of the line is a filter program that should contain
++# one occurrence of %s for the user to notify, and information on its
++# standard input.
++#
++# "ALL" or "DEFAULT" can be used in place of the regular expression.
++#
++# For example:
++#ALL mail %s -s "CVS notification"
--- /dev/null
--- /dev/null
++# The "rcsinfo" file is used to control templates with which the editor
++# is invoked on commit and import.
++#
++# The first entry on a line is a regular expression which is tested
++# against the directory that the change is being made to, relative to the
++# $CVSROOT. For the first match that is found, then the remainder of the
++# line is the name of the file that contains the template.
++#
++# If the repository name does not match any of the regular expressions in this
++# file, the "DEFAULT" line is used, if it is specified.
++#
++# If the name "ALL" appears as a regular expression it is always used
++# in addition to the first matching regex or "DEFAULT".
--- /dev/null
--- /dev/null
++# The "taginfo" file is used to control pre-tag checks.
++# The filter on the right is invoked with the following arguments:
++#
++# $1 -- tagname
++# $2 -- operation "add" for tag, "mov" for tag -F, and "del" for tag -d
++# $3 -- repository
++# $4-> file revision [file revision ...]
++#
++# A non-zero exit of the filter program will cause the tag to be aborted.
++#
++# The first entry on a line is a regular expression which is tested
++# against the directory that the change is being committed to, relative
++# to the $CVSROOT. For the first match that is found, then the remainder
++# of the line is the name of the filter to run.
++#
++# If the repository name does not match any of the regular expressions in this
++# file, the "DEFAULT" line is used, if it is specified.
++#
++# If the name "ALL" appears as a regular expression it is always used
++# in addition to the first matching regex or "DEFAULT".
--- /dev/null
--- /dev/null
++noinst_LIBRARIES = libCockpit.a
++
++libCockpit_a_SOURCES = \
++ cockpit.cxx cockpit.hxx \
++ hud.cxx hud.hxx \
++ hud_card.cxx hud_dnst.cxx hud_guag.cxx hud_inst.cxx \
++ hud_labl.cxx hud_ladr.cxx hud_scal.cxx hud_tbi.cxx \
++ panel.cxx panel.hxx
++
++INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib -I$(top_builddir)/Simulator
--- /dev/null
--- /dev/null
++//*************************************************************************
++// cockpit.cxx -- routines to draw a cockpit (initial draft)
++//
++// Written by Michele America, started September 1997.
++//
++// Copyright (C) 1997 Michele F. America - nomimarketing@mail.telepac.pt
++//
++// 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$
++// (Log is kept at end of this file)
++//*************************************************************************/
++
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#include <stdlib.h>
++#include <stdio.h>
++#include <string.h>
++
++#include <Aircraft/aircraft.hxx>
++#include <Debug/logstream.hxx>
++#include <Include/fg_constants.h>
++#include <Include/general.hxx>
++#include <Main/options.hxx>
++#include <Main/views.hxx>
++#include <Math/fg_random.h>
++#include <Math/mat3.h>
++#include <Math/polar3d.hxx>
++#include <Scenery/scenery.hxx>
++#include <Time/fg_timer.hxx>
++
++#include "cockpit.hxx"
++#include "panel.hxx"
++
++
++// This is a structure that contains all data related to
++// cockpit/panel/hud system
++
++static pCockpit ac_cockpit;
++
++// The following routines obtain information concerntin the aircraft's
++// current state and return it to calling instrument display routines.
++// They should eventually be member functions of the aircraft.
++//
++
++double get_latitude( void )
++{
++ return((double)((int)( current_aircraft.fdm_state->get_Latitude()
++ * RAD_TO_DEG)) );
++}
++
++double get_lat_min( void )
++{
++ double a, d;
++
++ a = current_aircraft.fdm_state->get_Latitude() * RAD_TO_DEG;
++ if (a < 0.0) {
++ a = -a;
++ }
++ d = (double) ( (int) a);
++ return( (a - d) * 60.0);
++}
++
++double get_longitude( void )
++{
++ return( (double)((int) (current_aircraft.fdm_state->get_Longitude()
++ * RAD_TO_DEG)) );
++}
++
++double get_long_min( void )
++{
++ double a, d;
++
++ a = current_aircraft.fdm_state->get_Longitude() * RAD_TO_DEG;
++ if (a < 0.0) {
++ a = -a;
++ }
++ d = (double) ( (int) a);
++ return( (a - d) * 60.0);
++}
++
++double get_throttleval( void )
++{
++ return controls.get_throttle( 0 ); // Hack limiting to one engine
++}
++
++double get_aileronval( void )
++{
++ return controls.get_aileron();
++}
++
++double get_elevatorval( void )
++{
++ return controls.get_elevator();
++}
++
++double get_elev_trimval( void )
++{
++ return controls.get_elevator_trim();
++}
++
++double get_rudderval( void )
++{
++ return controls.get_rudder();
++}
++
++double get_speed( void )
++{
++ return( current_aircraft.fdm_state->get_V_equiv_kts() );
++}
++
++double get_aoa( void )
++{
++ return( current_aircraft.fdm_state->get_Alpha() * RAD_TO_DEG );
++}
++
++double get_roll( void )
++{
++ return( current_aircraft.fdm_state->get_Phi() );
++}
++
++double get_pitch( void )
++{
++ return( current_aircraft.fdm_state->get_Theta() );
++}
++
++double get_heading( void )
++{
++ return( current_aircraft.fdm_state->get_Psi() * RAD_TO_DEG );
++}
++
++double get_altitude( void )
++{
++ if ( current_options.get_units() == fgOPTIONS::FG_UNITS_FEET ) {
++ return current_aircraft.fdm_state->get_Altitude();
++ } else {
++ return current_aircraft.fdm_state->get_Altitude() * FEET_TO_METER;
++ }
++}
++
++double get_agl( void )
++{
++ if ( current_options.get_units() == fgOPTIONS::FG_UNITS_FEET ) {
++ return current_aircraft.fdm_state->get_Altitude()
++ - scenery.cur_elev * METER_TO_FEET;
++ } else {
++ return current_aircraft.fdm_state->get_Altitude() * FEET_TO_METER
++ - scenery.cur_elev;
++ }
++}
++
++double get_sideslip( void )
++{
++ return( current_aircraft.fdm_state->get_Beta() );
++}
++
++double get_frame_rate( void )
++{
++ return (double) general.get_frame_rate();
++}
++
++double get_fov( void )
++{
++ return (current_options.get_fov());
++}
++
++double get_vfc_ratio( void )
++{
++ return current_view.get_vfc_ratio();
++}
++
++double get_vfc_tris_drawn ( void )
++{
++ return current_view.get_tris_rendered();
++}
++
++double get_climb_rate( void )
++{
++ if ( current_options.get_units() == fgOPTIONS::FG_UNITS_FEET ) {
++ return current_aircraft.fdm_state->get_Climb_Rate() * 60.0;
++ } else {
++ return current_aircraft.fdm_state->get_Climb_Rate()
++ * FEET_TO_METER * 60.0;
++ }
++}
++
++
++bool fgCockpitInit( fgAIRCRAFT *cur_aircraft )
++{
++ FG_LOG( FG_COCKPIT, FG_INFO, "Initializing cockpit subsystem" );
++
++ // cockpit->code = 1; /* It will be aircraft dependent */
++ // cockpit->status = 0;
++
++ // If aircraft has HUD specified we will get the specs from its def
++ // file. For now we will depend upon hard coding in hud?
++
++ // We must insure that the existing instrument link is purged.
++ // This is done by deleting the links in the list.
++
++ // HI_Head is now a null pointer so we can generate a new list from the
++ // current aircraft.
++
++ fgHUDInit( cur_aircraft );
++ ac_cockpit = new fg_Cockpit();
++
++ if ( current_options.get_panel_status() ) {
++ new FGPanel;
++ }
++
++ FG_LOG( FG_COCKPIT, FG_INFO,
++ " Code " << ac_cockpit->code() << " Status "
++ << ac_cockpit->status() );
++
++ return true;
++}
++
++
++void fgCockpitUpdate( void ) {
++ FG_LOG( FG_COCKPIT, FG_DEBUG,
++ "Cockpit: code " << ac_cockpit->code() << " status "
++ << ac_cockpit->status() );
++
++ if ( current_options.get_hud_status() ) {
++ // This will check the global hud linked list pointer.
++ // If these is anything to draw it will.
++ fgUpdateHUD();
++ }
++
++ if ( current_options.get_panel_status() &&
++ (fabs( current_view.get_view_offset() ) < 0.2) )
++ {
++ xglViewport( 0, 0,
++ current_view.get_winWidth(),
++ current_view.get_winHeight() );
++ FGPanel::OurPanel->Update();
++ }
++}
++
++
++// $Log$
++// Revision 1.31 1999/03/08 21:56:08 curt
++// Added panel changes sent in by Friedemann.
++//
++// Revision 1.30 1999/02/05 21:28:57 curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.29 1999/01/08 19:27:34 curt
++// Fixed AOA reading on HUD.
++// Continued work on time jitter compensation.
++//
++// Revision 1.28 1999/01/07 20:24:17 curt
++// Update fgGENERAL to FGGeneral.
++//
++// Revision 1.27 1998/12/18 23:35:09 curt
++// Converted to a simpler frame rate counting method.
++//
++// Revision 1.26 1998/12/09 18:50:19 curt
++// Converted "class fgVIEW" to "class FGView" and updated to make data
++// members private and make required accessor functions.
++//
++// Revision 1.25 1998/12/05 15:54:07 curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.24 1998/12/03 01:16:00 curt
++// Converted fgFLIGHT to a class.
++//
++// Revision 1.23 1998/11/09 23:38:50 curt
++// Panel updates from Friedemann.
++//
++// Revision 1.22 1998/11/06 21:17:45 curt
++// Converted to new logstream debugging facility. This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.21 1998/11/02 23:04:02 curt
++// HUD units now display in feet by default with meters being a command line
++// option.
++//
++// Revision 1.20 1998/10/25 14:08:40 curt
++// Turned "struct fgCONTROLS" into a class, with inlined accessor functions.
++//
++// Revision 1.19 1998/10/17 01:33:56 curt
++// C++ ifying ...
++//
++// Revision 1.18 1998/10/16 23:27:23 curt
++// C++-ifying.
++//
++// Revision 1.17 1998/09/29 14:56:30 curt
++// c++-ified comments.
++//
++// Revision 1.16 1998/09/29 02:01:06 curt
++// Added a "rate of climb" indicator.
++//
++// Revision 1.15 1998/08/28 18:14:39 curt
++// Added new cockpit code from Friedemann Reinhard
++// <mpt218@faupt212.physik.uni-erlangen.de>
++//
++// Revision 1.14 1998/08/24 20:05:15 curt
++// Added a second minimalistic HUD.
++// Added code to display the number of triangles rendered.
++//
++// Revision 1.13 1998/08/22 01:19:27 curt
++// Omit panel code because it's texture loading overruns array bounds.
++//
++// Revision 1.12 1998/07/13 21:28:00 curt
++// Converted the aoa scale to a radio altimeter.
++//
++// Revision 1.11 1998/07/13 21:00:45 curt
++// Integrated Charlies latest HUD updates.
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.10 1998/07/08 14:41:08 curt
++// Renamed polar3d.h to polar3d.hxx
++//
++// Revision 1.9 1998/06/27 16:47:53 curt
++// Incorporated Friedemann Reinhard's <mpt218@faupt212.physik.uni-erlangen.de>
++// first pass at an isntrument panel.
++//
++// Revision 1.8 1998/05/17 16:58:12 curt
++// Added a View Frustum Culling ratio display to the hud.
++//
++// Revision 1.7 1998/05/16 13:04:13 curt
++// New updates from Charlie Hotchkiss.
++//
++// Revision 1.6 1998/05/13 18:27:53 curt
++// Added an fov to hud display.
++//
++// Revision 1.5 1998/05/11 18:13:10 curt
++// Complete C++ rewrite of all cockpit code by Charlie Hotchkiss.
++//
++// Revision 1.4 1998/05/03 00:46:45 curt
++// polar.h -> polar3d.h
++//
++// Revision 1.3 1998/04/30 12:36:02 curt
++// C++-ifying a couple source files.
++//
++// Revision 1.2 1998/04/25 22:06:26 curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.1 1998/04/24 00:45:54 curt
++// C++-ifing the code a bit.
++//
++// Revision 1.13 1998/04/18 04:14:01 curt
++// Moved fg_debug.c to it's own library.
++//
++// Revision 1.12 1998/04/14 02:23:09 curt
++// Code reorganizations. Added a Lib/ directory for more general libraries.
++//
++// Revision 1.11 1998/03/14 00:32:13 curt
++// Changed a printf() to a fgPrintf().
++//
++// Revision 1.10 1998/02/07 15:29:33 curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.9 1998/02/03 23:20:14 curt
++// Lots of little tweaks to fix various consistency problems discovered by
++// Solaris' CC. Fixed a bug in fg_debug.c with how the fgPrintf() wrapper
++// passed arguments along to the real printf(). Also incorporated HUD changes
++// by Michele America.
++//
++// Revision 1.8 1998/01/31 00:43:03 curt
++// Added MetroWorks patches from Carmen Volpe.
++//
++// Revision 1.7 1998/01/27 00:47:51 curt
++// Incorporated Paul Bleisch's <bleisch@chromatic.com> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.6 1998/01/19 19:27:01 curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.5 1998/01/19 18:40:19 curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.4 1997/12/30 20:47:34 curt
++// Integrated new event manager with subsystem initializations.
++//
++// Revision 1.3 1997/12/15 23:54:33 curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.2 1997/12/10 22:37:38 curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.1 1997/08/29 18:03:20 curt
++// Initial revision.
++//
++
--- /dev/null
--- /dev/null
++/**************************************************************************
++ * cockpit.hxx -- cockpit defines and prototypes (initial draft)
++ *
++ * Written by Michele America, started September 1997.
++ *
++ * Copyright (C) 1997 Michele F. America - nomimarketing@mail.telepac.pt
++ *
++ * 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$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++
++#ifndef _COCKPIT_HXX
++#define _COCKPIT_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++
++#include "hud.hxx"
++#include "panel.hxx"
++
++// Class fg_Cockpit This class is a holder for the heads up display
++// and is initialized with a
++class fg_Cockpit {
++ private:
++ int Code;
++ int Status;
++
++ public:
++ fg_Cockpit () : Code(1), Status(0) {};
++ int code ( void ) { return Code; }
++ int status( void ) { return Status; }
++};
++
++
++typedef fg_Cockpit * pCockpit;
++
++bool fgCockpitInit( fgAIRCRAFT *cur_aircraft );
++void fgCockpitUpdate( void );
++
++
++#endif /* _COCKPIT_HXX */
++
++
++/* $Log$
++/* Revision 1.4 1998/07/13 21:00:46 curt
++/* Integrated Charlies latest HUD updates.
++/* Wrote access functions for current fgOPTIONS.
++/*
++ * Revision 1.3 1998/06/27 16:47:54 curt
++ * Incorporated Friedemann Reinhard's <mpt218@faupt212.physik.uni-erlangen.de>
++ * first pass at an isntrument panel.
++ *
++ * Revision 1.2 1998/05/11 18:13:10 curt
++ * Complete C++ rewrite of all cockpit code by Charlie Hotchkiss.
++ *
++ * Revision 1.1 1998/04/24 00:45:55 curt
++ * C++-ifing the code a bit.
++ *
++ * Revision 1.8 1998/04/22 13:26:19 curt
++ * C++ - ifing the code a bit.
++ *
++ * Revision 1.7 1998/04/21 17:02:34 curt
++ * Prepairing for C++ integration.
++ *
++ * Revision 1.6 1998/02/07 15:29:33 curt
++ * Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++ * <chotchkiss@namg.us.anritsu.com>
++ *
++ * Revision 1.5 1998/01/22 02:59:29 curt
++ * Changed #ifdef FILE_H to #ifdef _FILE_H
++ *
++ * Revision 1.4 1998/01/19 19:27:01 curt
++ * Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++ * This should simplify things tremendously.
++ *
++ * Revision 1.3 1998/01/19 18:40:19 curt
++ * Tons of little changes to clean up the code and to remove fatal errors
++ * when building with the c++ compiler.
++ *
++ * Revision 1.2 1997/12/10 22:37:39 curt
++ * Prepended "fg" on the name of all global structures that didn't have it yet.
++ * i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++ *
++ * Revision 1.1 1997/08/29 18:03:21 curt
++ * Initial revision.
++ *
++ */
--- /dev/null
--- /dev/null
++// hud.cxx -- hud defines and prototypes
++//
++// Written by Michele America, started September 1997.
++//
++// Copyright (C) 1997 Michele F. America - micheleamerica@geocities.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$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++
++#ifdef __BORLANDC__
++# define exception c_exception
++#endif
++#include <math.h>
++
++#include <GL/glut.h>
++#include <stdlib.h>
++#include <string.h>
++
++#include <Aircraft/aircraft.hxx>
++#include <Debug/logstream.hxx>
++#include <Include/fg_constants.h>
++#include <Main/options.hxx>
++#include <Math/fg_random.h>
++#include <Math/mat3.h>
++#include <Math/polar3d.hxx>
++#include <Scenery/scenery.hxx>
++#include <Time/fg_timer.hxx>
++
++#if defined ( __sun__ ) || defined ( __sgi )
++extern "C" {
++ extern void *memmove(void *, const void *, size_t);
++}
++#endif
++
++#include "hud.hxx"
++
++
++static char units[5];
++
++// The following routines obtain information concerntin the aircraft's
++// current state and return it to calling instrument display routines.
++// They should eventually be member functions of the aircraft.
++//
++
++HudContainerType HUD_deque;
++
++class locRECT {
++ public:
++ RECT rect;
++
++ locRECT( UINT left, UINT top, UINT right, UINT bottom);
++ RECT get_rect(void) { return rect;}
++};
++
++locRECT :: locRECT( UINT left, UINT top, UINT right, UINT bottom)
++{
++ rect.left = left;
++ rect.top = top;
++ rect.right = right;
++ rect.bottom = bottom;
++
++}
++// #define DEBUG
++
++void drawOneLine( UINT x1, UINT y1, UINT x2, UINT y2)
++{
++ glBegin(GL_LINES);
++ glVertex2f(x1, y1);
++ glVertex2f(x2, y2);
++ glEnd();
++}
++
++void drawOneLine( RECT &rect)
++{
++ glBegin(GL_LINES);
++ glVertex2f(rect.left, rect.top);
++ glVertex2f(rect.right, rect.bottom);
++ glEnd();
++}
++
++//
++// The following code deals with painting the "instrument" on the display
++//
++ /* textString - Bitmap font string */
++
++void textString( int x, int y, char *msg, void *font ){
++ glRasterPos2f(x, y);
++ while (*msg) {
++ glutBitmapCharacter(font, *msg);
++ msg++;
++ }
++}
++
++/* strokeString - Stroke font string */
++
++void strokeString(int x, int y, char *msg, void *font, float theta)
++{
++int xx;
++int yy;
++
++ glPushMatrix();
++ glRotatef(theta * RAD_TO_DEG, 0.0, 0.0, 1.0);
++ xx = (int)(x * cos(theta) + y * sin( theta ));
++ yy = (int)(y * cos(theta) - x * sin( theta ));
++ glTranslatef( xx, yy, 0);
++ glScalef(.1, .1, 0.0);
++ while (*msg) {
++ glutStrokeCharacter(font, *msg);
++ msg++;
++ }
++ glPopMatrix();
++}
++
++//========================= End of Class Implementations===================
++// fgHUDInit
++//
++// Constructs a HUD object and then adds in instruments. At the present
++// the instruments are hard coded into the routine. Ultimately these need
++// to be defined by the aircraft's instrumentation records so that the
++// display for a Piper Cub doesn't show the speed range of a North American
++// mustange and the engine readouts of a B36!
++//
++
++#define INSTRDEFS 21
++
++int fgHUDInit( fgAIRCRAFT * /* current_aircraft */ )
++{
++ instr_item *HIptr;
++ int index;
++
++ FG_LOG( FG_COCKPIT, FG_INFO, "Initializing current aircraft HUD" );
++
++ HUD_deque.erase( HUD_deque.begin(), HUD_deque.end()); // empty the HUD deque
++
++// hud->code = 1;
++// hud->status = 0;
++
++ // For now lets just hardcode the hud here.
++ // In the future, hud information has to come from the same place
++ // aircraft information came from.
++
++// fgHUDSetTimeMode( hud, NIGHT );
++// fgHUDSetBrightness( hud, BRT_LIGHT );
++
++ index = 0;
++
++ do {
++ switch ( index ) {
++ case 0: // TBI
++ HIptr = (instr_item *) new fgTBI_instr( 270, 100, 60, 10 );
++ break;
++
++ case 1: // Artificial Horizon
++ HIptr = (instr_item *) new HudLadder( 240, 195, 120, 180 );
++ break;
++
++ case 2: // KIAS
++ HIptr = (instr_item *) new hud_card( 130,
++ 170,
++ 28,
++ 200,
++ get_speed,
++ HUDS_LEFT | HUDS_VERT,
++ 200.0, 0.0,
++ 1.0,
++ 10, 5,
++ 0,
++ 0,
++ 50.0,
++ true);
++
++ break;
++
++ case 3: // Radio Altimeter
++ HIptr = (instr_item *) new hud_card( 420,
++ 195,
++ 25,
++ 150,
++ get_agl,
++ HUDS_LEFT | HUDS_VERT,
++ 1000, 0,
++ 1.0,
++ 25, 5,
++ 0,
++ 0,
++ 200.0,
++ true);
++ break;
++
++ case 4: // GYRO COMPASS
++ HIptr = (instr_item *) new hud_card( 200,
++ 375,
++ 200,
++ 28,
++ get_heading,
++ HUDS_TOP,
++ 360, 0,
++ 1.0,
++ 5, 1,
++ 360,
++ 0,
++ 25,
++ true);
++ break;
++
++ case 5: // AMSL
++ HIptr = (instr_item *) new hud_card( 460,
++ 170,
++ 35,
++ 200,
++ get_altitude,
++ HUDS_RIGHT | HUDS_VERT,
++ 15000, -500,
++ 1.0,
++ 100, 25,
++ 0,
++ 0,
++ 250,
++ true);
++ break;
++
++ case 6:
++ HIptr = (instr_item *) new guage_instr( 250, // x
++ 350, // y
++ 100, // width
++ 20, // height
++ get_aileronval, // data source
++ HUDS_BOTTOM | HUDS_NOTEXT,
++ 100.0,
++ +1.0,
++ -1.0);
++ break;
++
++ case 7:
++ HIptr = (instr_item *) new guage_instr( 170, // x
++ 225, // y
++ 20, // width
++ 100, // height
++ get_elevatorval, // data source
++ HUDS_RIGHT | HUDS_VERT | HUDS_NOTEXT,
++ -100.0, // Scale data
++ +1.0, // Data Range
++ -1.0);
++ break;
++
++ case 8:
++ HIptr = (instr_item *) new guage_instr( 250, // x
++ 200, // y
++ 100, // width
++ 20, // height
++ get_rudderval, // data source
++ HUDS_TOP | HUDS_NOTEXT,
++ 100.0,
++ +1.0,
++ -1.0);
++ break;
++
++ case 9:
++ HIptr = (instr_item *) new guage_instr( 100, // x
++ 190,
++ 20,
++ 160, // height
++ get_throttleval, // data source
++ HUDS_VERT | HUDS_RIGHT | HUDS_NOTEXT,
++ 100.0,
++ 1.0,
++ 0.0);
++ break;
++
++ case 10: // Digital KIAS
++ HIptr = (instr_item *) new instr_label ( 110,
++ 150,
++ 40,
++ 30,
++ get_speed,
++ "%5.0f",
++ NULL,
++ " Kts",
++ 1.0,
++ HUDS_TOP,
++ RIGHT_JUST,
++ SMALL,
++ 0,
++ TRUE );
++ break;
++
++ case 11: // Digital Rate of Climb
++ HIptr = (instr_item *) new instr_label ( 110,
++ 135,
++ 40,
++ 10,
++ get_climb_rate,
++ "%5.0f",
++ " Climb",
++ NULL,
++ 1.0,
++ HUDS_TOP,
++ RIGHT_JUST,
++ SMALL,
++ 0,
++ TRUE );
++ break;
++
++ case 12: // Roll indication diagnostic
++ HIptr = (instr_item *) new instr_label ( 110,
++ 120,
++ 40,
++ 10,
++ get_roll,
++ "%5.2f",
++ " Roll",
++ " Deg",
++ 1.0,
++ HUDS_TOP,
++ RIGHT_JUST,
++ SMALL,
++ 0,
++ TRUE );
++ break;
++
++ case 13: // Angle of attack diagnostic
++ HIptr = (instr_item *) new instr_label ( 440,
++ 150,
++ 60,
++ 10,
++ get_aoa,
++ " %5.2f",
++ "AOA",
++ " Deg",
++ 1.0,
++ HUDS_TOP,
++ RIGHT_JUST,
++ SMALL,
++ 0,
++ TRUE );
++ break;
++
++ case 14:
++ HIptr = (instr_item *) new instr_label ( 440,
++ 135,
++ 60,
++ 10,
++ get_heading,
++ " %5.1f",
++ "Heading ",
++ " Deg",
++ 1.0,
++ HUDS_TOP,
++ RIGHT_JUST,
++ SMALL,
++ 0,
++ TRUE );
++ break;
++
++ case 15:
++ HIptr = (instr_item *) new instr_label ( 440,
++ 120,
++ 60,
++ 10,
++ get_sideslip,
++ "%5.2f",
++ "Sideslip ",
++ NULL,
++ 1.0,
++ HUDS_TOP,
++ RIGHT_JUST,
++ SMALL,
++ 0,
++ TRUE );
++ break;
++
++ case 16:
++ HIptr = (instr_item *) new instr_label( 440,
++ 100,
++ 60,
++ 10,
++ get_throttleval,
++ "%5.2f",
++ "Throttle ",
++ NULL,
++ 1.0,
++ HUDS_TOP,
++ RIGHT_JUST,
++ SMALL,
++ 0,
++ TRUE );
++ break;
++
++ case 17:
++ HIptr = (instr_item *) new instr_label( 440,
++ 85,
++ 60,
++ 10,
++ get_elevatorval,
++ "%5.2f",
++ "Elevator ",
++ NULL,
++ 1.0,
++ HUDS_TOP,
++ RIGHT_JUST,
++ SMALL,
++ 0,
++ TRUE );
++ break;
++
++ case 18:
++ HIptr = (instr_item *) new instr_label( 440,
++ 60,
++ 60,
++ 10,
++ get_aileronval,
++ "%5.2f",
++ "Aileron ",
++ NULL,
++ 1.0,
++ HUDS_TOP,
++ RIGHT_JUST,
++ SMALL,
++ 0,
++ TRUE );
++ break;
++
++
++ case 19:
++ HIptr = (instr_item *) new instr_label( 10,
++ 10,
++ 60,
++ 10,
++ get_frame_rate,
++ "%.0f",
++ "Frame rate = ",
++ NULL,
++ 1.0,
++ HUDS_TOP,
++ RIGHT_JUST,
++ SMALL,
++ 0,
++ TRUE );
++ break;
++
++ case 20:
++ switch( current_options.get_tris_or_culled() ) {
++ case 0:
++ HIptr = (instr_item *) new instr_label( 10,
++ 25,
++ 90,
++ 10,
++ get_vfc_tris_drawn,
++ "%.0f",
++ "Tris Rendered = ",
++ NULL,
++ 1.0,
++ HUDS_TOP,
++ RIGHT_JUST,
++ SMALL,
++ 0,
++ TRUE );
++ break;
++ case 1:
++ HIptr = (instr_item *) new instr_label( 10,
++ 25,
++ 90,
++ 10,
++ get_vfc_ratio,
++ "%.2f",
++ "VFC Ratio = ",
++ NULL,
++ 1.0,
++ HUDS_TOP,
++ RIGHT_JUST,
++ SMALL,
++ 0,
++ TRUE );
++ break;
++ }
++ break;
++
++ case 21:
++ HIptr = (instr_item *) new instr_label( 10,
++ 40,
++ 90,
++ 10,
++ get_fov,
++ "%.1f",
++ "FOV = ",
++ NULL,
++ 1.0,
++ HUDS_TOP,
++ RIGHT_JUST,
++ SMALL,
++ 0,
++ TRUE );
++ break;
++
++ default:
++ HIptr = 0;;
++ }
++ if( HIptr ) { // Anything to install?
++ HUD_deque.insert( HUD_deque.begin(), HIptr);
++ }
++ index++;
++ }
++ while( HIptr );
++
++ return 0; // For now. Later we may use this for an error code.
++}
++
++int fgHUDInit2( fgAIRCRAFT * /* current_aircraft */ )
++{
++ int index;
++
++ FG_LOG( FG_COCKPIT, FG_INFO, "Initializing current aircraft HUD" );
++
++ HUD_deque.erase( HUD_deque.begin(), HUD_deque.end());
++
++ // hud->code = 1;
++ // hud->status = 0;
++
++ // For now lets just hardcode the hud here.
++ // In the future, hud information has to come from the same place
++ // aircraft information came from.
++
++ // fgHUDSetTimeMode( hud, NIGHT );
++ // fgHUDSetBrightness( hud, BRT_LIGHT );
++
++ // index = 0;
++ index = 19;
++
++ instr_item* p;
++
++ p = new instr_label( 10, 10, 60, 10,
++ get_frame_rate,
++ "%.0f",
++ "Frame rate = ",
++ NULL,
++ 1.0,
++ HUDS_TOP,
++ RIGHT_JUST,
++ SMALL,
++ 0,
++ TRUE );
++ HUD_deque.push_front( p );
++
++ if ( current_options.get_tris_or_culled() == 0 )
++ p = new instr_label( 10, 25, 90, 10,
++ get_vfc_tris_drawn,
++ "%.0f",
++ "Tris Rendered = ",
++ NULL,
++ 1.0,
++ HUDS_TOP,
++ RIGHT_JUST,
++ SMALL,
++ 0,
++ TRUE );
++ else
++ p = new instr_label( 10, 25, 90, 10,
++ get_vfc_ratio,
++ "%.2f",
++ "VFC Ratio = ",
++ NULL,
++ 1.0,
++ HUDS_TOP,
++ RIGHT_JUST,
++ SMALL,
++ 0,
++ TRUE );
++ HUD_deque.push_front( p );
++
++ p = new instr_label( 10, 40, 90, 10,
++ get_fov,
++ "%.1f",
++ "FOV = ",
++ NULL,
++ 1.0,
++ HUDS_TOP,
++ RIGHT_JUST,
++ SMALL,
++ 0,
++ TRUE );
++ HUD_deque.push_front( p );
++
++ const int x_pos = 480;
++ p = new instr_label( x_pos, 40, 40, 30,
++ get_speed,
++ "%5.0f",
++ "Airspeed ",
++ " Kts",
++ 1.0,
++ HUDS_TOP,
++ RIGHT_JUST,
++ SMALL,
++ 0,
++ TRUE );
++ HUD_deque.push_front( p );
++
++ if ( current_options.get_units() == fgOPTIONS::FG_UNITS_FEET ) {
++ strcpy(units, " ft");
++ } else {
++ strcpy(units, " m");
++ }
++ p = new instr_label( x_pos, 25, 40, 10,
++ get_altitude,
++ "%5.0f",
++ "Altitude ",
++ units,
++ 1.0,
++ HUDS_TOP,
++ RIGHT_JUST,
++ SMALL,
++ 0,
++ TRUE );
++ HUD_deque.push_front( p );
++
++ p = new instr_label( x_pos, 10, 60, 10,
++ get_heading,
++ "%5.1f",
++ "Heading ",
++ " Deg",
++ 1.0,
++ HUDS_TOP,
++ RIGHT_JUST,
++ SMALL,
++ 0,
++ TRUE );
++ HUD_deque.push_front( p );
++
++ return 0; // For now. Later we may use this for an error code.
++}
++
++int global_day_night_switch = DAY;
++
++void HUD_brightkey( bool incr_bright )
++{
++instr_item *pHUDInstr = HUD_deque[0];
++int brightness = pHUDInstr->get_brightness();
++
++ if( current_options.get_hud_status() ) {
++ if( incr_bright ) {
++ switch (brightness) {
++ case BRT_LIGHT:
++ current_options.set_hud_status(0);
++ break;
++
++ case BRT_MEDIUM:
++ brightness = BRT_LIGHT;
++ break;
++
++ case BRT_DARK:
++ brightness = BRT_MEDIUM;
++ break;
++
++ case BRT_BLACK:
++ brightness = BRT_DARK;
++ break;
++
++ default:
++ brightness = BRT_BLACK;
++ }
++ }
++ else {
++ switch (brightness) {
++ case BRT_LIGHT:
++ brightness = BRT_MEDIUM;
++ break;
++
++ case BRT_MEDIUM:
++ brightness = BRT_DARK;
++ break;
++
++ case BRT_DARK:
++ brightness = BRT_BLACK;
++ break;
++
++ case BRT_BLACK:
++ default:
++ current_options.set_hud_status(0);
++ }
++ }
++ }
++ else {
++ current_options.set_hud_status(1);
++ if( incr_bright ) {
++ if( DAY == global_day_night_switch ) {
++ brightness = BRT_BLACK;
++ }
++ else {
++ brightness = BRT_DARK;
++ global_day_night_switch = DAY;
++ }
++ }
++ else {
++ if( NIGHT == global_day_night_switch ) {
++ brightness = BRT_DARK;
++ }
++ else {
++ brightness = BRT_MEDIUM;
++ global_day_night_switch = NIGHT;
++ }
++ }
++ }
++ pHUDInstr->SetBrightness( brightness );
++}
++
++// fgUpdateHUD
++//
++// Performs a once around the list of calls to instruments installed in
++// the HUD object with requests for redraw. Kinda. It will when this is
++// all C++.
++//
++void fgUpdateHUD( void ) {
++ int i;
++ int brightness;
++// int day_night_sw = current_aircraft.controls->day_night_switch;
++ int day_night_sw = global_day_night_switch;
++ int hud_displays = HUD_deque.size();
++ instr_item *pHUDInstr;
++
++ if( !hud_displays ) { // Trust everyone, but ALWAYS cut the cards!
++ return;
++ }
++
++ pHUDInstr = HUD_deque[0];
++ brightness = pHUDInstr->get_brightness();
++// brightness = HUD_deque.at(0)->get_brightness();
++
++ glMatrixMode(GL_PROJECTION);
++ glPushMatrix();
++
++ glLoadIdentity();
++ gluOrtho2D(0, 640, 0, 480);
++ glMatrixMode(GL_MODELVIEW);
++ glPushMatrix();
++ glLoadIdentity();
++
++ glColor3f(1.0, 1.0, 1.0);
++ glIndexi(7);
++
++ glDisable(GL_DEPTH_TEST);
++ glDisable(GL_LIGHTING);
++
++ glLineWidth(1);
++
++ HudIterator current = HUD_deque.begin();
++ HudIterator last = HUD_deque.end();
++
++ for ( ; current != last; ++current ) {
++ pHUDInstr = *current;
++
++ // for( i = hud_displays; i; --i) { // Draw everything
++ // if( HUD_deque.at(i)->enabled()) {
++ // pHUDInstr = HUD_deque[i - 1];
++ if( pHUDInstr->enabled()) {
++ // We should to respond to a dial instead
++ // or as well to the of time of day. Of
++ // course, we have no dial!
++ if( day_night_sw == DAY) {
++ switch (brightness) {
++ case BRT_LIGHT:
++ glColor3f (0.1, 0.9, 0.1);
++ break;
++
++ case BRT_MEDIUM:
++ glColor3f (0.1, 0.7, 0.0);
++ break;
++
++ case BRT_DARK:
++ glColor3f (0.0, 0.5, 0.0);
++ break;
++
++ case BRT_BLACK:
++ glColor3f( 0.0, 0.0, 0.0);
++ break;
++
++ default:;
++ }
++ }
++ else {
++ if( day_night_sw == NIGHT) {
++ switch (brightness) {
++ case BRT_LIGHT:
++ glColor3f (0.9, 0.1, 0.1);
++ break;
++
++ case BRT_MEDIUM:
++ glColor3f (0.7, 0.0, 0.1);
++ break;
++
++ case BRT_DARK:
++ default:
++ glColor3f (0.5, 0.0, 0.0);
++ }
++ }
++ else { // Just in case default
++ glColor3f (0.1, 0.9, 0.1);
++ }
++ }
++ // fgPrintf( FG_COCKPIT, FG_DEBUG, "HUD Code %d Status %d\n",
++ // hud->code, hud->status );
++ pHUDInstr->draw();
++// HUD_deque.at(i)->draw(); // Responsible for broken or fixed variants.
++ // No broken displays honored just now.
++ }
++ }
++
++ glEnable(GL_DEPTH_TEST);
++ glEnable(GL_LIGHTING);
++ glMatrixMode(GL_PROJECTION);
++ glPopMatrix();
++ glMatrixMode(GL_MODELVIEW);
++ glPopMatrix();
++}
++
++// $Log$
++// Revision 1.32 1999/03/02 01:02:37 curt
++// Tweaks for building with native SGI compilers.
++//
++// Revision 1.31 1999/02/02 20:13:31 curt
++// MSVC++ portability changes by Bernie Bright:
++//
++// Lib/Serial/serial.[ch]xx: Initial Windows support - incomplete.
++// Simulator/Astro/stars.cxx: typo? included <stdio> instead of <cstdio>
++// Simulator/Cockpit/hud.cxx: Added Standard headers
++// Simulator/Cockpit/panel.cxx: Redefinition of default parameter
++// Simulator/Flight/flight.cxx: Replaced cout with FG_LOG. Deleted <stdio.h>
++// Simulator/Main/fg_init.cxx:
++// Simulator/Main/GLUTmain.cxx:
++// Simulator/Main/options.hxx: Shuffled <fg_serial.hxx> dependency
++// Simulator/Objects/material.hxx:
++// Simulator/Time/timestamp.hxx: VC++ friend kludge
++// Simulator/Scenery/tile.[ch]xx: Fixed using std::X declarations
++// Simulator/Main/views.hxx: Added a constant
++//
++// Revision 1.30 1999/01/27 04:47:52 curt
++// Make lower end of altitude = -500 so the altimeter is guaged below zero (such
++// as in death valley.)
++//
++// Revision 1.29 1998/12/18 23:35:10 curt
++// Converted to a simpler frame rate counting method.
++//
++// Revision 1.28 1998/11/23 21:48:59 curt
++// Borland portability tweaks.
++//
++// Revision 1.27 1998/11/06 21:17:47 curt
++// Converted to new logstream debugging facility. This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.26 1998/11/03 12:33:11 curt
++// Display ft or m in mini-hud next to altitude.
++//
++// Revision 1.25 1998/10/17 01:33:57 curt
++// C++ ifying ...
++//
++// Revision 1.24 1998/10/16 23:27:25 curt
++// C++-ifying.
++//
++// Revision 1.23 1998/10/16 00:53:00 curt
++// Mods to display a bit more info when mini-hud is active.
++//
++// Revision 1.22 1998/09/29 14:56:31 curt
++// c++-ified comments.
++//
++// Revision 1.21 1998/09/29 02:01:07 curt
++// Added a "rate of climb" indicator.
++//
++// Revision 1.20 1998/08/24 20:05:16 curt
++// Added a second minimalistic HUD.
++// Added code to display the number of triangles rendered.
++//
++// Revision 1.19 1998/07/30 23:44:05 curt
++// Tweaks for sgi building.
++//
++// Revision 1.18 1998/07/20 12:47:55 curt
++// Replace the hud rendering for loop (which linearly searches the the hud
++// list to find the entry with the proper position) with a simple linear
++// traversal using an "iterator."
++//
++// Revision 1.17 1998/07/13 21:28:02 curt
++// Converted the aoa scale to a radio altimeter.
++//
++// Revision 1.16 1998/07/13 21:00:47 curt
++// Integrated Charlies latest HUD updates.
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.15 1998/07/08 14:41:08 curt
++// Renamed polar3d.h to polar3d.hxx
++//
++// Revision 1.14 1998/07/06 21:31:20 curt
++// Removed an extraneous ^M.
++//
++// Revision 1.13 1998/07/03 13:16:28 curt
++// Added Charlie Hotchkiss's HUD updates and improvementes.
++//
++// Revision 1.11 1998/06/05 18:17:10 curt
++// Added the declaration of memmove needed by the stl which apparently
++// solaris only defines for cc compilations and not for c++ (__STDC__)
++//
++// Revision 1.10 1998/05/17 16:58:12 curt
++// Added a View Frustum Culling ratio display to the hud.
++//
++// Revision 1.9 1998/05/16 13:04:14 curt
++// New updates from Charlie Hotchkiss.
++//
++// Revision 1.8 1998/05/13 18:27:54 curt
++// Added an fov to hud display.
++//
++// Revision 1.7 1998/05/11 18:13:11 curt
++// Complete C++ rewrite of all cockpit code by Charlie Hotchkiss.
++//
++// Revision 1.22 1998/04/18 04:14:02 curt
++// Moved fg_debug.c to it's own library.
++//
++// Revision 1.21 1998/04/03 21:55:28 curt
++// Converting to Gnu autoconf system.
++// Tweaks to hud.c
++//
++// Revision 1.20 1998/03/09 22:48:40 curt
++// Minor "formatting" tweaks.
++//
++// Revision 1.19 1998/02/23 20:18:28 curt
++// Incorporated Michele America's hud changes.
++//
++// Revision 1.18 1998/02/21 14:53:10 curt
++// Added Charlie's HUD changes.
++//
++// Revision 1.17 1998/02/20 00:16:21 curt
++// Thursday's tweaks.
++//
++// Revision 1.16 1998/02/19 13:05:49 curt
++// Incorporated some HUD tweaks from Michelle America.
++// Tweaked the sky's sunset/rise colors.
++// Other misc. tweaks.
++//
++// Revision 1.15 1998/02/16 13:38:39 curt
++// Integrated changes from Charlie Hotchkiss.
++//
++// Revision 1.14 1998/02/12 21:59:41 curt
++// Incorporated code changes contributed by Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.12 1998/02/09 15:07:48 curt
++// Minor tweaks.
++//
++// Revision 1.11 1998/02/07 15:29:34 curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.10 1998/02/03 23:20:14 curt
++// Lots of little tweaks to fix various consistency problems discovered by
++// Solaris' CC. Fixed a bug in fg_debug.c with how the fgPrintf() wrapper
++// passed arguments along to the real printf(). Also incorporated HUD changes
++// by Michele America.
++//
++// Revision 1.9 1998/01/31 00:43:04 curt
++// Added MetroWorks patches from Carmen Volpe.
++//
++// Revision 1.8 1998/01/27 00:47:51 curt
++// Incorporated Paul Bleisch's <bleisch@chromatic.com> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.7 1998/01/19 18:40:20 curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.6 1997/12/15 23:54:34 curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.5 1997/12/10 22:37:39 curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.4 1997/09/23 00:29:32 curt
++// Tweaks to get things to compile with gcc-win32.
++//
++// Revision 1.3 1997/09/05 14:17:26 curt
++// More tweaking with stars.
++//
++// Revision 1.2 1997/09/04 02:17:30 curt
++// Shufflin' stuff.
++//
++// Revision 1.1 1997/08/29 18:03:22 curt
++// Initial revision.
++//
--- /dev/null
--- /dev/null
++// hud.hxx -- hud defines and prototypes (initial draft)
++//
++// Written by Michele America, started September 1997.
++//
++// Copyright (C) 1997 Michele F. America - nomimarketing@mail.telepac.pt
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#ifndef _HUD_HXX
++#define _HUD_HXX
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++
++#include <GL/glut.h>
++#include <stdlib.h>
++#include <string.h>
++
++#ifdef HAVE_VALUES_H
++# include <values.h> // for MAXINT
++#endif
++
++#include <deque> // STL double ended queue
++
++#include <fg_typedefs.h>
++#include <fg_constants.h>
++#include <Aircraft/aircraft.hxx>
++#include <FDM/flight.hxx>
++#include <Controls/controls.hxx>
++
++FG_USING_STD(deque);
++
++#ifndef WIN32
++ typedef struct {
++ int x, y;
++ } POINT;
++
++ typedef struct {
++ int top, bottom, left, right;
++ } RECT;
++#endif
++
++// View mode definitions
++
++enum VIEW_MODES{ HUD_VIEW, PANEL_VIEW, CHASE_VIEW, TOWER_VIEW };
++
++// DAY, NIGHT and brightness levels need to be visible where dialogs and
++// controls can be used to set intensity and appropriate color. This will
++// be moved.
++// Hud general constants
++#define DAY 1
++#define NIGHT 2
++#define BRT_BLACK 3
++#define BRT_DARK 4
++#define BRT_MEDIUM 5
++#define BRT_LIGHT 6
++#define SIZE_SMALL 7
++#define SIZE_LARGE 8
++
++// Label constants
++#define SMALL 1
++#define LARGE 2
++
++#define BLINK 3
++#define NOBLINK 4
++
++enum fgLabelJust{ LEFT_JUST, CENTER_JUST, RIGHT_JUST } ;
++
++// Ladder constants
++#define NONE 1
++#define UPPER_LEFT 2
++#define UPPER_CENTER 3
++#define UPPER_RIGHT 4
++#define CENTER_RIGHT 5
++#define LOWER_RIGHT 6
++#define LOWER_CENTER 7
++#define LOWER_LEFT 8
++#define CENTER_LEFT 9
++#define SOLID_LINES 10
++#define DASHED_LINES 11
++#define DASHED_NEG_LINES 12
++
++
++#define HORIZON_FIXED 1
++#define HORIZON_MOVING 2
++#define LABEL_COUNTER 1
++#define LABEL_WARNING 2
++
++#define HUDS_AUTOTICKS 0x0001
++#define HUDS_VERT 0x0002
++#define HUDS_HORZ 0x0000
++#define HUDS_TOP 0x0004
++#define HUDS_BOTTOM 0x0008
++#define HUDS_LEFT HUDS_TOP
++#define HUDS_RIGHT HUDS_BOTTOM
++#define HUDS_BOTH (HUDS_LEFT | HUDS_RIGHT)
++#define HUDS_NOTICKS 0x0010
++#define HUDS_ARITHTIC 0x0020
++#define HUDS_DECITICS 0x0040
++#define HUDS_NOTEXT 0x0080
++
++// Ladder orientaion
++// #define HUD_VERTICAL 1
++// #define HUD_HORIZONTAL 2
++// #define HUD_FREEFLOAT 3
++
++// Ladder orientation modes
++// #define HUD_LEFT 1
++// #define HUD_RIGHT 2
++// #define HUD_TOP 1
++// #define HUD_BOTTOM 2
++// #define HUD_V_LEFT 1
++// #define HUD_V_RIGHT 2
++// #define HUD_H_TOP 1
++// #define HUD_H_BOTTOM 2
++
++
++// Ladder sub-types
++// #define HUD_LIM 1
++// #define HUD_NOLIM 2
++// #define HUD_CIRC 3
++
++// #define HUD_INSTR_LADDER 1
++// #define HUD_INSTR_CLADDER 2
++// #define HUD_INSTR_HORIZON 3
++// #define HUD_INSTR_LABEL 4
++
++extern double get_throttleval ( void );
++extern double get_aileronval ( void );
++extern double get_elevatorval ( void );
++extern double get_elev_trimval( void );
++extern double get_rudderval ( void );
++extern double get_speed ( void );
++extern double get_aoa ( void );
++extern double get_roll ( void );
++extern double get_pitch ( void );
++extern double get_heading ( void );
++extern double get_altitude ( void );
++extern double get_agl ( void );
++extern double get_sideslip ( void );
++extern double get_frame_rate ( void );
++extern double get_latitude ( void );
++extern double get_lat_min ( void );
++extern double get_longitude ( void );
++extern double get_long_min ( void );
++extern double get_fov ( void );
++extern double get_vfc_ratio ( void );
++extern double get_vfc_tris_drawn ( void );
++extern double get_climb_rate ( void );
++
++enum hudinstype{ HUDno_instr,
++ HUDscale,
++ HUDlabel,
++ HUDladder,
++ HUDcirc_ladder,
++ HUDhorizon,
++ HUDguage,
++ HUDdual_inst,
++ HUDmoving_scale,
++ HUDtbi
++ };
++
++typedef struct gltagRGBTRIPLE { // rgbt
++ GLfloat Blue;
++ GLfloat Green;
++ GLfloat Red;
++} glRGBTRIPLE;
++
++class instr_item { // An Abstract Base Class (ABC)
++ private:
++ static UINT instances; // More than 64K instruments? Nah!
++ static int brightness;
++ static glRGBTRIPLE color;
++
++ UINT handle;
++ RECT scrn_pos; // Framing - affects scale dimensions
++ // and orientation. Vert vs Horz, etc.
++ DBLFNPTR load_value_fn;
++ double disp_factor; // Multiply by to get numbers shown on scale.
++ UINT opts;
++ bool is_enabled;
++ bool broken;
++ UINT scr_span; // Working values for draw;
++ POINT mid_span; //
++
++ public:
++ instr_item( int x,
++ int y,
++ UINT height,
++ UINT width,
++ DBLFNPTR data_source,
++ double data_scaling,
++ UINT options,
++ bool working = true);
++
++ instr_item( const instr_item & image );
++
++ instr_item & operator = ( const instr_item & rhs );
++ virtual ~instr_item ();
++
++ int get_brightness ( void ) { return brightness;}
++ RECT get_location ( void ) { return scrn_pos; }
++ bool is_broken ( void ) { return broken; }
++ bool enabled ( void ) { return is_enabled;}
++ bool data_available ( void ) { return !!load_value_fn; }
++ double get_value ( void ) { return load_value_fn(); }
++ double data_scaling ( void ) { return disp_factor; }
++ UINT get_span ( void ) { return scr_span; }
++ POINT get_centroid ( void ) { return mid_span; }
++ UINT get_options ( void ) { return opts; }
++
++ virtual void display_enable( bool working ) { is_enabled = !! working;}
++
++
++ virtual void update( void );
++ virtual void break_display ( bool bad );
++ virtual void SetBrightness( int illumination_level ); // fgHUDSetBright...
++ void SetPosition ( int x, int y, UINT width, UINT height );
++ UINT get_Handle( void );
++ virtual void draw( void ) = 0; // Required method in derived classes
++};
++
++typedef deque< instr_item * > HudContainerType;
++typedef HudContainerType::iterator HudIterator;
++
++typedef instr_item *HIptr;
++extern HudContainerType HUD_deque;
++
++// instr_item This class has no other purpose than to maintain
++// a linked list of instrument and derived class
++// object pointers.
++
++
++class instr_label : public instr_item {
++ private:
++ const char *pformat;
++ const char *pre_str;
++ const char *post_str;
++ fgLabelJust justify;
++ int fontSize;
++ int blink;
++
++ public:
++ instr_label( int x,
++ int y,
++ UINT width,
++ UINT height,
++ DBLFNPTR data_source,
++ const char *label_format,
++ const char *pre_label_string = 0,
++ const char *post_label_string = 0,
++ double scale_data = 1.0,
++ UINT options = HUDS_TOP,
++ fgLabelJust justification = CENTER_JUST,
++ int font_size = SMALL,
++ int blinking = NOBLINK,
++ bool working = true);
++
++ ~instr_label();
++
++ instr_label( const instr_label & image);
++ instr_label & operator = (const instr_label & rhs );
++ virtual void draw( void ); // Required method in base class
++};
++
++typedef instr_label * pInstlabel;
++
++//
++// instr_scale This class is an abstract base class for both moving
++// scale and moving needle (fixed scale) indicators. It
++// does not draw itself, but is not instanciable.
++//
++
++class instr_scale : public instr_item {
++ private:
++ double range_shown; // Width Units.
++ double Maximum_value; // ceiling.
++ double Minimum_value; // Representation floor.
++ double scale_factor; // factor => screen units/range values.
++ UINT Maj_div; // major division marker units
++ UINT Min_div; // minor division marker units
++ UINT Modulo; // Roll over point
++ int signif_digits; // digits to show to the right.
++
++ public:
++ instr_scale( int x,
++ int y,
++ UINT width,
++ UINT height,
++ DBLFNPTR load_fn,
++ UINT options,
++ double show_range,
++ double max_value = 100.0,
++ double min_value = 0.0,
++ double disp_scaling = 1.0,
++ UINT major_divs = 10,
++ UINT minor_divs = 5,
++ UINT rollover = 0,
++ int dp_showing = 2,
++ bool working = true);
++
++ virtual ~instr_scale();
++ instr_scale( const instr_scale & image);
++ instr_scale & operator = (const instr_scale & rhs);
++
++ virtual void draw ( void ) {}; // No-op here. Defined in derived classes.
++ UINT div_min ( void ) { return Min_div;}
++ UINT div_max ( void ) { return Maj_div;}
++ double min_val ( void ) { return Minimum_value;}
++ double max_val ( void ) { return Maximum_value;}
++ UINT modulo ( void ) { return Modulo; }
++ double factor ( void ) { return scale_factor;}
++ double range_to_show( void ) { return range_shown;}
++};
++
++// hud_card_ This class displays the indicated quantity on
++// a scale that moves past the pointer. It may be
++// horizontal or vertical, read above(left) or below(right) of the base
++// line.
++
++class hud_card : public instr_scale {
++ private:
++ double val_span;
++ double half_width_units;
++
++ public:
++ hud_card( int x,
++ int y,
++ UINT width,
++ UINT height,
++ DBLFNPTR load_fn,
++ UINT options,
++ double maxValue = 100.0,
++ double minValue = 0.0,
++ double disp_scaling = 1.0,
++ UINT major_divs = 10,
++ UINT minor_divs = 5,
++ UINT modulator = 100,
++ int dp_showing = 2,
++ double value_span = 100.0,
++ bool working = true);
++
++ ~hud_card();
++ hud_card( const hud_card & image);
++ hud_card & operator = (const hud_card & rhs );
++// virtual void display_enable( bool setting );
++ virtual void draw( void ); // Required method in base class
++};
++
++typedef hud_card * pCardScale;
++
++class guage_instr : public instr_scale {
++ private:
++
++ public:
++ guage_instr( int x,
++ int y,
++ UINT width,
++ UINT height,
++ DBLFNPTR load_fn,
++ UINT options,
++ double disp_scaling = 1.0,
++ double maxValue = 100,
++ double minValue = 0,
++ UINT major_divs = 50,
++ UINT minor_divs = 0,
++ int dp_showing = 2,
++ UINT modulus = 0,
++ bool working = true);
++
++ ~guage_instr();
++ guage_instr( const guage_instr & image);
++ guage_instr & operator = (const guage_instr & rhs );
++ virtual void draw( void ); // Required method in base class
++};
++
++typedef guage_instr * pGuageInst;
++//
++// dual_instr_item This class was created to form the base class
++// for both panel and HUD Turn Bank Indicators.
++
++class dual_instr_item : public instr_item {
++ private:
++ DBLFNPTR alt_data_source;
++
++ public:
++ dual_instr_item ( int x,
++ int y,
++ UINT width,
++ UINT height,
++ DBLFNPTR chn1_source,
++ DBLFNPTR chn2_source,
++ bool working = true,
++ UINT options = HUDS_TOP);
++
++ virtual ~dual_instr_item() {};
++ dual_instr_item( const dual_instr_item & image);
++ dual_instr_item & operator = (const dual_instr_item & rhs );
++
++ double current_ch1( void ) { return alt_data_source();}
++ double current_ch2( void ) { return get_value();}
++ virtual void draw ( void ) { }
++};
++
++class fgTBI_instr : public dual_instr_item {
++ private:
++ UINT BankLimit;
++ UINT SlewLimit;
++ UINT scr_hole;
++
++ public:
++ fgTBI_instr( int x,
++ int y,
++ UINT width,
++ UINT height,
++ DBLFNPTR chn1_source = get_roll,
++ DBLFNPTR chn2_source = get_sideslip,
++ double maxBankAngle = 45.0,
++ double maxSlipAngle = 5.0,
++ UINT gap_width = 5.0,
++ bool working = true);
++
++ fgTBI_instr( const fgTBI_instr & image);
++ fgTBI_instr & operator = (const fgTBI_instr & rhs );
++
++ ~fgTBI_instr();
++
++ UINT bank_limit( void ) { return BankLimit;}
++ UINT slew_limit( void ) { return SlewLimit;}
++
++ virtual void draw( void ); // Required method in base class
++};
++
++typedef fgTBI_instr * pTBI;
++
++class HudLadder : public dual_instr_item {
++ private:
++ UINT width_units;
++ int div_units;
++ UINT minor_div;
++ UINT label_pos;
++ UINT scr_hole;
++ double vmax;
++ double vmin;
++ double factor;
++
++ public:
++ HudLadder( int x,
++ int y,
++ UINT width,
++ UINT height,
++ DBLFNPTR ptch_source = get_roll,
++ DBLFNPTR roll_source = get_pitch,
++ double span_units = 45.0,
++ double division_units = 10.0,
++ double minor_division = 0.0,
++ UINT screen_hole = 70,
++ UINT lbl_pos = 0,
++ bool working = true );
++
++ ~HudLadder();
++
++ HudLadder( const HudLadder & image );
++ HudLadder & operator = ( const HudLadder & rhs );
++ virtual void draw( void );
++};
++
++
++//using namespace std;
++//deque <instr_item> * Hdeque_ptr;
++
++extern void HUD_brightkey( bool incr_bright );
++extern int fgHUDInit( fgAIRCRAFT * /* current_aircraft */ );
++extern int fgHUDInit2( fgAIRCRAFT * /* current_aircraft */ );
++extern void fgUpdateHUD( void );
++
++extern void drawOneLine ( UINT x1, UINT y1, UINT x2, UINT y2);
++extern void drawOneLine ( RECT &rect);
++extern void textString ( int x,
++ int y,
++ char *msg,
++ void *font = GLUT_BITMAP_8_BY_13);
++extern void strokeString( int x,
++ int y,
++ char *msg,
++ void *font = GLUT_STROKE_ROMAN,
++ float theta = 0);
++/*
++bool AddHUDInstrument( instr_item *pBlackBox );
++void DrawHUD ( void );
++bool DamageInstrument( INSTR_HANDLE unit );
++bool RepairInstrument( INSTR_HANDLE unit );
++
++
++void fgUpdateHUD ( Hptr hud );
++void fgUpdateHUD2( Hptr hud ); // Future use?
++void fgHUDSetTimeMode( Hptr hud, int time_of_day );
++*/
++
++#endif // _HUD_H
++
++// $Log$
++// Revision 1.19 1999/03/02 01:02:38 curt
++// Tweaks for building with native SGI compilers.
++//
++// Revision 1.18 1999/02/26 22:08:45 curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.17 1999/02/01 21:33:28 curt
++// Renamed FlightGear/Simulator/Flight to FlightGear/Simulator/FDM since
++// Jon accepted my offer to do this and thought it was a good idea.
++//
++// Revision 1.16 1998/10/17 01:33:59 curt
++// C++ ifying ...
++//
++// Revision 1.15 1998/10/16 23:27:27 curt
++// C++-ifying.
++//
++// Revision 1.14 1998/09/29 14:56:33 curt
++// c++-ified comments.
++//
++// Revision 1.13 1998/09/29 02:01:09 curt
++// Added a "rate of climb" indicator.
++//
++// Revision 1.12 1998/08/24 20:05:17 curt
++// Added a second minimalistic HUD.
++// Added code to display the number of triangles rendered.
++//
++// Revision 1.11 1998/07/24 21:36:55 curt
++// Ran dos2unix to get rid of extraneous ^M's. Tweaked parameter in
++// ImageGetRawData() to match usage.
++//
++// Revision 1.10 1998/07/13 21:28:02 curt
++// Converted the aoa scale to a radio altimeter.
++//
++// Revision 1.9 1998/07/13 21:00:48 curt
++// Integrated Charlies latest HUD updates.
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.8 1998/07/03 13:16:29 curt
++// Added Charlie Hotchkiss's HUD updates and improvementes.
++//
++// Revision 1.6 1998/06/03 00:43:28 curt
++// No .h when including stl stuff.
++//
++// Revision 1.5 1998/05/17 16:58:13 curt
++// Added a View Frustum Culling ratio display to the hud.
++//
++// Revision 1.4 1998/05/16 13:04:15 curt
++// New updates from Charlie Hotchkiss.
++//
++// Revision 1.3 1998/05/13 18:27:55 curt
++// Added an fov to hud display.
++//
++// Revision 1.2 1998/05/11 18:13:12 curt
++// Complete C++ rewrite of all cockpit code by Charlie Hotchkiss.
++//
++// Revision 1.15 1998/02/23 19:07:57 curt
++// Incorporated Durk's Astro/ tweaks. Includes unifying the sun position
++// calculation code between sun display, and other FG sections that use this
++// for things like lighting.
++//
++// Revision 1.14 1998/02/21 14:53:14 curt
++// Added Charlie's HUD changes.
++//
++// Revision 1.13 1998/02/20 00:16:22 curt
++// Thursday's tweaks.
++//
++// Revision 1.12 1998/02/19 13:05:52 curt
++// Incorporated some HUD tweaks from Michelle America.
++// Tweaked the sky's sunset/rise colors.
++// Other misc. tweaks.
++//
++// Revision 1.11 1998/02/16 13:38:42 curt
++// Integrated changes from Charlie Hotchkiss.
++//
++// Revision 1.11 1998/02/16 13:38:42 curt
++// Integrated changes from Charlie Hotchkiss.
++//
++// Revision 1.10 1998/02/12 21:59:42 curt
++// Incorporated code changes contributed by Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.8 1998/02/07 15:29:35 curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.7 1998/02/03 23:20:15 curt
++// Lots of little tweaks to fix various consistency problems discovered by
++// Solaris' CC. Fixed a bug in fg_debug.c with how the fgPrintf() wrapper
++// passed arguments along to the real printf(). Also incorporated HUD changes
++// by Michele America.
++//
++// Revision 1.6 1998/01/22 02:59:30 curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.5 1998/01/19 19:27:01 curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.4 1998/01/19 18:40:21 curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.3 1997/12/30 16:36:41 curt
++// Merged in Durk's changes ...
++//
++// Revision 1.2 1997/12/10 22:37:40 curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.1 1997/08/29 18:03:22 curt
++// Initial revision.
++//
--- /dev/null
--- /dev/null
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++#include <stdlib.h>
++#include <string.h>
++#include <Aircraft/aircraft.hxx>
++#include <Include/fg_constants.h>
++#include <Math/fg_random.h>
++#include <Math/mat3.h>
++#include <Math/polar3d.hxx>
++#include <Scenery/scenery.hxx>
++#include <Time/fg_timer.hxx>
++
++
++#include "hud.hxx"
++//========== Top of hud_card class member definitions =============
++
++hud_card ::
++hud_card( int x,
++ int y,
++ UINT width,
++ UINT height,
++ DBLFNPTR data_source,
++ UINT options,
++ double max_value,
++ double min_value,
++ double disp_scaling,
++ UINT major_divs,
++ UINT minor_divs,
++ UINT modulus,
++ int dp_showing,
++ double value_span,
++ bool working) :
++ instr_scale( x,y,width,height,
++ data_source, options,
++ value_span,
++ max_value, min_value, disp_scaling,
++ major_divs, minor_divs, modulus,
++ working),
++ val_span ( value_span)
++{
++ half_width_units = range_to_show() / 2.0;
++}
++
++hud_card ::
++~hud_card() { }
++
++hud_card ::
++hud_card( const hud_card & image):
++ instr_scale( (const instr_scale & ) image),
++ val_span( image.val_span),
++ half_width_units (image.half_width_units)
++{
++}
++
++hud_card & hud_card ::
++operator = (const hud_card & rhs )
++{
++ if( !( this == &rhs)){
++ instr_scale::operator = (rhs);
++ val_span = rhs.val_span;
++ half_width_units = rhs.half_width_units;
++ }
++ return *this;
++}
++
++void hud_card ::
++draw( void ) // (HUD_scale * pscale )
++{
++ double vmin, vmax;
++ int marker_xs;
++ int marker_xe;
++ int marker_ys;
++ int marker_ye;
++ /* register */ int i;
++ char TextScale[80];
++ bool condition;
++ int disp_val = 0;
++ POINT mid_scr = get_centroid();
++ double cur_value = get_value();
++ RECT scrn_rect = get_location();
++ UINT options = get_options();
++
++ vmin = cur_value - half_width_units; // width units == needle travel
++ vmax = cur_value + half_width_units; // or picture unit span.
++ // Draw the basic markings for the scale...
++
++ if( options & HUDS_VERT ) { // Vertical scale
++ drawOneLine( scrn_rect.left, // Bottom tick bar
++ scrn_rect.top,
++ scrn_rect.left + scrn_rect.right,
++ scrn_rect.top);
++
++ drawOneLine( scrn_rect.left, // Top tick bar
++ scrn_rect.top + scrn_rect.bottom,
++ scrn_rect.left + scrn_rect.right,
++ scrn_rect.top + scrn_rect.bottom );
++
++ marker_xs = scrn_rect.left;
++ marker_xe = scrn_rect.left + scrn_rect.right;
++
++ // We do not use else in the following so that combining the two
++ // options produces a "caged" display with double carrots. The
++ // same is done for horizontal card indicators.
++
++ if( options & HUDS_LEFT ) { // Calculate x marker offset
++ drawOneLine( scrn_rect.left + scrn_rect.right,
++ scrn_rect.top,
++ scrn_rect.left + scrn_rect.right,
++ scrn_rect.top + scrn_rect.bottom); // Cap right side
++
++ marker_xs = marker_xe - scrn_rect.right / 3; // Adjust tick xs
++ // Indicator carrot
++ drawOneLine( marker_xs, mid_scr.y,
++ marker_xe, mid_scr.y + scrn_rect.right / 6);
++ drawOneLine( marker_xs, mid_scr.y,
++ marker_xe, mid_scr.y - scrn_rect.right / 6);
++
++ }
++ if( options & HUDS_RIGHT ) { // We'll default this for now.
++ drawOneLine( scrn_rect.left,
++ scrn_rect.top,
++ scrn_rect.left,
++ scrn_rect.top + scrn_rect.bottom); // Cap left side
++
++ marker_xe = scrn_rect.left + scrn_rect.right / 3; // Adjust tick xe
++ // Indicator carrot
++ drawOneLine( scrn_rect.left, mid_scr.y + scrn_rect.right / 6,
++ marker_xe, mid_scr.y );
++ drawOneLine( scrn_rect.left, mid_scr.y - scrn_rect.right / 6,
++ marker_xe, mid_scr.y);
++ }
++
++ // At this point marker x_start and x_end values are transposed.
++ // To keep this from confusing things they are now interchanged.
++ if(( options & HUDS_BOTH) == HUDS_BOTH) {
++ marker_ye = marker_xs;
++ marker_xs = marker_xe;
++ marker_xe = marker_ye;
++ }
++
++ // Work through from bottom to top of scale. Calculating where to put
++ // minor and major ticks.
++
++ for( i = (int)vmin; i <= (int)vmax; i++ ) {
++ condition = true;
++ if( !modulo()) {
++ if( i < min_val()) {
++ condition = false;
++ }
++ }
++
++ if( condition ) { // Show a tick if necessary
++ // Calculate the location of this tick
++ marker_ys = scrn_rect.top + (int)((i - vmin) * factor() + .5);
++
++ // Block calculation artifact from drawing ticks below min coordinate.
++ // Calculation here accounts for text height.
++
++ if(( marker_ys < (scrn_rect.top + 4)) |
++ ( marker_ys > (scrn_rect.top + scrn_rect.bottom - 4))) {
++ // Magic numbers!!!
++ continue;
++ }
++ if( div_min()) {
++ if( (i%div_min()) == 0) {
++ if((( marker_ys - 5) > scrn_rect.top ) &&
++ (( marker_ys + 5) < (scrn_rect.top + scrn_rect.bottom))){
++ if( (options & HUDS_BOTH) == HUDS_BOTH ) {
++ drawOneLine( scrn_rect.left, marker_ys,
++ marker_xs, marker_ys );
++ drawOneLine( marker_xe, marker_ys,
++ scrn_rect.left + scrn_rect.right, marker_ys );
++ }
++ else {
++ if( options & HUDS_LEFT ) {
++ drawOneLine( marker_xs + 4, marker_ys,
++ marker_xe, marker_ys );
++ }
++ else {
++ drawOneLine( marker_xs, marker_ys,
++ marker_xe - 4, marker_ys );
++ }
++ }
++ }
++ }
++ }
++ if( div_max()) {
++ if( !(i%(int)div_max())){
++ if(modulo()) {
++ if( disp_val < 0) {
++ disp_val += modulo();
++ }
++ else {
++ disp_val = i % modulo();
++ }
++ }
++ else {
++ disp_val = i;
++ }
++ sprintf( TextScale, "%d", (int)(disp_val * data_scaling() +.5));
++ if(( (marker_ys - 8 ) > scrn_rect.top ) &&
++ ( (marker_ys + 8) < (scrn_rect.top + scrn_rect.bottom))){
++ if( (options & HUDS_BOTH) == HUDS_BOTH) {
++ drawOneLine( scrn_rect.left, marker_ys,
++ marker_xs, marker_ys);
++ drawOneLine( marker_xs, marker_ys,
++ scrn_rect.left + scrn_rect.right,
++ marker_ys);
++ if( !(options & HUDS_NOTEXT)) {
++ textString ( marker_xs + 2, marker_ys,
++ TextScale, GLUT_BITMAP_8_BY_13 );
++ }
++ }
++ else {
++ drawOneLine( marker_xs, marker_ys, marker_xe, marker_ys );
++ if( !(options & HUDS_NOTEXT)) {
++ if( options & HUDS_LEFT ) {
++ textString( marker_xs - 8 * strlen(TextScale) - 2,
++ marker_ys - 4,
++ TextScale, GLUT_BITMAP_8_BY_13 );
++ }
++ else {
++ textString( marker_xe + 3 * strlen(TextScale),
++ marker_ys - 4,
++ TextScale, GLUT_BITMAP_8_BY_13 );
++ }
++ }
++ }
++ } // Else read oriented right
++ } // End if modulo division by major interval is zero
++ } // End if major interval divisor non-zero
++ } // End if condition
++ } // End for range of i from vmin to vmax
++ } // End if VERTICAL SCALE TYPE
++ else { // Horizontal scale by default
++ drawOneLine( scrn_rect.left, // left tick bar
++ scrn_rect.top,
++ scrn_rect.left,
++ scrn_rect.top + scrn_rect.bottom);
++
++ drawOneLine( scrn_rect.left + scrn_rect.right, // right tick bar
++ scrn_rect.top,
++ scrn_rect.left + scrn_rect.right,
++ scrn_rect.top + scrn_rect.bottom );
++
++ marker_ys = scrn_rect.top; // Starting point for
++ marker_ye = scrn_rect.top + scrn_rect.bottom; // tick y location calcs
++
++ if( options & HUDS_TOP ) {
++ drawOneLine( scrn_rect.left,
++ scrn_rect.top,
++ scrn_rect.left + scrn_rect.right,
++ scrn_rect.top); // Bottom box line
++
++ marker_ye = scrn_rect.top + scrn_rect.bottom / 2; // Tick point adjust
++ // Bottom arrow
++ drawOneLine( mid_scr.x, marker_ye,
++ mid_scr.x - scrn_rect.bottom / 4, scrn_rect.top);
++ drawOneLine( mid_scr.x, marker_ye,
++ mid_scr.x + scrn_rect.bottom / 4, scrn_rect.top);
++ }
++ if( options & HUDS_BOTTOM) {
++ drawOneLine( scrn_rect.left,
++ scrn_rect.top + scrn_rect.bottom,
++ scrn_rect.left + scrn_rect.right,
++ scrn_rect.top + scrn_rect.bottom); // Top box line
++ // Tick point adjust
++ marker_ys = scrn_rect.top +
++ scrn_rect.bottom - scrn_rect.bottom / 2;
++ // Top arrow
++ drawOneLine( mid_scr.x + scrn_rect.bottom / 4,
++ scrn_rect.top + scrn_rect.bottom,
++ mid_scr.x ,
++ marker_ys );
++ drawOneLine( mid_scr.x - scrn_rect.bottom / 4,
++ scrn_rect.top + scrn_rect.bottom,
++ mid_scr.x ,
++ marker_ys );
++ }
++
++// if(( options & HUDS_BOTTOM) == HUDS_BOTTOM ) {
++// marker_xe = marker_ys;
++// marker_ys = marker_ye;
++// marker_ye = marker_xe;
++// }
++
++ // printf("vmin = %d vmax = %d\n", (int)vmin, (int)vmax);
++ for( i = (int)vmin; i <= (int)vmax; i++ ) {
++ // printf("<*> i = %d\n", i);
++ condition = true;
++ if( !modulo()) {
++ if( i < min_val()) {
++ condition = false;
++ }
++ }
++ // printf("<**> i = %d\n", i);
++ if( condition ) {
++ marker_xs = scrn_rect.left + (int)((i - vmin) * factor() + .5);
++ if( div_min()){
++ if( (i%(int)div_min()) == 0 ) {
++ // draw in ticks only if they aren't too close to the edge.
++ if((( marker_xs - 5) > scrn_rect.left ) &&
++ (( marker_xs + 5 )< (scrn_rect.left + scrn_rect.right))){
++
++ if( (options & HUDS_BOTH) == HUDS_BOTH ) {
++ drawOneLine( marker_xs, scrn_rect.top,
++ marker_xs, marker_ys - 4);
++ drawOneLine( marker_xs, marker_ye + 4,
++ marker_xs, scrn_rect.top + scrn_rect.bottom);
++ }
++ else {
++ if( options & HUDS_TOP) {
++ drawOneLine( marker_xs, marker_ys,
++ marker_xs, marker_ye - 4);
++ }
++ else {
++ drawOneLine( marker_xs, marker_ys + 4,
++ marker_xs, marker_ye);
++ }
++ }
++ }
++ }
++ }
++ // printf("<***> i = %d\n", i);
++ if( div_max()) {
++ // printf("i = %d\n", i);
++ if( (i%(int)div_max())==0 ) {
++ if(modulo()) {
++ if( disp_val < 0) {
++ disp_val += modulo();
++ }
++ else {
++ disp_val = i % modulo();
++ }
++ }
++ else {
++ disp_val = i;
++ }
++ // printf("disp_val = %d\n", disp_val);
++ // printf("%d\n", (int)(disp_val * (double)data_scaling() + 0.5));
++ sprintf( TextScale, "%d", (int)(disp_val * data_scaling() +.5));
++ // Draw major ticks and text only if far enough from the edge.
++ if(( (marker_xs - 10)> scrn_rect.left ) &&
++ ( (marker_xs + 10) < (scrn_rect.left + scrn_rect.right))){
++ if( (options & HUDS_BOTH) == HUDS_BOTH) {
++ drawOneLine( marker_xs, scrn_rect.top,
++ marker_xs, marker_ys);
++ drawOneLine( marker_xs, marker_ye,
++ marker_xs, scrn_rect.top + scrn_rect.bottom);
++
++ if( !(options & HUDS_NOTEXT)) {
++ textString ( marker_xs - 4 * strlen(TextScale),
++ marker_ys + 4,
++ TextScale, GLUT_BITMAP_8_BY_13 );
++ }
++ }
++ else {
++ drawOneLine( marker_xs, marker_ys,
++ marker_xs, marker_ye );
++ if( !(options & HUDS_NOTEXT)) {
++ if( options & HUDS_TOP ) {
++ textString ( marker_xs - 4 * strlen(TextScale),
++ scrn_rect.top + scrn_rect.bottom - 10,
++ TextScale, GLUT_BITMAP_8_BY_13 );
++ }
++ else {
++ textString( marker_xs - 4 * strlen(TextScale),
++ scrn_rect.top,
++ TextScale, GLUT_BITMAP_8_BY_13 );
++ }
++ }
++ }
++ }
++ }
++ }
++ // printf("<****> i = %d\n", i);
++ }
++ }
++ }
++}
++
--- /dev/null
--- /dev/null
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++#include <stdlib.h>
++#include <string.h>
++#include <Aircraft/aircraft.hxx>
++#include <Include/fg_constants.h>
++#include <Math/fg_random.h>
++#include <Math/mat3.h>
++#include <Math/polar3d.hxx>
++#include <Scenery/scenery.hxx>
++#include <Time/fg_timer.hxx>
++
++
++#include "hud.hxx"
++
++//============ Top of dual_instr_item class member definitions ============
++
++dual_instr_item ::
++ dual_instr_item ( int x,
++ int y,
++ UINT width,
++ UINT height,
++ DBLFNPTR chn1_source,
++ DBLFNPTR chn2_source,
++ bool working,
++ UINT options ):
++ instr_item( x, y, width, height,
++ chn1_source, options, working),
++ alt_data_source( chn2_source )
++{
++}
++
++dual_instr_item ::
++ dual_instr_item( const dual_instr_item & image) :
++ instr_item ((instr_item &) image ),
++ alt_data_source( image.alt_data_source)
++{
++}
++
++dual_instr_item & dual_instr_item ::
++ operator = (const dual_instr_item & rhs )
++{
++ if( !(this == &rhs)) {
++ instr_item::operator = (rhs);
++ alt_data_source = rhs.alt_data_source;
++ }
++ return *this;
++}
++
++// End of hud_dnst.cxx
++
--- /dev/null
--- /dev/null
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++#include <stdlib.h>
++#include <string.h>
++#include <Aircraft/aircraft.hxx>
++#include <Include/fg_constants.h>
++#include <Math/fg_random.h>
++#include <Math/mat3.h>
++#include <Math/polar3d.hxx>
++#include <Scenery/scenery.hxx>
++#include <Time/fg_timer.hxx>
++
++
++#include "hud.hxx"
++//============== Top of guage_instr class member definitions ==============
++
++guage_instr ::
++ guage_instr( int x,
++ int y,
++ UINT width,
++ UINT height,
++ DBLFNPTR load_fn,
++ UINT options,
++ double disp_scale,
++ double maxValue,
++ double minValue,
++ UINT major_divs,
++ UINT minor_divs,
++ int dp_showing,
++ UINT modulus,
++ bool working) :
++ instr_scale( x, y, width, height,
++ load_fn, options,
++ (maxValue - minValue), // Always shows span?
++ maxValue, minValue,
++ disp_scale,
++ major_divs, minor_divs,
++ modulus, dp_showing,
++ working)
++{
++}
++
++guage_instr ::
++ ~guage_instr()
++{
++}
++
++guage_instr ::
++ guage_instr( const guage_instr & image):
++ instr_scale( (instr_scale &) image)
++{
++}
++
++guage_instr & guage_instr ::
++ operator = (const guage_instr & rhs )
++{
++ if( !(this == &rhs)) {
++ instr_scale::operator = (rhs);
++ }
++ return *this;
++}
++
++// As implemented, draw only correctly draws a horizontal or vertical
++// scale. It should contain a variation that permits clock type displays.
++// Now is supports "tickless" displays such as control surface indicators.
++// This routine should be worked over before using. Current value would be
++// fetched and not used if not commented out. Clearly that is intollerable.
++
++void guage_instr :: draw (void)
++{
++ int marker_xs, marker_xe;
++ int marker_ys, marker_ye;
++ int text_x, text_y;
++ int i;
++ char TextScale[80];
++ bool condition;
++ int disp_val;
++ double vmin = min_val();
++ double vmax = max_val();
++ POINT mid_scr = get_centroid();
++ double cur_value = get_value();
++ RECT scrn_rect = get_location();
++ UINT options = get_options();
++
++ // Draw the basic markings for the scale...
++
++ if( options & HUDS_VERT ) { // Vertical scale
++ drawOneLine( scrn_rect.left, // Bottom tick bar
++ scrn_rect.top,
++ scrn_rect.left + scrn_rect.right,
++ scrn_rect.top);
++
++ drawOneLine( scrn_rect.left, // Top tick bar
++ scrn_rect.top + scrn_rect.bottom,
++ scrn_rect.left + scrn_rect.right,
++ scrn_rect.top + scrn_rect.bottom );
++
++ marker_xs = scrn_rect.left;
++ marker_xe = scrn_rect.left + scrn_rect.right;
++
++ if( options & HUDS_LEFT ) { // Read left, so line down right side
++ drawOneLine( scrn_rect.left + scrn_rect.right,
++ scrn_rect.top,
++ scrn_rect.left + scrn_rect.right,
++ scrn_rect.top + scrn_rect.bottom);
++
++ marker_xs = marker_xe - scrn_rect.right / 3; // Adjust tick xs
++ }
++ if( options & HUDS_RIGHT ) { // Read right, so down left sides
++ drawOneLine( scrn_rect.left,
++ scrn_rect.top,
++ scrn_rect.left,
++ scrn_rect.top + scrn_rect.bottom);
++ marker_xe = scrn_rect.left + scrn_rect.right / 3; // Adjust tick xe
++ }
++
++ // At this point marker x_start and x_end values are transposed.
++ // To keep this from confusing things they are now interchanged.
++ if(( options & HUDS_BOTH) == HUDS_BOTH) {
++ marker_ye = marker_xs;
++ marker_xs = marker_xe;
++ marker_xe = marker_ye;
++ }
++
++ // Work through from bottom to top of scale. Calculating where to put
++ // minor and major ticks.
++
++ if( !(options & HUDS_NOTICKS )) { // If not no ticks...:)
++ // Calculate x marker offsets
++ for( i = (int)vmin; i <= (int)vmax; i++ ) {
++
++ // Calculate the location of this tick
++ marker_ys = scrn_rect.top + (int)((i - vmin) * factor() + .5);
++
++ // We compute marker_ys even though we don't know if we will use
++ // either major or minor divisions. Simpler.
++
++ if( div_min()) { // Minor tick marks
++ if( (i%div_min()) == 0) {
++ if((options & HUDS_LEFT) && (options && HUDS_RIGHT)) {
++ drawOneLine( scrn_rect.left, marker_ys,
++ marker_xs - 3, marker_ys );
++ drawOneLine( marker_xe + 3, marker_ys,
++ scrn_rect.left + scrn_rect.right, marker_ys );
++ }
++ else {
++ if( options & HUDS_LEFT) {
++ drawOneLine( marker_xs + 3, marker_ys, marker_xe, marker_ys );
++ }
++ else {
++ drawOneLine( marker_xs, marker_ys, marker_xe - 3, marker_ys );
++ }
++ }
++ }
++ }
++
++ // Now we work on the major divisions. Since these are also labeled
++ // and no labels are drawn otherwise, we label inside this if
++ // statement.
++
++ if( div_max()) { // Major tick mark
++ if( (i%div_max()) == 0 ) {
++ if((options & HUDS_LEFT) && (options && HUDS_RIGHT)) {
++
++ drawOneLine( scrn_rect.left, marker_ys,
++ marker_xs, marker_ys );
++ drawOneLine( marker_xe, marker_ys,
++ scrn_rect.left + scrn_rect.right, marker_ys );
++ }
++ else {
++ drawOneLine( marker_xs, marker_ys, marker_xe, marker_ys );
++ }
++
++ if( !(options & HUDS_NOTEXT)) {
++ disp_val = i;
++ sprintf( TextScale, "%d",disp_val * (int)(data_scaling() +.5));
++
++ if((options & HUDS_LEFT) && (options && HUDS_RIGHT)) {
++ text_x = mid_scr.x - 2 - ((3 * strlen( TextScale ))>>1);
++ }
++ else {
++ if( options & HUDS_LEFT ) {
++ text_x = marker_xs - 2 - 3 * strlen( TextScale);
++ }
++ else {
++ text_x = marker_xe + 10 - strlen( TextScale );
++ }
++ }
++ // Now we know where to put the text.
++ text_y = marker_ys;
++ textString( text_x, text_y, TextScale, GLUT_BITMAP_8_BY_13 );
++ }
++ }
++ } //
++ } //
++ } //
++ // Now that the scale is drawn, we draw in the pointer(s). Since labels
++ // have been drawn, text_x and text_y may be recycled. This is used
++ // with the marker start stops to produce a pointer for each side reading
++
++ text_y = scrn_rect.top + (int)((cur_value - vmin) * factor() + .5);
++// text_x = marker_xs - scrn_rect.left;
++
++ if( options & HUDS_RIGHT ) {
++ drawOneLine(scrn_rect.left, text_y + 5,
++ marker_xe, text_y);
++ drawOneLine(scrn_rect.left, text_y - 5,
++ marker_xe, text_y);
++ }
++ if( options & HUDS_LEFT ) {
++ drawOneLine(scrn_rect.left + scrn_rect.right, text_y + 5,
++ marker_xs, text_y);
++ drawOneLine(scrn_rect.left + scrn_rect.right, text_y - 5,
++ marker_xs, text_y);
++ }
++ } // End if VERTICAL SCALE TYPE
++ else { // Horizontal scale by default
++ drawOneLine( scrn_rect.left, // left tick bar
++ scrn_rect.top,
++ scrn_rect.left,
++ scrn_rect.top + scrn_rect.bottom);
++
++ drawOneLine( scrn_rect.left + scrn_rect.right, // right tick bar
++ scrn_rect.top,
++ scrn_rect.left + scrn_rect.right,
++ scrn_rect.top + scrn_rect.bottom );
++
++ marker_ys = scrn_rect.top; // Starting point for
++ marker_ye = scrn_rect.top + scrn_rect.bottom; // tick y location calcs
++ marker_xs = scrn_rect.left + (int)((cur_value - vmin) * factor() + .5);
++
++ if( options & HUDS_TOP ) {
++ drawOneLine( scrn_rect.left,
++ scrn_rect.top,
++ scrn_rect.left + scrn_rect.right,
++ scrn_rect.top); // Bottom box line
++
++ marker_ye = scrn_rect.top + scrn_rect.bottom / 2; // Tick point adjust
++ // Bottom arrow
++ drawOneLine( marker_xs, marker_ye,
++ marker_xs - scrn_rect.bottom / 4, scrn_rect.top);
++ drawOneLine( marker_xs, marker_ye,
++ marker_xs + scrn_rect.bottom / 4, scrn_rect.top);
++ }
++ if( options & HUDS_BOTTOM) {
++ drawOneLine( scrn_rect.left,
++ scrn_rect.top + scrn_rect.bottom,
++ scrn_rect.left + scrn_rect.right,
++ scrn_rect.top + scrn_rect.bottom); // Top box line
++ // Tick point adjust
++ marker_ys = scrn_rect.top +
++ scrn_rect.bottom - scrn_rect.bottom / 2;
++ // Top arrow
++ drawOneLine( marker_xs + scrn_rect.bottom / 4,
++ scrn_rect.top + scrn_rect.bottom,
++ marker_xs,
++ marker_ys );
++ drawOneLine( marker_xs - scrn_rect.bottom / 4,
++ scrn_rect.top + scrn_rect.bottom,
++ marker_xs ,
++ marker_ys );
++ }
++
++ for( i = (int)vmin; i <= (int)vmax; i++ ) {
++ condition = true;
++ if( !modulo()) {
++ if( i < min_val()) {
++ condition = false;
++ }
++ }
++ if( condition ) {
++ marker_xs = scrn_rect.left + (int)((i - vmin) * factor() + .5);
++ if( div_min()){
++ if( (i%(int)div_min()) == 0 ) {
++ // draw in ticks only if they aren't too close to the edge.
++ if((( marker_xs + 5) > scrn_rect.left ) ||
++ (( marker_xs - 5 )< (scrn_rect.left + scrn_rect.right))){
++
++ if( (options & HUDS_BOTH) == HUDS_BOTH ) {
++ drawOneLine( marker_xs, scrn_rect.top,
++ marker_xs, marker_ys - 4);
++ drawOneLine( marker_xs, marker_ye + 4,
++ marker_xs, scrn_rect.top + scrn_rect.bottom);
++ }
++ else {
++ if( options & HUDS_TOP) {
++ drawOneLine( marker_xs, marker_ys,
++ marker_xs, marker_ye - 4);
++ }
++ else {
++ drawOneLine( marker_xs, marker_ys + 4,
++ marker_xs, marker_ye);
++ }
++ }
++ }
++ }
++ }
++ if( div_max()) {
++ if( (i%(int)div_max())==0 ) {
++ if(modulo()) {
++ if( disp_val < 0) {
++ disp_val += modulo();
++ }
++ else {
++ disp_val = i % modulo();
++ }
++ }
++ else {
++ disp_val = i;
++ }
++ sprintf( TextScale, "%d", (int)(disp_val * data_scaling() +.5));
++ // Draw major ticks and text only if far enough from the edge.
++ if(( (marker_xs - 10)> scrn_rect.left ) &&
++ ( (marker_xs + 10) < (scrn_rect.left + scrn_rect.right))){
++ if( (options & HUDS_BOTH) == HUDS_BOTH) {
++ drawOneLine( marker_xs, scrn_rect.top,
++ marker_xs, marker_ys);
++ drawOneLine( marker_xs, marker_ye,
++ marker_xs, scrn_rect.top + scrn_rect.bottom);
++
++ if( !(options & HUDS_NOTEXT)) {
++ textString ( marker_xs - 4 * strlen(TextScale),
++ marker_ys + 4,
++ TextScale, GLUT_BITMAP_8_BY_13 );
++ }
++ }
++ else {
++ drawOneLine( marker_xs, marker_ys,
++ marker_xs, marker_ye );
++ if( !(options & HUDS_NOTEXT)) {
++ if( options & HUDS_TOP ) {
++ textString ( marker_xs - 4 * strlen(TextScale),
++ scrn_rect.top + scrn_rect.bottom - 10,
++ TextScale, GLUT_BITMAP_8_BY_13 );
++ }
++ else {
++ textString( marker_xs - 4 * strlen(TextScale),
++ scrn_rect.top,
++ TextScale, GLUT_BITMAP_8_BY_13 );
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++}
++
++
--- /dev/null
--- /dev/null
++// Abstract Base Class instr_item
++//
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++
++#include <stdlib.h>
++#include <string.h>
++#include <Aircraft/aircraft.hxx>
++#include <Include/fg_constants.h>
++#include <Math/fg_random.h>
++#include <Math/mat3.h>
++#include <Math/polar3d.hxx>
++#include <Scenery/scenery.hxx>
++#include <Time/fg_timer.hxx>
++
++
++#include "hud.hxx"
++
++UINT instr_item :: instances = 0; // Initial value of zero
++int instr_item :: brightness = BRT_MEDIUM;
++glRGBTRIPLE instr_item :: color = {0.1, 0.7, 0.0};
++
++// constructor ( No default provided )
++instr_item ::
++ instr_item( int x,
++ int y,
++ UINT width,
++ UINT height,
++ DBLFNPTR data_source,
++ double data_scaling,
++ UINT options,
++ bool working) :
++ handle ( ++instances ),
++ load_value_fn ( data_source ),
++ disp_factor ( data_scaling ),
++ opts ( options ),
++ is_enabled ( working ),
++ broken ( FALSE )
++{
++ scrn_pos.left = x;
++ scrn_pos.top = y;
++ scrn_pos.right = width;
++ scrn_pos.bottom = height;
++
++ // Set up convenience values for centroid of the box and
++ // the span values according to orientation
++
++ if( opts & HUDS_VERT) { // Vertical style
++ // Insure that the midpoint marker will fall exactly at the
++ // middle of the bar.
++ if( !(scrn_pos.bottom % 2)) {
++ scrn_pos.bottom++;
++ }
++ scr_span = scrn_pos.bottom;
++ }
++ else {
++ // Insure that the midpoint marker will fall exactly at the
++ // middle of the bar.
++ if( !(scrn_pos.right % 2)) {
++ scrn_pos.right++;
++ }
++ scr_span = scrn_pos.right;
++ }
++ // Here we work out the centroid for the corrected box.
++ mid_span.x = scrn_pos.left + (scrn_pos.right >> 1);
++ mid_span.y = scrn_pos.top + (scrn_pos.bottom >> 1);
++}
++
++
++// copy constructor
++instr_item ::
++ instr_item ( const instr_item & image ):
++ handle ( ++instances ),
++ scrn_pos ( image.scrn_pos ),
++ load_value_fn( image.load_value_fn),
++ disp_factor ( image.disp_factor ),
++ opts ( image.opts ),
++ is_enabled ( image.is_enabled ),
++ broken ( image.broken ),
++ scr_span ( image.scr_span ),
++ mid_span ( image.mid_span )
++{
++}
++
++// assignment operator
++
++instr_item & instr_item :: operator = ( const instr_item & rhs )
++{
++ if( !(this == &rhs )) { // Not an identity assignment
++ scrn_pos = rhs.scrn_pos;
++ load_value_fn = rhs.load_value_fn;
++ disp_factor = rhs.disp_factor;
++ opts = rhs.opts;
++ is_enabled = rhs.is_enabled;
++ broken = rhs.broken;
++ }
++ return *this;
++}
++
++// destructor
++
++instr_item :: ~instr_item ()
++{
++ if( instances ) {
++ instances--;
++ }
++}
++
++void instr_item ::
++ update( void )
++{
++}
++
++// break_display This is emplaced to provide hooks for making
++// instruments unreliable. The default behavior is
++// to simply not display, but more sophisticated behavior is available
++// by over riding the function which is virtual in this class.
++
++void instr_item ::
++ break_display ( bool bad )
++{
++ broken = !!bad;
++ is_enabled = FALSE;
++}
++
++void instr_item ::
++ SetBrightness ( int level )
++{
++ brightness = level; // This is all we will do for now. Later the
++ // brightness levels will be sensitive both to
++ // the control knob and the outside light levels
++ // to emulated night vision effects.
++}
++
++UINT instr_item :: get_Handle( void )
++{
++ return handle;
++}
++
--- /dev/null
--- /dev/null
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++#include <stdlib.h>
++#include <string.h>
++#include <Aircraft/aircraft.hxx>
++#include <Include/fg_constants.h>
++#include <Math/fg_random.h>
++#include <Math/mat3.h>
++#include <Math/polar3d.hxx>
++#include <Scenery/scenery.hxx>
++#include <Time/fg_timer.hxx>
++
++
++#include "hud.hxx"
++
++//======================= Top of instr_label class =========================
++instr_label ::
++ instr_label( int x,
++ int y,
++ UINT width,
++ UINT height,
++ DBLFNPTR data_source,
++ const char *label_format,
++ const char *pre_label_string,
++ const char *post_label_string,
++ double scale_data,
++ UINT options,
++ fgLabelJust justification,
++ int font_size,
++ int blinking,
++ bool working ):
++ instr_item( x, y, width, height,
++ data_source, scale_data,options, working ),
++ pformat ( label_format ),
++ pre_str ( pre_label_string ),
++ post_str ( post_label_string ),
++ justify ( justification ),
++ fontSize ( font_size ),
++ blink ( blinking )
++{
++}
++
++// I put this in to make it easy to construct a class member using the current
++// C code.
++
++
++instr_label :: ~instr_label()
++{
++}
++
++// Copy constructor
++instr_label :: instr_label( const instr_label & image) :
++ instr_item((const instr_item &)image),
++ pformat ( image.pformat ),
++ pre_str ( image.pre_str ),
++ post_str ( image.post_str ),
++ blink ( image.blink )
++{
++}
++
++instr_label & instr_label ::operator = (const instr_label & rhs )
++{
++ if( !(this == &rhs)) {
++ instr_item::operator = (rhs);
++ pformat = rhs.pformat;
++ fontSize = rhs.fontSize;
++ blink = rhs.blink;
++ justify = rhs.justify;
++ pre_str = rhs.pre_str;
++ post_str = rhs.post_str;
++ }
++ return *this;
++}
++
++//
++// draw Draws a label anywhere in the HUD
++//
++//
++void instr_label ::
++draw( void ) // Required method in base class
++{
++ char format_buffer[80];
++ char label_buffer[80];
++ int posincr;
++ int lenstr;
++ RECT scrn_rect = get_location();
++
++ if( pre_str != NULL) {
++ if( post_str != NULL ) {
++ sprintf( format_buffer, "%s%s%s", pre_str, pformat, post_str );
++ }
++ else {
++ sprintf( format_buffer, "%s%s", pre_str, pformat );
++ }
++ }
++ else {
++ if( post_str != NULL ) {
++ sprintf( format_buffer, "%s%s", pformat, post_str );
++ }
++ } // else do nothing if both pre and post strings are nulls. Interesting.
++
++ if( data_available() ) {
++ sprintf( label_buffer, format_buffer, get_value() );
++ }
++ else {
++ sprintf( label_buffer, format_buffer );
++ }
++
++#ifdef DEBUGHUD
++ fgPrintf( FG_COCKPIT, FG_DEBUG, format_buffer );
++ fgPrintf( FG_COCKPIT, FG_DEBUG, "\n" );
++ fgPrintf( FG_COCKPIT, FG_DEBUG, label_buffer );
++ fgPrintf( FG_COCKPIT, FG_DEBUG, "\n" );
++#endif
++ lenstr = strlen( label_buffer );
++
++ posincr = 0; // default to RIGHT_JUST ... center located calc: -lenstr*8;
++
++ if( justify == CENTER_JUST ) {
++ posincr = - (lenstr << 2); // -lenstr*4;
++ }
++ else {
++ if( justify == LEFT_JUST ) {
++ posincr = - (lenstr << 8); // 0;
++ }
++ }
++
++ if( fontSize == SMALL ) {
++ textString( scrn_rect.left + posincr, scrn_rect.top,
++ label_buffer, GLUT_BITMAP_8_BY_13);
++ }
++ else {
++ if( fontSize == LARGE ) {
++ textString( scrn_rect.left + posincr, scrn_rect.top,
++ label_buffer, GLUT_BITMAP_9_BY_15);
++ }
++ }
++}
++
--- /dev/null
--- /dev/null
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++#include <stdlib.h>
++#include <string.h>
++#include <Aircraft/aircraft.hxx>
++#include <Include/fg_constants.h>
++#include <Math/fg_random.h>
++#include <Math/mat3.h>
++#include <Math/polar3d.hxx>
++#include <Scenery/scenery.hxx>
++#include <Time/fg_timer.hxx>
++
++
++#include "hud.hxx"
++//====================== Top of HudLadder Class =======================
++HudLadder ::
++ HudLadder( int x,
++ int y,
++ UINT width,
++ UINT height,
++ DBLFNPTR ptch_source,
++ DBLFNPTR roll_source,
++ double span_units,
++ double major_div,
++ double minor_div,
++ UINT screen_hole,
++ UINT lbl_pos,
++ bool working) :
++ dual_instr_item( x, y, width, height,
++ ptch_source,
++ roll_source,
++ working,
++ HUDS_RIGHT),
++ width_units ( span_units ),
++ div_units ( major_div < 0? -major_div: major_div ),
++ minor_div ( minor_div ),
++ label_pos ( lbl_pos ),
++ scr_hole ( screen_hole ),
++ vmax ( span_units/2 ),
++ vmin ( -vmax )
++{
++ if( !width_units ) {
++ width_units = 45;
++ }
++ factor = (double)get_span() / (double) width_units;
++}
++
++HudLadder ::
++ ~HudLadder()
++{
++}
++
++HudLadder ::
++ HudLadder( const HudLadder & image ) :
++ dual_instr_item( (dual_instr_item &) image),
++ width_units ( image.width_units ),
++ div_units ( image.div_units ),
++ label_pos ( image.label_pos ),
++ scr_hole ( image.scr_hole ),
++ vmax ( image.vmax ),
++ vmin ( image.vmin ),
++ factor ( image.factor )
++{
++}
++HudLadder & HudLadder ::
++ operator = ( const HudLadder & rhs )
++{
++ if( !(this == &rhs)) {
++ (dual_instr_item &)(*this) = (dual_instr_item &)rhs;
++ width_units = rhs.width_units;
++ div_units = rhs.div_units;
++ label_pos = rhs.label_pos;
++ scr_hole = rhs.scr_hole;
++ vmax = rhs.vmax;
++ vmin = rhs.vmin;
++ factor = rhs.factor;
++ }
++ return *this;
++}
++
++//
++// Draws a climb ladder in the center of the HUD
++//
++
++void HudLadder :: draw( void )
++{
++ double roll_value;
++ double pitch_value;
++ int marker_y;
++ int x_ini;
++ int x_end;
++ int y_ini;
++ int y_end;
++ int new_x_ini;
++ int new_x_end;
++ int new_y_ini;
++ int new_y_end;
++ int i;
++ POINT centroid = get_centroid();
++ RECT box = get_location();
++ int scr_min = box.top;
++ int half_span = box.right >> 1;
++ char TextLadder[80];
++ int condition;
++ int label_length;
++ roll_value = current_ch2();
++ GLfloat sinRoll = sin( roll_value );
++ GLfloat cosRoll = cos( roll_value );
++
++ pitch_value = current_ch1() * RAD_TO_DEG;
++ vmin = pitch_value - (double)width_units/2.0;
++ vmax = pitch_value + (double)width_units/2.0;
++
++// Box the target.
++ drawOneLine( centroid.x - 5, centroid.y, centroid.x, centroid.y + 5);
++ drawOneLine( centroid.x, centroid.y + 5, centroid.x + 5, centroid.y);
++ drawOneLine( centroid.x + 5, centroid.y, centroid.x, centroid.y - 5);
++ drawOneLine( centroid.x, centroid.y - 5, centroid.x - 5, centroid.y);
++
++ for( i=(int)vmin; i<=(int)vmax; i++ ) { // Through integer pitch values...
++ condition = 1;
++ if( condition ) {
++ marker_y = centroid.y + (int)(((double)(i - pitch_value) * factor) + .5);
++ if( div_units ) {
++ if( !(i % div_units )) { // At integral multiple of div
++ sprintf( TextLadder, "%d", i );
++ label_length = strlen( TextLadder );
++ if( scr_hole == 0 ) {
++ if( i ) {
++ x_ini = centroid.x - half_span;
++ }
++ else { // Make zero point wider on left
++ x_ini = centroid.x - half_span - 10;
++ }
++ y_ini = marker_y;
++ x_end = centroid.x + half_span;
++ y_end = marker_y;
++ new_x_ini = centroid.x + (int)(
++ (x_ini - centroid.x) * cosRoll -
++ (y_ini - centroid.y) * sinRoll);
++ new_y_ini = centroid.y + (int)( \
++ (x_ini - centroid.x) * sinRoll + \
++ (y_ini - centroid.y) * cosRoll);
++ new_x_end = centroid.x + (int)( \
++ (x_end - centroid.x) * cosRoll - \
++ (y_end - centroid.y) * sinRoll);
++ new_y_end = centroid.y + (int)( \
++ (x_end - centroid.x) * sinRoll + \
++ (y_end - centroid.y) * cosRoll);
++
++ if( i >= 0 ) { // Above zero draw solid lines
++ drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
++ }
++ else { // Below zero draw dashed lines.
++ glEnable(GL_LINE_STIPPLE);
++ glLineStipple( 1, 0x00FF );
++ drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
++ glDisable(GL_LINE_STIPPLE);
++ }
++ // Calculate the position of the left text and write it.
++ new_x_ini = centroid.x + (int)(
++ (x_ini - 8 * label_length- 4 - centroid.x) * cosRoll -
++ (y_ini - 4 ) * sinRoll);
++ new_y_ini = centroid.y + (int)(
++ (x_ini - 8 * label_length- 4 - centroid.x) * sinRoll +
++ (y_ini - 4 - centroid.y) * cosRoll);
++ strokeString( new_x_ini , new_y_ini ,
++ TextLadder, GLUT_STROKE_ROMAN,
++ roll_value );
++
++ // Calculate the position of the right text and write it.
++ new_x_end = centroid.x + (int)( \
++ (x_end + 24 - 8 * label_length - centroid.x) * cosRoll - \
++ (y_end - 4 - centroid.y) * sinRoll);
++ new_y_end = centroid.y + (int)( \
++ (x_end + 24 - 8 * label_length - centroid.x) * sinRoll + \
++ (y_end - 4 - centroid.y) * cosRoll);
++ strokeString( new_x_end, new_y_end,
++ TextLadder, GLUT_STROKE_ROMAN,
++ roll_value );
++ }
++ else { // Draw ladder with space in the middle of the lines
++ // Start by calculating the points and drawing the
++ // left side lines.
++ if( i != 0 ) {
++ x_ini = centroid.x - half_span;
++ }
++ else {
++ x_ini = centroid.x - half_span - 10;
++ }
++ y_ini = marker_y;
++ x_end = centroid.x - half_span + scr_hole/2;
++ y_end = marker_y;
++
++ new_x_end = centroid.x+ (int)( \
++ (x_end - centroid.x) * cosRoll -\
++ (y_end - centroid.y) * sinRoll);
++ new_y_end = centroid.y+ (int)( \
++ (x_end - centroid.x) * sinRoll +\
++ (y_end - centroid.y) * cosRoll);
++ new_x_ini = centroid.x + (int)( \
++ (x_ini - centroid.x) * cosRoll -\
++ (y_ini - centroid.y) * sinRoll);
++ new_y_ini = centroid.y + (int)( \
++ (x_ini - centroid.x) * sinRoll +\
++ (y_ini - centroid.y) * cosRoll);
++
++ if( i >= 0 )
++ {
++ drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
++ }
++ else {
++ glEnable(GL_LINE_STIPPLE);
++ glLineStipple( 1, 0x00FF );
++ drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
++ glDisable(GL_LINE_STIPPLE);
++ }
++ // Now calculate the location of the left side label using
++ // the previously calculated start of the left side line.
++
++ x_ini = x_ini - (label_length + 32 + centroid.x);
++ if( i < 0) {
++ x_ini -= 8;
++ }
++ else {
++ if( i == 0 ) {
++ x_ini += 20;
++ }
++ }
++ y_ini = y_ini - ( 4 + centroid.y);
++
++ new_x_ini = centroid.x + (int)(x_ini * cosRoll - y_ini * sinRoll);
++ new_y_ini = centroid.y + (int)(x_ini * sinRoll + y_ini * cosRoll);
++ strokeString( new_x_ini , new_y_ini ,
++ TextLadder, GLUT_STROKE_MONO_ROMAN,
++ roll_value );
++
++ // Now calculate and draw the right side line location
++ x_ini = centroid.x + half_span - scr_hole/2;
++ y_ini = marker_y;
++ if( i != 0 ) {
++ x_end = centroid.x + half_span;
++ }
++ else {
++ x_end = centroid.x + half_span + 10;
++ }
++ y_end = marker_y;
++
++ new_x_ini = centroid.x + (int)( \
++ (x_ini-centroid.x)*cosRoll -\
++ (y_ini-centroid.y)*sinRoll);
++ new_y_ini = centroid.y + (int)( \
++ (x_ini-centroid.x)*sinRoll +\
++ (y_ini-centroid.y)*cosRoll);
++ new_x_end = centroid.x + (int)( \
++ (x_end-centroid.x)*cosRoll -\
++ (y_end-centroid.y)*sinRoll);
++ new_y_end = centroid.y + (int)( \
++ (x_end-centroid.x)*sinRoll +\
++ (y_end-centroid.y)*cosRoll);
++
++ if( i >= 0 )
++ {
++ drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
++ }
++ else
++ {
++ glEnable(GL_LINE_STIPPLE);
++ glLineStipple( 1, 0x00FF );
++ drawOneLine( new_x_ini, new_y_ini, new_x_end, new_y_end );
++ glDisable(GL_LINE_STIPPLE);
++ }
++
++ // Calculate the location and draw the right side label
++ // using the end of the line as previously calculated.
++ x_end -= centroid.x + label_length - 24;
++ if( i < 0 ) {
++ x_end -= 8;
++ }
++ y_end = marker_y - ( 4 + centroid.y);
++ new_x_end = centroid.x + (int)( (GLfloat)x_end * cosRoll -
++ (GLfloat)y_end * sinRoll);
++ new_y_end = centroid.y + (int)( (GLfloat)x_end * sinRoll +
++ (GLfloat)y_end * cosRoll);
++ strokeString( new_x_end, new_y_end,
++ TextLadder, GLUT_STROKE_MONO_ROMAN,
++ roll_value );
++ }
++ }
++ }
++ }
++ }
++}
++
--- /dev/null
--- /dev/null
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++#include <stdlib.h>
++#include <string.h>
++#include <Aircraft/aircraft.hxx>
++#include <Include/fg_constants.h>
++#include <Math/fg_random.h>
++#include <Math/mat3.h>
++#include <Math/polar3d.hxx>
++#include <Scenery/scenery.hxx>
++#include <Time/fg_timer.hxx>
++
++
++#include "hud.hxx"
++//============== Top of instr_scale class memeber definitions ===============
++//
++// Notes:
++// 1. instr_scales divide the specified location into half and then
++// the half opposite the read direction in half again. A bar is
++// then drawn along the second divider. Scale ticks are drawn
++// between the middle and quarter section lines (minor division
++// markers) or just over the middle line.
++//
++// 2. This class was not intended to be instanciated. See moving_scale
++// and guage_instr classes.
++//============================================================================
++instr_scale ::
++instr_scale ( int x,
++ int y,
++ UINT width,
++ UINT height,
++ DBLFNPTR load_fn,
++ UINT options,
++ double show_range,
++ double maxValue,
++ double minValue,
++ double disp_scale,
++ UINT major_divs,
++ UINT minor_divs,
++ UINT rollover,
++ int dp_showing,
++ bool working ) :
++ instr_item( x, y, width, height,
++ load_fn, disp_scale, options, working),
++ range_shown ( show_range ),
++ Maximum_value( maxValue ),
++ Minimum_value( minValue ),
++ Maj_div ( major_divs ),
++ Min_div ( minor_divs ),
++ Modulo ( rollover ),
++ signif_digits( dp_showing )
++{
++int temp;
++
++ scale_factor = (double)get_span() / range_shown;
++ if( show_range < 0 ) {
++ range_shown = -range_shown;
++ }
++ temp = (Maximum_value - Minimum_value) / 100;
++ if( range_shown < temp ) {
++ range_shown = temp;
++ }
++}
++
++instr_scale ::
++ instr_scale( const instr_scale & image ) :
++ instr_item( (const instr_item &) image),
++ range_shown ( image.range_shown ),
++ Maximum_value( image.Maximum_value ),
++ Minimum_value( image.Minimum_value ),
++ scale_factor ( image.scale_factor ),
++ Maj_div ( image.Maj_div ),
++ Min_div ( image.Min_div ),
++ Modulo ( image.Modulo ),
++ signif_digits( image.signif_digits )
++{
++}
++
++instr_scale & instr_scale :: operator = (const instr_scale & rhs )
++{
++ if( !(this == &rhs)) {
++ instr_item::operator = (rhs);
++ range_shown = rhs.range_shown;
++ scale_factor = rhs.scale_factor;
++ Maximum_value = rhs.Maximum_value;
++ Minimum_value = rhs.Minimum_value;
++ Maj_div = rhs.Maj_div;
++ Min_div = rhs.Min_div;
++ Modulo = rhs.Modulo;
++ signif_digits = rhs.signif_digits;
++ }
++ return *this;
++}
++
++instr_scale :: ~ instr_scale () {}
++
--- /dev/null
--- /dev/null
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++#include <stdlib.h>
++#include <string.h>
++#include <Aircraft/aircraft.hxx>
++#include <Include/fg_constants.h>
++#include <Math/fg_random.h>
++#include <Math/mat3.h>
++#include <Math/polar3d.hxx>
++#include <Scenery/scenery.hxx>
++#include <Time/fg_timer.hxx>
++
++
++#include "hud.hxx"
++//============ Top of fgTBI_instr class member definitions ==============
++
++fgTBI_instr ::
++fgTBI_instr( int x,
++ int y,
++ UINT width,
++ UINT height,
++ DBLFNPTR chn1_source,
++ DBLFNPTR chn2_source,
++ double maxBankAngle,
++ double maxSlipAngle,
++ UINT gap_width,
++ bool working ) :
++ dual_instr_item( x, y, width, height,
++ chn1_source,
++ chn2_source,
++ working,
++ HUDS_TOP),
++ BankLimit (maxBankAngle),
++ SlewLimit (maxSlipAngle),
++ scr_hole (gap_width )
++{
++}
++
++fgTBI_instr :: ~fgTBI_instr() {}
++
++fgTBI_instr :: fgTBI_instr( const fgTBI_instr & image):
++ dual_instr_item( (const dual_instr_item &) image),
++ BankLimit( image.BankLimit),
++ SlewLimit( image.SlewLimit),
++ scr_hole ( image.scr_hole )
++{
++}
++
++fgTBI_instr & fgTBI_instr ::
++operator = (const fgTBI_instr & rhs )
++{
++ if( !(this == &rhs)) {
++ dual_instr_item::operator = (rhs);
++ BankLimit = rhs.BankLimit;
++ SlewLimit = rhs.SlewLimit;
++ scr_hole = rhs.scr_hole;
++ }
++ return *this;
++}
++
++//
++// Draws a Turn Bank Indicator on the screen
++//
++
++ void fgTBI_instr :: draw( void )
++{
++ int x_inc1, y_inc1;
++ int x_inc2, y_inc2;
++ int x_t_inc1, y_t_inc1;
++
++ int d_bottom_x, d_bottom_y;
++ int d_right_x, d_right_y;
++ int d_top_x, d_top_y;
++ int d_left_x, d_left_y;
++
++ int inc_b_x, inc_b_y;
++ int inc_r_x, inc_r_y;
++ int inc_t_x, inc_t_y;
++ int inc_l_x, inc_l_y;
++ RECT My_box = get_location();
++ POINT centroid = get_centroid();
++ int tee_height = My_box.bottom;
++
++// struct fgFLIGHT *f = ¤t_aircraft.flight;
++ double sin_bank, cos_bank;
++ double bank_angle, sideslip_angle;
++ double ss_const; // sideslip angle pixels per rad
++
++ bank_angle = current_ch2(); // Roll limit +/- 30 degrees
++ if( bank_angle < -FG_PI_2/3 ) {
++ bank_angle = -FG_PI_2/3;
++ }
++ else
++ if( bank_angle > FG_PI_2/3 ) {
++ bank_angle = FG_PI_2/3;
++ }
++ sideslip_angle = current_ch1(); // Sideslip limit +/- 20 degrees
++ if( sideslip_angle < -FG_PI/9 ) {
++ sideslip_angle = -FG_PI/9;
++ }
++ else
++ if( sideslip_angle > FG_PI/9 ) {
++ sideslip_angle = FG_PI/9;
++ }
++
++ // sin_bank = sin( FG_2PI-FG_Phi );
++ // cos_bank = cos( FG_2PI-FG_Phi );
++ sin_bank = sin(FG_2PI-bank_angle);
++ cos_bank = cos(FG_2PI-bank_angle);
++
++ x_inc1 = (int)(get_span() * cos_bank);
++ y_inc1 = (int)(get_span() * sin_bank);
++ x_inc2 = (int)(scr_hole * cos_bank);
++ y_inc2 = (int)(scr_hole * sin_bank);
++
++ x_t_inc1 = (int)(tee_height * sin_bank);
++ y_t_inc1 = (int)(tee_height * cos_bank);
++
++ d_bottom_x = 0;
++ d_bottom_y = (int)(-scr_hole);
++ d_right_x = (int)(scr_hole);
++ d_right_y = 0;
++ d_top_x = 0;
++ d_top_y = (int)(scr_hole);
++ d_left_x = (int)(-scr_hole);
++ d_left_y = 0;
++
++ ss_const = (get_span()*2)/(FG_2PI/9); // width represents 40 degrees
++
++ d_bottom_x += (int)(sideslip_angle*ss_const);
++ d_right_x += (int)(sideslip_angle*ss_const);
++ d_left_x += (int)(sideslip_angle*ss_const);
++ d_top_x += (int)(sideslip_angle*ss_const);
++
++ inc_b_x = (int)(d_bottom_x*cos_bank-d_bottom_y*sin_bank);
++ inc_b_y = (int)(d_bottom_x*sin_bank+d_bottom_y*cos_bank);
++ inc_r_x = (int)(d_right_x*cos_bank-d_right_y*sin_bank);
++ inc_r_y = (int)(d_right_x*sin_bank+d_right_y*cos_bank);
++ inc_t_x = (int)(d_top_x*cos_bank-d_top_y*sin_bank);
++ inc_t_y = (int)(d_top_x*sin_bank+d_top_y*cos_bank);
++ inc_l_x = (int)(d_left_x*cos_bank-d_left_y*sin_bank);
++ inc_l_y = (int)(d_left_x*sin_bank+d_left_y*cos_bank);
++
++ if( scr_hole == 0 )
++ {
++ drawOneLine( centroid.x - x_inc1, centroid.y - y_inc1, \
++ centroid.x + x_inc1, centroid.y + y_inc1 );
++ }
++ else
++ {
++ drawOneLine( centroid.x - x_inc1, centroid.y - y_inc1, \
++ centroid.x - x_inc2, centroid.y - y_inc2 );
++ drawOneLine( centroid.x + x_inc2, centroid.y + y_inc2, \
++ centroid.x + x_inc1, centroid.y + y_inc1 );
++ }
++
++ // draw teemarks
++ drawOneLine( centroid.x + x_inc2, \
++ centroid.y + y_inc2, \
++ centroid.x + x_inc2 + x_t_inc1, \
++ centroid.y + y_inc2 - y_t_inc1 );
++ drawOneLine( centroid.x - x_inc2, \
++ centroid.y - y_inc2, \
++ centroid.x - x_inc2 + x_t_inc1, \
++ centroid.y - y_inc2 - y_t_inc1 );
++
++ // draw sideslip diamond (it is not yet positioned correctly )
++ drawOneLine( centroid.x + inc_b_x, \
++ centroid.y + inc_b_y, \
++ centroid.x + inc_r_x, \
++ centroid.y + inc_r_y );
++ drawOneLine( centroid.x + inc_r_x, \
++ centroid.y + inc_r_y, \
++ centroid.x + inc_t_x, \
++ centroid.y + inc_t_y );
++ drawOneLine( centroid.x + inc_t_x, \
++ centroid.y + inc_t_y, \
++ centroid.x + inc_l_x, \
++ centroid.y + inc_l_y );
++ drawOneLine( centroid.x + inc_l_x, \
++ centroid.y + inc_l_y, \
++ centroid.x + inc_b_x, \
++ centroid.y + inc_b_y );
++
++}
--- /dev/null
--- /dev/null
++// panel.cxx -- routines to draw an instrument panel
++//
++// Written by Friedemann Reinhard, started June 1998.
++//
++// Copyright(C)1998 Friedemann Reinhard-reinhard@theorie2.physik.uni-erlangen.de
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++
++#define FILLED true
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#include <stdlib.h>
++#include <stdio.h>
++#include <string.h>
++#include <string>
++#include <math.h>
++
++#include <Debug/logstream.hxx>
++#include <Aircraft/aircraft.hxx>
++#include <Main/options.hxx>
++#include <Main/views.hxx>
++#include <Objects/texload.h>
++
++#include "panel.hxx"
++#include "cockpit.hxx"
++#include "hud.hxx"
++
++GLubyte *imag;
++int imag_width, imag_height;
++
++GLubyte *img;
++int img_width, img_height;
++
++static float value[4];
++static GLuint panel_tex_id[2];
++static GLubyte tex[32][128][3];
++static float alphahist;
++static float Xzoom, Yzoom;
++static Pointer pointer[20];
++static int NumPoint = 4;
++static int i = 0;
++static GLdouble mvmatrix[16];
++static GLdouble matrix[16];
++static double var[20];
++static double offset;
++static float alpha;
++static int n1;
++static int n2;
++
++static GLfloat Wings[] = {-1.25, -28.125, 1.255, -28.125, 1.255, 28.125, -1.25, 28.125};
++static GLfloat Elevator[] = { 3.0, -10.9375, 4.5, -10.9375, 4.5, 10.9375, 3.0, 10.9375};
++static GLfloat Rudder[] = {2.0, -0.45, 10.625, -0.45, 10.625, 0.55, 2.0, 0.55};
++
++FGPanel* FGPanel::OurPanel = 0;
++
++// FGPanel::FGPanel() - constructor to initialize the panel.
++FGPanel::FGPanel(void){
++
++ string tpath;
++ int x, y;
++ FILE *f;
++ char line[256];
++ GLint test;
++ GLubyte tex[262144];
++
++OurPanel = this;
++
++ Xzoom = (float)((float)(current_view.get_winWidth())/1024);
++ Yzoom = (float)((float)(current_view.get_winHeight())/768);
++
++test_instr[3] = new FGTexInstrument(144.375, 166.875, 4, 32, 3, 30, 15.0, 260.0, -20.0, 360, 65, 193, 0);
++test_instr[4] = new FGTexInstrument(358, 52, 4, 30, 3, 30, -3.0, 3.0, 100, 440, 66.15, 66, 2);
++test_instr[5] = new FGTexInstrument(357.5, 167, 5, 25, 4, 30, 0, 10000, 0, 360, 194, 191, 1);
++test_instr[6] = new FGTexInstrument(357.5, 167, 5, 32, 3, 30, 0, 3000, 0, 1080, 194, 191, 1);
++test_instr[0] = new FGHorizon(251, 166.75);
++test_instr[1] = new FGTurnCoordinator(143.75, 51.75);
++//test_instr[2] = new FGRpmGauge(462.5, 133);
++test_instr[2] = new FGTexInstrument(462.5, 133, 10, 20, 5.5, 60, 0.0, 1.0, -67, 180, 174, 83, 3);
++
++// FontList = glGenLists (256);
++// glListBase(FontList);
++// InitLists();
++
++#ifdef GL_VERSION_1_1
++ xglGenTextures(2, panel_tex_id);
++ xglBindTexture(GL_TEXTURE_2D, panel_tex_id[1]);
++#elif GL_EXT_texture_object
++ xglGenTexturesEXT(2, panel_tex_id);
++ xglBindTextureEXT(GL_TEXTURE_2D, panel_tex_id[1]);
++#else
++# error port me
++#endif
++
++ xglMatrixMode(GL_PROJECTION);
++ xglPushMatrix();
++ xglLoadIdentity();
++ xglViewport(0, 0, 640, 480);
++ xglOrtho(0, 640, 0, 480, 1, -1);
++ xglMatrixMode(GL_MODELVIEW);
++ xglPushMatrix();
++ xglLoadIdentity();
++ xglPixelStorei(GL_UNPACK_ALIGNMENT, 4);
++ xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
++ xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
++ xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
++ xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
++
++ // load in the texture data
++
++ xglPixelStorei(GL_UNPACK_ROW_LENGTH, 256);
++ tpath = current_options.get_fg_root() + "/Textures/gauges.rgb";
++ if((img = read_rgb_texture( (char *)tpath.c_str(), &img_width, &img_height ))==NULL){
++ }
++
++ xglPixelStorei(GL_UNPACK_ROW_LENGTH, 256);
++ tpath = current_options.get_fg_root() + "/Textures/gauges2.rgb";
++ if((imag = read_rgb_texture( (char *)tpath.c_str(), &imag_width, &imag_height ))==NULL){
++ }
++
++ xglPixelStorei(GL_UNPACK_ROW_LENGTH, 1024);
++
++ tpath = current_options.get_fg_root() + "/Textures/Fullone.rgb";
++ if ((background = read_rgb_texture( (char *)tpath.c_str(), &width, &height ))==NULL ){
++ }
++
++// for(y=0;y<256;y++){
++// for(x=0;x<256;x++){
++// tex[(y+x*256)*3] = imag[(y+x*256)*3];
++// tex[(y+x*256)*3 + 1] = imag[(y+x*256)*3 + 1];
++// tex[(y+x*256)*3 + 2] = imag[(y+x*256)*3 + 2];
++// tex[(y+x*256)*3 + 3] = (imag[(y+x*256)*3 + 1] + imag[(y+x*256)*3 + 2] // + imag[(y+x*256)*3 + 0])/3;
++//
++// if((imag[(y+x*256)*3] < 150) && (imag[(y+x*256)*3 +1] < 150) && // (imag[(y+x*256)*3 + 2] < 150) ){
++// tex[(y+x*256)*3 + 3] = 0x0;
++// }
++// else{
++// tex[(y+x*256)*3 + 3] = 0xff;
++// }
++// }
++// }
++
++ xglPixelZoom(Xzoom, Yzoom);
++ xglPixelStorei(GL_UNPACK_ALIGNMENT, 1);
++ xglPixelStorei(GL_UNPACK_ROW_LENGTH, 1024);
++ xglPixelStorei(GL_UNPACK_ROW_LENGTH, 1024);
++ xglRasterPos2i(0,0);
++ xglPixelZoom(Xzoom, Yzoom);
++ xglPixelStorei(GL_UNPACK_ROW_LENGTH, 256);
++ xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, imag);
++
++#ifdef GL_VERSION_1_1
++ xglBindTexture(GL_TEXTURE_2D, panel_tex_id[0]);
++#elif GL_EXT_texture_object
++ xglBindTextureEXT(GL_TEXTURE_2D, panel_tex_id[0]);
++#else
++# error port me
++#endif
++ xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
++ xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
++ xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
++ xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
++ xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid *)(img));
++
++ xglMatrixMode(GL_MODELVIEW);
++ xglPopMatrix();
++}
++
++void FGPanel::ReInit( int x, int y, int finx, int finy){
++ fgOPTIONS *o;
++ int i;
++ GLint buffer;
++
++ o = ¤t_options;
++
++ xglDisable(GL_DEPTH_TEST);
++
++ Xzoom = (float)((float)(current_view.get_winWidth())/1024);
++ Yzoom = (float)((float)(current_view.get_winHeight())/768);
++
++ // save the current buffer state
++ xglGetIntegerv(GL_DRAW_BUFFER, &buffer);
++
++ // and enable both buffers for writing
++ xglDrawBuffer(GL_FRONT_AND_BACK);
++
++ xglMatrixMode(GL_PROJECTION);
++ xglPushMatrix();
++ xglLoadIdentity();
++ xglViewport(0, 0, 640, 480);
++ xglOrtho(0, 640, 0, 480, 1, -1);
++ xglMatrixMode(GL_MODELVIEW);
++ xglPushMatrix();
++ xglLoadIdentity();
++ xglPixelStorei(GL_UNPACK_ALIGNMENT, 1);
++ xglPixelZoom(Xzoom, Yzoom);
++ xglPixelStorei(GL_UNPACK_ALIGNMENT, 1);
++ xglPixelStorei(GL_UNPACK_ROW_LENGTH, 1024);
++ xglPixelStorei(GL_UNPACK_SKIP_PIXELS, x);
++ xglPixelStorei(GL_UNPACK_SKIP_ROWS, y);
++ xglRasterPos2i(x, y);
++ xglPixelZoom(Xzoom, Yzoom);
++ xglDrawPixels(finx - x, finy - y, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid *)(background));
++
++ // restore original buffer state
++ xglDrawBuffer( buffer );
++ xglEnable(GL_DEPTH_TEST);
++}
++
++void FGPanel::Update ( void ) {
++
++ float alpha;
++ double pitch;
++ double roll;
++ float alpharad;
++ double speed;
++ int i;
++
++// static bool beech_drawn = false;
++// char *test = "ALM 100";
++
++ var[0] = get_speed() /* * 1.4 */; // We have to multiply the airspeed by a
++ // factor, to simulate flying a Bonanza
++ var[1] = get_altitude();
++ var[2] = get_climb_rate() / 1000.0;
++ var[3] = get_throttleval();
++
++ xglMatrixMode(GL_PROJECTION);
++ xglPushMatrix();
++ xglLoadIdentity();
++ xglOrtho(0, 640, 0, 480, 10, -10);
++ xglMatrixMode(GL_MODELVIEW);
++ xglPushMatrix();
++ xglLoadIdentity();
++ xglDisable(GL_DEPTH_TEST);
++ xglEnable(GL_LIGHTING);
++ xglEnable(GL_TEXTURE_2D);
++ xglDisable(GL_BLEND);
++
++ xglMatrixMode(GL_MODELVIEW);
++ xglPopMatrix();
++ xglPushMatrix();
++
++ xglDisable(GL_LIGHTING);
++ test_instr[3]->Render();
++ test_instr[4]->Render();
++ test_instr[5]->Render();
++ test_instr[6]->Render();
++ xglPopMatrix();
++ xglPushMatrix();
++
++ test_instr[1]->Render();
++ test_instr[2]->Render();
++
++// DrawBeechcraftLogo(230, 235, 30, 10);
++// DrawScale(144.375, 166.875, 38, 41.0, 18, 340, 44, 2.0, 1.0, 1.0, 1.0);
++
++ xglEnable(GL_LIGHTING);
++
++ test_instr[0]->Render();
++
++
++ xglDisable(GL_TEXTURE_2D);
++ xglPopMatrix();
++ xglEnable(GL_DEPTH_TEST);
++ xglEnable(GL_LIGHTING);
++ xglDisable(GL_TEXTURE_2D);
++ xglDisable(GL_BLEND);
++ xglMatrixMode(GL_PROJECTION);
++ xglPopMatrix();
++ xglMatrixMode(GL_MODELVIEW);
++ xglPopMatrix();
++}
++
++// horizon - Let's draw an artificial horizon using both texture mapping and
++// primitive drawing
++
++void FGHorizon::Render(void){
++ double pitch;
++ double roll;
++ float shifted, alpha, theta;
++ float epsi = 360 / 180;
++ GLboolean Light;
++ GLfloat normal[2];
++
++ static int n, dn, rot, tmp1, tmp2;
++ float a;
++
++ GLfloat material[] = { 0.714844, 0.265625, 0.056875 ,1.0};
++ GLfloat material2[] = {0.6640625, 0.921875, 0.984375, 1.0};
++ GLfloat material3[] = {0.2, 0.2, 0.2, 1.0};
++ GLfloat material4[] = {0.8, 0.8, 0.8, 1.0};
++ GLfloat material5[] = {0.0, 0.0, 0.0, 1.0};
++ GLfloat direction[] = {0.0, 0.0, 0.0};
++ GLfloat light_position[4];
++ GLfloat light_ambient[] = {0.7, 0.7, 0.7, 1.0};
++ GLfloat light_ambient2[] = {0.7, 0.7, 0.7, 1.0};
++ GLfloat light_diffuse[] = {1.0, 1.0, 1.0, 1.0};
++ GLfloat light_specular[] = {1.0, 1.0, 1.0, 1.0};
++
++ pitch = get_pitch() * RAD_TO_DEG;
++ if(pitch > 45)
++ pitch = 45;
++
++ if(pitch < -45)
++ pitch = -45;
++
++ roll = get_roll() * RAD_TO_DEG;
++
++ xglEnable(GL_NORMALIZE);
++ xglEnable(GL_LIGHTING);
++ xglEnable(GL_TEXTURE_2D);
++ xglEnable(GL_LIGHT1);
++ xglDisable(GL_LIGHT2);
++ xglDisable(GL_LIGHT0);
++ xglMatrixMode(GL_MODELVIEW);
++ xglLoadIdentity();
++ xglTranslatef(XPos, YPos, 0);
++ xglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
++ xglMatrixMode(GL_TEXTURE);
++ xglPushMatrix();
++
++ // computations for the non-textured parts of the AH
++
++ shifted = -((pitch / 10) * 7.0588235);
++
++ if(shifted > (bottom - radius)){
++ theta = (180 - (acos((bottom - shifted) / radius)*RAD_TO_DEG));
++ n = (int)(theta / epsi) - 1;
++ n1 = n;
++ n2 = (180 - n1) + 2;
++ dn = n2 - n1;
++ rot = (int)(roll / epsi);
++ n1 += rot + 45;
++ n2 += rot + 45;
++ }
++
++ if(shifted < (-top + radius)){
++ theta = ((acos((-top - shifted) / radius)*RAD_TO_DEG));
++ n = (int)(theta / epsi) + 1;
++ n1 = n;
++ n2 = (180 - n1) + 2;
++ dn = n2 - n1;
++ rot = (int)(roll / epsi);
++ n1 += rot - 45;
++ n2 += rot - 45;
++ if(n1 < 0){ n1 += 180; n2 +=180;}
++ }
++
++ // end of computations
++
++ light_position[0] = 0.0;
++ light_position[1] = 0.0;
++ light_position[2] = 1.5;
++ light_position[3] = 0.0;
++ xglLightfv(GL_LIGHT1, GL_POSITION, light_position);
++ xglLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient);
++ xglLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);
++ xglLightfv(GL_LIGHT1, GL_SPECULAR, light_specular);
++ xglLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, direction);
++
++ #ifdef GL_VERSION_1_1
++ xglBindTexture(GL_TEXTURE_2D, panel_tex_id[1]);
++ #elif GL_EXT_texture_object
++ xglBindTextureEXT(GL_TEXTURE_2D, panel_tex_id[1]);
++ #else
++ # error port me
++ #endif
++
++ xglLoadIdentity();
++ xglTranslatef(0.0, ((pitch / 10) * 0.046875), 0.0);
++ xglTranslatef((texXPos/256), (texYPos/256), 0.0);
++ xglRotatef(-roll, 0.0, 0.0, 1.0);
++ xglScalef(1.7, 1.7, 0.0);
++
++ // the following loop draws the textured part of the AH
++
++ xglMaterialf(GL_FRONT, GL_SHININESS, 85.0);
++
++ xglMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, material4);
++ xglMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, material5);
++ xglMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, material3);
++
++ xglMatrixMode(GL_MODELVIEW);
++ xglBegin(GL_TRIANGLES);
++ for(i=45;i<225;i++){
++ xglTexCoord2f(0.0, 0.0);
++ xglNormal3f(0.0, 0.0, 0.6);
++ xglVertex3f(0.0, 0.0, 0.0);
++ xglTexCoord2f(texCoord[i % 180][0], texCoord[i % 180][1]);
++ xglNormal3f(normals[i % 180][0], normals[i % 180][1], 0.6);
++ xglVertex3f(vertices[i % 180][0], vertices[i % 180][1], 0.0);
++ n = (i + 1) % 180;
++ xglTexCoord2f(texCoord[n][0], texCoord[n][1]);
++ xglNormal3f(normals[n][0], normals[n][1], 0.6);
++ xglVertex3f(vertices[n][0], vertices[n][1], 0.0);
++ }
++ xglEnd();
++
++
++ if((shifted > (bottom - radius)) && (n1 < 1000) && (n1 > 0)){
++
++ a = sin(theta * DEG_TO_RAD) * sin(theta * DEG_TO_RAD);
++light_ambient2[0] = a;
++light_ambient2[1] = a;
++light_ambient2[2] = a;
++
++ xglLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient2);
++ xglLightfv(GL_LIGHT1, GL_DIFFUSE, light_ambient2);
++ xglLightfv(GL_LIGHT1, GL_SPECULAR, light_ambient2);
++
++ xglBegin(GL_TRIANGLES);
++
++ tmp1 = n1; tmp2 = n2;
++
++ for(i = tmp1; i < tmp2 + 1; i++){
++ n = i % 180;
++ xglNormal3f(0.0, 0.0, 1.5);
++ xglTexCoord2f((56 / 256), (140 / 256));
++ xglVertex3f(((vertices[n1 % 180][0] + vertices[n2 % 180][0]) / 2), ((vertices[n1 % 180][1] + vertices[n2 % 180][1]) / 2), 0.0);
++
++ xglTexCoord2f((57 / 256), (139 / 256));
++ xglNormal3f(normals[n][0], normals[n][1], normals[n][3]);
++ xglVertex3f(vertices[n][0], vertices[n][1], 0.0);
++
++ n = (i + 1) % 180;
++ xglTexCoord2f((57 / 256), (139 / 256));
++ xglNormal3f(normals[n][0], normals[n][1], normals[n][3]);
++ xglVertex3f(vertices[n][0], vertices[n][1], 0.0);
++ }
++ xglEnd();
++ }
++
++ if((shifted < (-top + radius)) && (n1 < 1000) && (n1 > 0)){
++ a = sin(theta * DEG_TO_RAD) * sin(theta * DEG_TO_RAD);
++light_ambient2[0] = a;
++light_ambient2[1] = a;
++light_ambient2[2] = a;
++
++ xglLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient2);
++ xglLightfv(GL_LIGHT1, GL_DIFFUSE, light_ambient2);
++ xglLightfv(GL_LIGHT1, GL_SPECULAR, light_ambient2);
++ xglMaterialf(GL_FRONT, GL_SHININESS, a * 85);
++ xglBegin(GL_TRIANGLES);
++ tmp1 = n1; tmp2 = n2;
++ for(i = tmp1; i <= tmp2; i++){
++ n = i % 180;
++ xglNormal3f(0.0, 0.0, 1.5);
++ xglTexCoord2f((73 / 256), (237 / 256));
++ xglVertex3f(((vertices[n1 % 180][0] + vertices[n2 % 180][0]) / 2), ((vertices[n1 % 180][1] + vertices[n2 % 180][1]) / 2), 0.0);
++
++ xglTexCoord2f((73 / 256), (236 / 256));
++ xglNormal3f(normals[n][0], normals[n][1], normals[n][2]);
++ xglVertex3f(vertices[n][0], vertices[n][1], 0.0);
++
++ n = (i + 1) % 180;
++ xglTexCoord2f((73 / 256), (236 / 256));
++ xglNormal3f(normals[n][0], normals[n][1], normals[n][2]);
++ xglVertex3f(vertices[n][0], vertices[n][1], 0.0);
++ }
++ xglEnd();
++ }
++
++ // Now we will have to draw the small triangle indicating the roll value
++
++ xglDisable(GL_LIGHTING);
++ xglDisable(GL_TEXTURE_2D);
++
++ xglRotatef(roll, 0.0, 0.0, 1.0);
++
++ xglBegin(GL_TRIANGLES);
++ xglColor3f(1.0, 1.0, 1.0);
++ xglVertex3f(0.0, radius, 0.0);
++ xglVertex3f(-3.0, (radius - 7.0), 0.0);
++ xglVertex3f(3.0, (radius - 7.0), 0.0);
++ xglEnd();
++
++ xglLoadIdentity();
++
++ xglBegin(GL_POLYGON);
++ xglColor3f(0.2109375, 0.23046875, 0.203125);
++ xglVertex2f(275.625, 138.0);
++ xglVertex2f(275.625, 148.125);
++ xglVertex2f(258.125, 151.25);
++ xglVertex2f(246.875, 151.25);
++ xglVertex2f(226.875, 147.5);
++ xglVertex2f(226.875, 138.0);
++ xglVertex2f(275.625, 138.0);
++ xglEnd();
++
++ xglLoadIdentity();
++
++ xglMatrixMode(GL_TEXTURE);
++ xglPopMatrix();
++ xglMatrixMode(GL_PROJECTION);
++ xglPopMatrix();
++ xglDisable(GL_TEXTURE_2D);
++ xglDisable(GL_NORMALIZE);
++ xglDisable(GL_LIGHTING);
++ xglDisable(GL_LIGHT1);
++ xglEnable(GL_LIGHT0);
++ }
++
++// fgHorizonInit - initialize values for the AH
++
++void FGHorizon::Init(void){
++ radius = 28.9;
++ texXPos = 56;
++ texYPos = 174;
++ bottom = 36.5;
++ top = 36.5;
++ int n;
++
++float step = (360*DEG_TO_RAD)/180;
++
++for(n=0;n<180;n++){
++ vertices[n][0] = cos(n * step) * radius;
++ vertices[n][1] = sin(n * step) * radius;
++ texCoord[n][0] = (cos(n * step) * radius)/256;
++ texCoord[n][1] = (sin(n * step) * radius)/256;
++ normals[n][0] = cos(n * step) * radius + sin(n * step);
++ normals[n][1] = sin(n * step) * radius + cos(n * step);
++ normals[n][2] = 0.0;
++ }
++}
++
++void FGTexInstrument::UpdatePointer(void){
++ double pitch;
++ double roll;
++ float alpharad;
++ double speed;
++ glEnableClientState(GL_VERTEX_ARRAY);
++ glVertexPointer(2, GL_FLOAT, 0, vertices);
++
++ alpha=((((float)((var[variable]) - (value1))) / (value2 - value1))* (alpha2 - alpha1) + alpha1);
++
++ if (alpha < alpha1)
++ alpha = alpha1;
++ if (alpha > alpha2)
++ alpha = alpha2;
++ xglMatrixMode(GL_MODELVIEW);
++ xglPushMatrix();
++ xglLoadIdentity();
++ xglDisable(GL_TEXTURE_2D);
++ xglTranslatef(XPos, YPos, 0);
++ xglRotatef(-alpha, 0.0, 0.0, 1.0);
++ xglColor4f(1.0, 1.0, 1.0, 1.0);
++ glDrawArrays(GL_POLYGON, 0, 10);
++ tape[0] = tape[1];
++ tape[1] = alpha;
++ xglEnable(GL_TEXTURE_2D);
++ glDisableClientState(GL_VERTEX_ARRAY);
++}
++
++// fgEraseArea - 'Erases' a drawn Polygon by overlaying it with a textured
++// area. Shall be a method of a panel class once.
++
++void fgEraseArea(GLfloat *array, int NumVerti, GLfloat texXPos, GLfloat texYPos, GLfloat XPos, GLfloat YPos, int Texid, float ScaleFactor){
++int i, j;
++int n;
++float a;
++float ififth;
++
++xglEnable(GL_TEXTURE_2D);
++xglEnable(GL_TEXTURE_GEN_S);
++xglEnable(GL_TEXTURE_GEN_T);
++glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
++glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
++xglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
++xglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
++xglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
++xglMatrixMode(GL_TEXTURE);
++xglLoadIdentity();
++
++ #ifdef GL_VERSION_1_1
++ xglBindTexture(GL_TEXTURE_2D, panel_tex_id[Texid]);
++ #elif GL_EXT_texture_object
++ xglBindTextureEXT(GL_TEXTURE_2D, panel_tex_id[Texid]);
++ #else
++ # error port me
++ #endif
++
++xglMatrixMode(GL_TEXTURE);
++xglLoadIdentity();
++xglTranslatef(-((float)((XPos/0.625)/256)), -((float)((YPos/0.625)/256)), 0.0);
++xglTranslatef(texXPos/256 , texYPos/256, 0.0);
++xglScalef(0.00625, 0.00625, 1.0);
++
++ xglBegin(GL_POLYGON);
++for(n=0;n<NumVerti;n += 2){
++xglVertex2f(array[n] * ScaleFactor, array[n + 1] * ScaleFactor);
++}
++ xglEnd();
++
++ xglLoadIdentity();
++ xglMatrixMode(GL_MODELVIEW);
++ xglPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
++ xglPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
++ xglDisable(GL_TEXTURE_2D);
++ xglDisable(GL_TEXTURE_GEN_S);
++ xglDisable(GL_TEXTURE_GEN_T);
++
++}
++
++// CreatePointer - calculate the vertices of a pointer
++
++void FGTexInstrument::CreatePointer(void){
++int i;
++float alpha;
++float alphastep;
++float r = radius;
++
++vertices[0] = 0;
++vertices[1] = length;
++vertices[2] = -(width/2);
++vertices[3] = length - ((width/2)/(tan(angle*DEG_TO_RAD/2)));
++vertices[4] = -(width/2);
++vertices[5] = cos(asin((width/2)/r))*r;
++
++alphastep = (asin((width/2)/r)+asin((width/2)/r))/5;
++alpha = asin(-(width/2)/r);
++
++for(i=0;i<5;i++){
++alpha += alphastep;
++vertices[(i*2)+6] = sin(alpha)*r;
++ }
++
++alpha = asin(-(width/2)/r);
++
++for(i=0;i<5;i++){
++alpha +=alphastep;
++vertices[(i*2)+7]= cos(alpha)*r;
++ }
++
++vertices[16] = - vertices[4];
++vertices[17] = vertices[5];
++vertices[18] = - vertices[2];
++vertices[19] = vertices[3];
++
++}
++
++// fgUpdateTurnCoordinator - draws turn coordinator related stuff
++
++void FGTurnCoordinator::Render(void){
++int n;
++
++xglDisable(GL_LIGHTING);
++xglDisable(GL_BLEND);
++xglEnable(GL_TEXTURE_2D);
++
++ alpha = (get_sideslip() / 1.5) * 560;
++ if(alpha > 56){
++ alpha = 56;
++ }
++ if(alpha < -56){
++ alpha = -56;
++ }
++
++ PlaneAlpha = get_roll();
++
++ xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
++ xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
++ xglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
++
++xglMatrixMode(GL_MODELVIEW);
++xglLoadIdentity();
++xglTranslatef(BallXPos, BallYPos, 0.0);
++xglTranslatef(0.75 * sin(alphahist[0] * DEG_TO_RAD) * 31, 0.3 * (39 - (cos(alphahist[0] * DEG_TO_RAD) * 39)), 0.0);
++fgEraseArea(vertices, 72, BallTexXPos + ((0.75 * sin(alphahist[0] * DEG_TO_RAD) * 31) / 0.625), BallTexYPos + ((0.3 * (39 - (cos(alphahist[0] * DEG_TO_RAD) * 39))) / 0.625), BallXPos + (0.75 * sin(alphahist[0] * DEG_TO_RAD) * 31), BallYPos + (0.3 * (39 - (cos(alphahist[0] * DEG_TO_RAD) * 39))), 1, 1);
++xglDisable(GL_TEXTURE_2D);
++xglEnable(GL_BLEND);
++xglBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE);
++xglMatrixMode(GL_MODELVIEW);
++xglLoadIdentity();
++xglTranslatef(BallXPos, BallYPos, 0.0);
++xglTranslatef(0.75 * sin(alpha * DEG_TO_RAD) * 31, 0.3 * (39 - (cos(alpha * DEG_TO_RAD) * 39)), 0.0);
++xglBegin(GL_POLYGON);
++xglColor3f(0.8, 0.8, 0.8);
++for(i=0;i<36;i++){
++xglVertex2f(vertices[2 * i], vertices[(2 * i) + 1]);
++}
++xglEnd();
++
++xglDisable(GL_TEXTURE_2D);
++xglDisable(GL_BLEND);
++
++xglMatrixMode(GL_MODELVIEW);
++xglLoadIdentity();
++xglTranslatef(XPos, YPos, 0.0);
++xglRotatef(rollhist[0] * RAD_TO_DEG + 90, 0.0, 0.0, 1.0);
++
++fgEraseArea(Wings, 8, PlaneTexXPos, PlaneTexYPos, XPos, YPos, 1, 1);
++fgEraseArea(Elevator, 8, PlaneTexXPos, PlaneTexYPos, XPos, YPos, 1, 1);
++fgEraseArea(Rudder, 8, PlaneTexXPos, PlaneTexYPos, XPos, YPos, 1, 1);
++
++xglLoadIdentity();
++xglTranslatef(XPos, YPos, 0.0);
++xglRotatef(-get_roll() * RAD_TO_DEG + 90, 0.0, 0.0, 1.0);
++
++xglBegin(GL_POLYGON);
++xglColor3f(1.0, 1.0, 1.0);
++for(i=0;i<90;i++){
++xglVertex2f(cos(i * 4 * DEG_TO_RAD) * 5, sin(i * 4 * DEG_TO_RAD) * 5);
++}
++xglEnd();
++
++xglBegin(GL_POLYGON);
++xglVertex2f(Wings[0], Wings[1]);
++xglVertex2f(Wings[2], Wings[3]);
++xglVertex2f(Wings[4], Wings[5]);
++xglVertex2f(Wings[6], Wings[7]);
++xglVertex2f(Wings[0], Wings[1]);
++xglEnd();
++
++xglBegin(GL_POLYGON);
++xglVertex2f(Elevator[0], Elevator[1]);
++xglVertex2f(Elevator[2], Elevator[3]);
++xglVertex2f(Elevator[4], Elevator[5]);
++xglVertex2f(Elevator[6], Elevator[7]);
++xglVertex2f(Elevator[0], Elevator[1]);
++xglEnd();
++
++xglBegin(GL_POLYGON);
++xglVertex2f(Rudder[0], Rudder[1]);
++xglVertex2f(Rudder[2], Rudder[3]);
++xglVertex2f(Rudder[4], Rudder[5]);
++xglVertex2f(Rudder[6], Rudder[7]);
++xglVertex2f(Rudder[0], Rudder[1]);
++xglEnd();
++
++
++alphahist[0] = alphahist[1];
++alphahist[1] = alpha;
++rollhist[0] = rollhist[1];
++rollhist[1] = -get_roll();
++
++xglDisable(GL_BLEND);
++}
++
++void FGTurnCoordinator::Init(void){
++int n;
++PlaneTexXPos = 49;
++PlaneTexYPos = 59.75;
++BallXPos = 145;
++BallYPos = 24;
++BallTexXPos = 49;
++BallTexYPos = 16;
++BallRadius = 3.5;
++
++for(n=0;n<36;n++){
++vertices[2 * n] = cos(10 * n * DEG_TO_RAD) * BallRadius;
++vertices[(2 * n) + 1] = sin(10 * n * DEG_TO_RAD) * BallRadius;
++ }
++}
++
++void DrawScale(float XPos, float YPos, float InnerRadius, float OuterRadius, float alpha1, float alpha2, int steps, float LineWidth, float red, float green, float blue, bool filled){
++ int i;
++ float diff = (alpha2 - alpha1) / (float)(steps - 1);
++
++ #define ANTIALIASED_INSTRUMENTS
++
++ #ifdef ANTIALIASED_INSTRUMENTS
++ xglEnable(GL_LINE_SMOOTH);
++ xglEnable(GL_BLEND);
++ xglHint(GL_LINE_SMOOTH_HINT, GL_FASTEST);
++ #endif
++
++ xglMatrixMode(GL_MODELVIEW);
++ xglLoadIdentity();
++
++ xglTranslatef(XPos, YPos, 0.0);
++ xglRotatef(-alpha1, 0.0, 0.0, 1.0);
++
++ xglLineWidth(LineWidth);
++ xglColor3f(red, green, blue);
++
++ if(!filled){
++ xglBegin(GL_LINES);
++ }
++ else{
++ xglBegin(GL_QUAD_STRIP);
++ }
++
++ for(i=0;i < steps; i++){
++ xglVertex3f(sin(i * diff * DEG_TO_RAD) * OuterRadius, cos(i * diff * DEG_TO_RAD) * OuterRadius, 0.0);
++ xglVertex3f(sin(i * diff * DEG_TO_RAD) * InnerRadius, cos(i * diff * DEG_TO_RAD) * InnerRadius, 0.0);
++ }
++ xglEnd();
++
++ xglLoadIdentity();
++ xglDisable(GL_LINE_SMOOTH);
++ xglDisable(GL_BLEND);
++ }
++
++void DrawBeechcraftLogo(float XPos, float YPos, float width, float height){
++ xglMatrixMode(GL_MODELVIEW);
++ xglLoadIdentity();
++ xglTranslatef(XPos, YPos, 0.0);
++ xglEnable(GL_BLEND);
++ xglEnable(GL_TEXTURE_2D);
++// xglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
++// xglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
++
++ #ifdef GL_VERSION_1_1
++ xglBindTexture(GL_TEXTURE_2D, panel_tex_id[1]);
++ #elif GL_EXT_texture_object
++ xglBindTextureEXT(GL_TEXTURE_2D, panel_tex_id[1]);
++ #else
++ # error port me
++ #endif
++
++ xglBegin(GL_POLYGON);
++
++ xglTexCoord2f(.39844, .01953);
++ xglVertex2f(0.0, 0.0);
++ xglTexCoord2f(.58594, .01953);
++ xglVertex2f(width, 0.0);
++ xglTexCoord2f(.58594, .074219);
++ xglVertex2f(width, height);
++ xglTexCoord2f(.39844, .074219);
++ xglVertex2f(0.0, height);
++
++ xglEnd();
++
++ xglDisable(GL_BLEND);
++ xglDisable(GL_TEXTURE_2D);
++ }
++
++
++// PrintMatrix - routine to print the current modelview matrix.
++
++void PrintMatrix( void){
++xglGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix);
++printf("matrix2 = %f %f %f %f \n", mvmatrix[0], mvmatrix[1], mvmatrix[2], mvmatrix[3]);
++printf(" %f %f %f %f \n", mvmatrix[4], mvmatrix[5], mvmatrix[6], mvmatrix[7]);
++printf(" %f %f %f %f \n", mvmatrix[8], mvmatrix[9], mvmatrix[10], mvmatrix[11]);
++printf(" %f %f %f %f \n", mvmatrix[12], mvmatrix[13], mvmatrix[14], mvmatrix[15]);
++}
++
++void FGRpmGauge::Init(void){
++ list = xglGenLists (1);
++ int n;
++
++ xglNewList(list, GL_COMPILE);
++
++ xglColor3f(.26, .289, .3281);
++ xglBegin(GL_POLYGON);
++ for(n = 0; n < 180; n++){
++ xglVertex2f(cos(n * 0.0349066) * 24.5, sin(n * 0.0349066) * 24.5);
++ }
++ xglEnd();
++
++DrawScale(XPos, YPos, 22.5, 25.625, 50, 135, 10, 1.0, 0.0, 0.7, 0.0,FILLED);
++DrawScale(XPos, YPos, 21.0, 25.625, -70, 180, 8, 1.8, 0.88, 0.88, 0.88, false);
++DrawScale(XPos, YPos, 22.5, 25.0, -70, 180, 40, 0.6, 0.5, 0.5, 0.5, false);
++
++ xglEndList();
++ }
++
++void FGRpmGauge::Render(void){
++ xglMatrixMode(GL_MODELVIEW);
++ xglLoadIdentity();
++ xglTranslatef(XPos, YPos, 0.0);
++
++ xglCallList(list);
++
++ }
++
++void FGPanel::DrawTestLetter(float X, float Y){
++ xglEnable(GL_TEXTURE_2D);
++ xglEnable(GL_BLEND);
++
++ xglMatrixMode(GL_TEXTURE);
++ xglLoadIdentity();
++ xglTranslatef(X, Y, 0.0);
++
++ DrawLetter();
++
++ xglMatrixMode(GL_MODELVIEW);
++ xglTranslatef(6.0, 0.0, 0.0);
++ xglDisable(GL_TEXTURE_2D);
++ xglDisable(GL_BLEND);
++ }
++
++void FGPanel::InitLists(void){
++ xglNewList(FontList + 'A', GL_COMPILE);
++ DrawTestLetter(0.391625, 0.29296875);
++ xglEndList();
++
++ xglNewList(FontList + 'B', GL_COMPILE);
++ DrawTestLetter(0.391625 + 1 * LETTER_OFFSET, 0.29296875);
++ xglEndList();
++
++ xglNewList(FontList + 'C', GL_COMPILE);
++ DrawTestLetter(0.391625 + 2 * LETTER_OFFSET, 0.29296875);
++ xglEndList();
++
++ xglNewList(FontList + 'D', GL_COMPILE);
++ DrawTestLetter(0.391625 + 3 * LETTER_OFFSET, 0.29296875);
++ xglEndList();
++
++ xglNewList(FontList + 'E', GL_COMPILE);
++ DrawTestLetter(0.391625 + 4 * LETTER_OFFSET, 0.29296875);
++ xglEndList();
++
++ xglNewList(FontList + 'F', GL_COMPILE);
++ DrawTestLetter(0.391625 + 5 * LETTER_OFFSET, 0.29296875);
++ xglEndList();
++
++ xglNewList(FontList + 'G', GL_COMPILE);
++ DrawTestLetter(0.391625 + 6 * LETTER_OFFSET, 0.29296875);
++ xglEndList();
++
++ xglNewList(FontList + 'H', GL_COMPILE);
++ DrawTestLetter(0.391625 + 7 * LETTER_OFFSET, 0.29296875);
++ xglEndList();
++
++ xglNewList(FontList + 'I', GL_COMPILE);
++ DrawTestLetter(0.391625 + 8 * LETTER_OFFSET, 0.29296875);
++ xglEndList();
++
++ xglNewList(FontList + 'J', GL_COMPILE);
++ DrawTestLetter(0.391625 + 9 * LETTER_OFFSET, 0.29296875);
++ xglEndList();
++
++ xglNewList(FontList + 'K', GL_COMPILE);
++ DrawTestLetter(0.391625 + 9.7 * LETTER_OFFSET, 0.29296875);
++ xglEndList();
++
++ xglNewList(FontList + 'L', GL_COMPILE);
++ DrawTestLetter(0.399625 + 10.6 * LETTER_OFFSET, 0.29296875);
++ xglEndList();
++
++ xglNewList(FontList + 'M', GL_COMPILE);
++ DrawTestLetter(0.80459375, 0.29296875);
++ xglEndList();
++
++ xglNewList(FontList + 'N', GL_COMPILE);
++ DrawTestLetter(0.83975, 0.29296875);
++ xglEndList();
++
++ xglNewList(FontList + 'O', GL_COMPILE);
++ DrawTestLetter(0.871, 0.29296875);
++ xglEndList();
++
++ xglNewList(FontList + 'P', GL_COMPILE);
++ DrawTestLetter(0.90715625, 0.29296875);
++ xglEndList();
++
++ xglNewList(FontList + 'Q', GL_COMPILE);
++ DrawTestLetter(0.9413125, 0.29296875);
++ xglEndList();
++
++ xglNewList(FontList + '1', GL_COMPILE);
++ DrawTestLetter(0.390625, 0.35546875);
++ xglEndList();
++
++ xglNewList(FontList + '2', GL_COMPILE);
++ DrawTestLetter(0.390625 + 1*LETTER_OFFSET, 0.3515625);
++ xglEndList();
++
++ xglNewList(FontList + '3', GL_COMPILE);
++ DrawTestLetter(0.390625 + 2*LETTER_OFFSET, 0.3515625);
++ xglEndList();
++
++ xglNewList(FontList + '4', GL_COMPILE);
++ DrawTestLetter(0.390625 + 3*LETTER_OFFSET, 0.3515625);
++ xglEndList();
++
++ xglNewList(FontList + '5', GL_COMPILE);
++ DrawTestLetter(0.390625 + 4*LETTER_OFFSET, 0.3515625);
++ xglEndList();
++
++ xglNewList(FontList + '6', GL_COMPILE);
++ DrawTestLetter(0.390625 + 5*LETTER_OFFSET, 0.3515625);
++ xglEndList();
++
++ xglNewList(FontList + '7', GL_COMPILE);
++ DrawTestLetter(0.390625 + 6*LETTER_OFFSET, 0.3515625);
++ xglEndList();
++
++ xglNewList(FontList + '8', GL_COMPILE);
++ DrawTestLetter(0.390625 + 7*LETTER_OFFSET, 0.3515625);
++ xglEndList();
++
++ xglNewList(FontList + '9', GL_COMPILE);
++ DrawTestLetter(0.390625 + 8*LETTER_OFFSET, 0.3515625);
++ xglEndList();
++
++ xglNewList(FontList + '0', GL_COMPILE);
++ DrawTestLetter(0.383625 + 9*LETTER_OFFSET, 0.3515625);
++ xglEndList();
++
++ xglNewList(FontList + ' ', GL_COMPILE);
++ xglTranslatef(8.0, 0.0, 0.0);
++ xglEndList();
++ }
++
++void FGPanel::TexString(char *s, float XPos, float YPos, float size){
++ xglMatrixMode(GL_MODELVIEW);
++ xglLoadIdentity();
++ xglTranslatef(XPos, YPos, 0.0);
++ xglScalef(size, size, 1.0);
++
++ #ifdef GL_VERSION_1_1
++ xglBindTexture(GL_TEXTURE_2D, panel_tex_id[1]);
++ #elif GL_EXT_texture_object
++ xglBindTextureEXT(GL_TEXTURE_2D, panel_tex_id[1]);
++ #else
++ # error port me
++ #endif
++
++ while((*s) != '\0'){
++ xglCallList(FontList + (*s));
++ s++;
++ }
++ xglLoadIdentity();
++ }
++
++void FGTexInstrument::Init(void){
++ CreatePointer();
++ }
++
++void FGTexInstrument::Render(void){
++xglEnable(GL_TEXTURE_2D);
++ xglLoadIdentity();
++ xglTranslatef(XPos, YPos, 0.0);
++ xglRotatef(-tape[0], 0.0, 0.0, 1.0);
++ fgEraseArea(vertices, 20, (GLfloat)(teXpos), (GLfloat)(texYpos), (GLfloat)(XPos), (GLfloat)(YPos), 0, 1);
++
++ UpdatePointer();
++
++ xglDisable(GL_TEXTURE_2D);
++ }
++
++// $Log$
++// Revision 1.18 1999/03/09 20:58:17 curt
++// Tweaks for compiling under native Irix compilers.
++//
++// Revision 1.17 1999/03/08 21:56:09 curt
++// Added panel changes sent in by Friedemann.
++//
++// Revision 1.13 1999/01/07 19:25:53 curt
++// Updates from Friedemann Reinhard.
++//
++// Revision 1.11 1998/11/11 00:19:27 curt
++// Updated comment delimeter to C++ style.
++//
++// Revision 1.10 1998/11/09 23:38:52 curt
++// Panel updates from Friedemann.
++//
++// Revision 1.9 1998/11/06 21:18:01 curt
++// Converted to new logstream debugging facility. This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.8 1998/10/16 23:27:37 curt
++// C++-ifying.
++//
++// Revision 1.7 1998/08/31 20:45:31 curt
++// Tweaks from Friedemann.
++//
++// Revision 1.6 1998/08/28 18:14:40 curt
++// Added new cockpit code from Friedemann Reinhard
++// <mpt218@faupt212.physik.uni-erlangen.de>
++//
++// Revision 1.1 1998/06/27 16:47:54 curt
++// Incorporated Friedemann Reinhard's <mpt218@faupt212.physik.uni-erlangen.de>
++// first pass at an isntrument panel.
++//
++
++
--- /dev/null
--- /dev/null
++// panel.hxx -- instrument panel defines and prototypes
++//
++// Written by Friedemann Reinhard, started June 1998.
++//
++// 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$
++// (Log is kept at end of this file)
++
++#define LETTER_OFFSET 0.03515625
++
++#ifndef _PANEL_HXX
++#define _PANEL_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++class FGInstrument;
++
++class FGPanel{
++
++private:
++int height, width;
++GLuint FontList;
++
++GLubyte *background;
++
++// FGInstrument **instr_list;
++FGInstrument *test_instr[7];
++
++void GetData(void);
++
++public:
++static FGPanel *OurPanel;
++
++ FGPanel(void);
++
++float get_height(void){
++ return height;
++ }
++
++void ReInit( int x, int y, int finx, int finy);
++void Update(void);
++
++void DrawLetter(void){
++ glBegin(GL_POLYGON);
++ glTexCoord2f(0.0, 0.0);
++ glVertex2f(0.0, 0.0);
++ glTexCoord2f(LETTER_OFFSET + 0.004, 0.0);
++ glVertex2f(7.0, 0.0);
++ glTexCoord2f(LETTER_OFFSET + 0.004, 0.0390625);
++ glVertex2f(7.0, 9.0);
++ glTexCoord2f(0.0, 0.0390625);
++ glVertex2f(0.0, 9.0);
++ glEnd();
++ }
++
++void DrawTestLetter(float X, float Y);
++void InitLists(void);
++void TexString(char *s, float XPos, float YPos, float size);
++
++};
++
++class FGInstrument{
++friend class FGPanel;
++
++protected:
++float XPos, YPos;
++
++public:
++ FGInstrument(void){
++ }
++
++ virtual ~FGInstrument(void){}
++
++virtual void Init(void) = 0;
++virtual void Render(void) = 0;
++};
++
++class FGHorizon : public FGInstrument {
++private:
++ float texXPos;
++ float texYPos;
++ float radius;
++ float bottom; // tell the program the offset between midpoint and bottom
++ float top; // guess what ;-)
++ float vertices[180][2];
++ float normals[180][3];
++ float texCoord[180][2];
++
++public:
++ FGHorizon(void){
++ XPos = 0.0; YPos = 0.0;
++ Init();
++ }
++
++ FGHorizon(float inXPos, float inYPos){
++ XPos = inXPos; YPos = inYPos;
++ Init();
++ }
++
++virtual void Init(void);
++virtual void Render(void);
++
++};
++
++class FGTurnCoordinator : public FGInstrument {
++private:
++ float PlaneTexXPos;
++ float PlaneTexYPos;
++ float alpha;
++ float PlaneAlpha;
++ float alphahist[2];
++ float rollhist[2];
++ float BallXPos;
++ float BallYPos;
++ float BallTexXPos;
++ float BallTexYPos;
++ float BallRadius;
++ GLfloat vertices[72];
++
++public:
++ FGTurnCoordinator(void){
++ XPos = 0.0; YPos = 0.0;
++ Init();
++ }
++
++ FGTurnCoordinator(float inXPos, float inYPos){
++ XPos = inXPos; YPos = inYPos;
++ Init();
++ }
++
++virtual void Init (void);
++virtual void Render(void);
++
++};
++
++class FGRpmGauge : public FGInstrument {
++private:
++ GLuint list;
++
++public:
++ FGRpmGauge(void){
++ XPos = 0.0; YPos = 0.0;
++ Init();
++ }
++
++ FGRpmGauge(float inXPos, float inYPos){
++ XPos = inXPos; YPos = inYPos;
++ Init();
++ }
++
++virtual void Init(void);
++virtual void Render(void);
++};
++
++// temporary class until I get the software-only routines for the
++// instruments run
++
++class FGTexInstrument : public FGInstrument {
++
++private:
++ float radius;
++ float length;
++ float width;
++ float angle;
++ float tape[2];
++ float value1;
++ float value2;
++ float alpha1;
++ float alpha2;
++ float teXpos;
++ float texYpos;
++ int variable;
++ GLfloat vertices[20];
++
++public:
++ FGTexInstrument(void){
++ XPos = 0.0; YPos = 0.0;
++ Init();
++ }
++
++ FGTexInstrument(float inXPos, float inYPos, float inradius, float inlength, float inwidth, float inangle, float invalue1, float invalue2, float inalpha1, float inalpha2, float intexXPos, float intexYPos, int invariable){
++
++ XPos = inXPos; YPos = inYPos;
++ radius = inradius; angle = inangle;
++ length = inlength; width = inwidth;
++ value1 = invalue1; value2 = invalue2;
++ alpha1 = inalpha1; alpha2 = inalpha2;
++ teXpos = intexXPos; texYpos = intexYPos;
++ variable = invariable;
++ Init();
++ }
++
++ void CreatePointer(void);
++ void UpdatePointer(void);
++
++ void Init(void);
++ void Render(void);
++};
++
++typedef struct{
++float XPos;
++float YPos;
++ float radius;
++ float length;
++ float width;
++ float angle;
++ float tape[2];
++ float value1;
++ float value2;
++ float alpha1;
++ float alpha2;
++ float teXpos;
++ float texYpos;
++ int variable;
++ GLfloat vertices[20];
++}Pointer;
++
++void fgEraseArea(GLfloat *array, int NumVerti, GLfloat texXPos, GLfloat texYPos, GLfloat XPos, GLfloat YPos, int Texid, float ScaleFactor);
++void DrawScale(float XPos, float YPos, float InnerRadius, float OuterRadius, float alpha1, float alpha2, int steps, float LineWidth, float red, float green, float blue, bool filled);
++void DrawBeechcraftLogo(float XPos, float YPos, float Width, float Height);
++
++void PrintMatrix( void);
++
++#endif // _PANEL_HXX
++
++
++
++// $Log$
++// Revision 1.9 1999/03/09 20:58:18 curt
++// Tweaks for compiling under native Irix compilers.
++//
++// Revision 1.8 1999/03/08 21:56:10 curt
++// Added panel changes sent in by Friedemann.
++//
++// Revision 1.5 1999/01/07 19:25:55 curt
++// Updates from Friedemann Reinhard.
++//
++// Revision 1.4 1998/11/11 00:19:29 curt
++// Updated comment delimeter to C++ style.
++//
++// Revision 1.3 1998/11/09 23:38:54 curt
++// Panel updates from Friedemann.
++//
++// Revision 1.2 1998/08/28 18:14:41 curt
++// Added new cockpit code from Friedemann Reinhard
++// <mpt218@faupt212.physik.uni-erlangen.de>
++//
++// Revision 1.1 1998/06/27 16:47:55 curt
++// Incorporated Friedemann Reinhard's <mpt218@faupt212.physik.uni-erlangen.de>
++// first pass at an isntrument panel.
++
++
--- /dev/null
--- /dev/null
++noinst_LIBRARIES = libControls.a
++
++libControls_a_SOURCES = controls.cxx controls.hxx
++
++INCLUDES += -I$(top_builddir) -I$(top_builddir)/Simulator
--- /dev/null
--- /dev/null
++// controls.cxx -- defines a standard interface to all flight sim controls
++//
++// Written by Curtis Olson, started May 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$
++// (Log is kept at end of this file)
++
++
++#include "controls.hxx"
++
++
++FGControls controls;
++
++
++// Constructor
++FGControls::FGControls() :
++ aileron( 0.0 ),
++ elevator( 0.0 ),
++ elevator_trim( 1.969572E-03 ),
++ rudder( 0.0 )
++{
++ for ( int engine = 0; engine < MAX_ENGINES; engine++ ) {
++ throttle[engine] = 0.0;
++ }
++
++ for ( int wheel = 0; wheel < MAX_WHEELS; wheel++ ) {
++ brake[wheel] = 0.0;
++ }
++}
++
++
++// Destructor
++FGControls::~FGControls() {
++}
++
++
++// $Log$
++// Revision 1.3 1998/12/05 16:13:12 curt
++// Renamed class fgCONTROLS to class FGControls.
++//
++// Revision 1.2 1998/10/25 14:08:41 curt
++// Turned "struct fgCONTROLS" into a class, with inlined accessor functions.
++//
++// Revision 1.1 1998/10/18 01:51:05 curt
++// c++-ifying ...
++//
++// Revision 1.8 1998/09/29 02:01:31 curt
++// Added a brake.
++//
++// Revision 1.7 1998/02/07 15:29:36 curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.6 1998/01/19 19:27:02 curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.5 1998/01/19 18:40:22 curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.4 1997/12/10 22:37:41 curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.3 1997/08/27 03:30:01 curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.2 1997/06/21 17:12:48 curt
++// Capitalized subdirectory names.
++//
++// Revision 1.1 1997/05/31 19:24:04 curt
++// Initial revision.
++//
++
--- /dev/null
--- /dev/null
++// controls.hxx -- defines a standard interface to all flight sim controls
++//
++// Written by Curtis Olson, started May 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$
++// (Log is kept at end of this file)
++
++
++#ifndef _CONTROLS_HXX
++#define _CONTROLS_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++
++// Define a structure containing the control parameters
++
++class FGControls {
++
++public:
++
++ enum
++ {
++ ALL_ENGINES = -1,
++ MAX_ENGINES = 10
++ };
++
++ enum
++ {
++ ALL_WHEELS = -1,
++ MAX_WHEELS = 3
++ };
++
++private:
++
++ double aileron;
++ double elevator;
++ double elevator_trim;
++ double rudder;
++ double throttle[MAX_ENGINES];
++ double brake[MAX_WHEELS];
++
++public:
++
++ FGControls();
++ ~FGControls();
++
++ // Query functions
++ inline double get_aileron() const { return aileron; }
++ inline double get_elevator() const { return elevator; }
++ inline double get_elevator_trim() const { return elevator_trim; }
++ inline double get_rudder() const { return rudder; }
++ inline double get_throttle(int engine) const { return throttle[engine]; }
++ inline double get_brake(int wheel) const { return brake[wheel]; }
++
++ // Update functions
++ inline void set_aileron( double pos ) {
++ aileron = pos;
++ if ( aileron < -1.0 ) aileron = -1.0;
++ if ( aileron > 1.0 ) aileron = 1.0;
++ }
++ inline void move_aileron( double amt ) {
++ aileron += amt;
++ if ( aileron < -1.0 ) aileron = -1.0;
++ if ( aileron > 1.0 ) aileron = 1.0;
++ }
++ inline void set_elevator( double pos ) {
++ elevator = pos;
++ if ( elevator < -1.0 ) elevator = -1.0;
++ if ( elevator > 1.0 ) elevator = 1.0;
++ }
++ inline void move_elevator( double amt ) {
++ elevator += amt;
++ if ( elevator < -1.0 ) elevator = -1.0;
++ if ( elevator > 1.0 ) elevator = 1.0;
++ }
++ inline void set_elevator_trim( double pos ) {
++ elevator_trim = pos;
++ if ( elevator_trim < -1.0 ) elevator_trim = -1.0;
++ if ( elevator_trim > 1.0 ) elevator_trim = 1.0;
++ }
++ inline void move_elevator_trim( double amt ) {
++ elevator_trim += amt;
++ if ( elevator_trim < -1.0 ) elevator_trim = -1.0;
++ if ( elevator_trim > 1.0 ) elevator_trim = 1.0;
++ }
++ inline void set_rudder( double pos ) {
++ rudder = pos;
++ if ( rudder < -1.0 ) rudder = -1.0;
++ if ( rudder > 1.0 ) rudder = 1.0;
++ }
++ inline void move_rudder( double amt ) {
++ rudder += amt;
++ if ( rudder < -1.0 ) rudder = -1.0;
++ if ( rudder > 1.0 ) rudder = 1.0;
++ }
++ inline void set_throttle( int engine, double pos ) {
++ if ( engine == ALL_ENGINES ) {
++ for ( int i = 0; i < MAX_ENGINES; i++ ) {
++ throttle[i] = pos;
++ if ( throttle[i] < 0.0 ) throttle[i] = 0.0;
++ if ( throttle[i] > 1.0 ) throttle[i] = 1.0;
++ }
++ } else {
++ if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
++ throttle[engine] = pos;
++ if ( throttle[engine] < 0.0 ) throttle[engine] = 0.0;
++ if ( throttle[engine] > 1.0 ) throttle[engine] = 1.0;
++ }
++ }
++ }
++ inline void move_throttle( int engine, double amt ) {
++ if ( engine == ALL_ENGINES ) {
++ for ( int i = 0; i < MAX_ENGINES; i++ ) {
++ throttle[i] += amt;
++ if ( throttle[i] < 0.0 ) throttle[i] = 0.0;
++ if ( throttle[i] > 1.0 ) throttle[i] = 1.0;
++ }
++ } else {
++ if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
++ throttle[engine] += amt;
++ if ( throttle[engine] < 0.0 ) throttle[engine] = 0.0;
++ if ( throttle[engine] > 1.0 ) throttle[engine] = 1.0;
++ }
++ }
++ }
++ inline void set_brake( int wheel, double pos ) {
++ if ( wheel == ALL_WHEELS ) {
++ for ( int i = 0; i < MAX_WHEELS; i++ ) {
++ brake[i] = pos;
++ if ( brake[i] < 0.0 ) brake[i] = 0.0;
++ if ( brake[i] > 1.0 ) brake[i] = 1.0;
++ }
++ } else {
++ if ( (wheel >= 0) && (wheel < MAX_WHEELS) ) {
++ brake[wheel] = pos;
++ if ( brake[wheel] < 0.0 ) brake[wheel] = 0.0;
++ if ( brake[wheel] > 1.0 ) brake[wheel] = 1.0;
++ }
++ }
++ }
++ inline void move_brake( int wheel, double amt ) {
++ if ( wheel == ALL_WHEELS ) {
++ for ( int i = 0; i < MAX_WHEELS; i++ ) {
++ brake[i] += amt;
++ if ( brake[i] < 0.0 ) brake[i] = 0.0;
++ if ( brake[i] > 1.0 ) brake[i] = 1.0;
++ }
++ } else {
++ if ( (wheel >= 0) && (wheel < MAX_WHEELS) ) {
++ brake[wheel] += amt;
++ if ( brake[wheel] < 0.0 ) brake[wheel] = 0.0;
++ if ( brake[wheel] > 1.0 ) brake[wheel] = 1.0;
++ }
++ }
++ }
++};
++
++
++extern FGControls controls;
++
++
++#endif // _CONTROLS_HXX
++
++
++// $Log$
++// Revision 1.4 1999/01/27 04:48:13 curt
++// C++ style refinements by Bernie Bright.
++//
++// Revision 1.3 1998/12/05 16:13:13 curt
++// Renamed class fgCONTROLS to class FGControls.
++//
++// Revision 1.2 1998/10/25 14:08:42 curt
++// Turned "struct fgCONTROLS" into a class, with inlined accessor functions.
++//
++// Revision 1.1 1998/10/18 01:51:07 curt
++// c++-ifying ...
++//
++// Revision 1.17 1998/09/29 14:57:00 curt
++// c++-ified some comments.
++//
++// Revision 1.16 1998/09/29 02:01:32 curt
++// Added a brake.
++//
++// Revision 1.15 1998/04/25 22:06:27 curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.14 1998/04/22 13:26:19 curt
++// C++ - ifing the code a bit.
++//
++// Revision 1.13 1998/04/21 17:02:35 curt
++// Prepairing for C++ integration.
++//
++// Revision 1.12 1998/02/09 22:56:48 curt
++// Removed "depend" files from cvs control. Other minor make tweaks.
++//
++// Revision 1.11 1998/02/07 15:29:36 curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.10 1998/01/27 00:47:52 curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.9 1998/01/22 02:59:31 curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.8 1998/01/19 18:40:22 curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.7 1997/12/15 23:54:36 curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.6 1997/12/10 22:37:41 curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.5 1997/08/27 03:30:02 curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.4 1997/07/23 21:52:18 curt
++// Put comments around the text after an #endif for increased portability.
++//
++// Revision 1.3 1997/05/31 19:16:27 curt
++// Elevator trim added.
++//
++// Revision 1.2 1997/05/23 15:40:33 curt
++// Added GNU copyright headers.
++//
++// Revision 1.1 1997/05/16 15:59:48 curt
++// Initial revision.
++//
--- /dev/null
--- /dev/null
++noinst_LIBRARIES = libExternal.a
++
++libExternal_a_SOURCES = external.cxx external.hxx
++
++INCLUDES += -I$(top_builddir) -I$(top_builddir)/Simulator
--- /dev/null
--- /dev/null
++// external.cxx -- externally driven flight model
++//
++// Written by Curtis Olson, started January 1998.
++//
++// Copyright (C) 1998 Curtis L. Olson - curt@flightgear.org
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#include <math.h>
++
++#include "external.hxx"
++
++#include <FDM/flight.hxx>
++#include <Include/fg_constants.h>
++
++
++// reset flight params to a specific position
++void fgExternalInit( FGInterface &f ) {
++}
++
++
++// update position based on inputs, positions, velocities, etc.
++void fgExternalUpdate( FGInterface& f, int multiloop ) {
++
++}
++
++
++// $Log$
++// Revision 1.5 1999/02/05 21:29:03 curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.4 1999/02/01 21:33:32 curt
++// Renamed FlightGear/Simulator/Flight to FlightGear/Simulator/FDM since
++// Jon accepted my offer to do this and thought it was a good idea.
++//
++// Revision 1.3 1999/01/19 17:52:11 curt
++// Working on being able to extrapolate a new position and orientation
++// based on a position, orientation, and time offset.
++//
++// Revision 1.2 1998/12/05 15:54:13 curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.1 1998/12/04 01:28:49 curt
++// Initial revision.
++//
--- /dev/null
--- /dev/null
++// external.hxx -- the "external" flight model (driven from other
++// external input)
++//
++// Written by Curtis Olson, started December 1998.
++//
++// Copyright (C) 1998 Curtis L. Olson - curt@flightgear.org
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#ifndef _EXTERNAL_HXX
++#define _EXTERNAL_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++
++#include <Time/fg_time.hxx>
++#include <Time/timestamp.hxx>
++
++
++/*
++class fgFDM_EXTERNAL {
++
++public:
++
++ // Time Stamp
++
++ // The time at which these values are correct (for extrapolating
++ // later frames between position updates)
++ FGTimeStamp t;
++
++ // Positions
++
++ // placement in geodetic coordinates
++ double Latitude;
++ double Longitude;
++ double Altitude;
++
++ // orientation in euler angles relative to local frame (or ground
++ // position)
++ double Phi; // roll
++ double Theta; // pitch
++ double Psi; // heading
++
++ // Velocities
++
++ // velocities in geodetic coordinates
++ double Latitude_dot; // rad/sec
++ double Longitude_dot; // rad/sec
++ double Altitude_dot; // feet/sec
++
++ // rotational rates
++ double Phi_dot;
++ double Theta_dot;
++ double Psi_dot;
++};
++*/
++
++
++// reset flight params to a specific position
++void fgExternalInit( FGInterface& f );
++
++
++#endif // _EXTERNAL_HXX
++
++
++// $Log$
++// Revision 1.6 1999/02/05 21:29:04 curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.5 1999/01/19 17:52:12 curt
++// Working on being able to extrapolate a new position and orientation
++// based on a position, orientation, and time offset.
++//
++// Revision 1.4 1999/01/09 13:37:37 curt
++// Convert fgTIMESTAMP to FGTimeStamp which holds usec instead of ms.
++//
++// Revision 1.3 1998/12/05 15:54:14 curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.2 1998/12/05 14:18:47 curt
++// added an fgTIMESTAMP to define when this record is valid.
++//
++// Revision 1.1 1998/12/04 01:28:49 curt
++// Initial revision.
++//
--- /dev/null
--- /dev/null
++// JSBsim.cxx -- interface to the JSBsim flight model
++//
++// Written by Curtis Olson, started February 1999.
++//
++// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#include <Include/compiler.h>
++
++#include STL_STRING
++
++#include <Aircraft/aircraft.hxx>
++#include <Controls/controls.hxx>
++#include <Debug/logstream.hxx>
++#include <Include/fg_constants.h>
++#include <Main/options.hxx>
++#include <Math/fg_geodesy.hxx>
++
++#include <FDM/JSBsim/FGFDMExec.h>
++#include <FDM/JSBsim/FGAircraft.h>
++#include <FDM/JSBsim/FGFCS.h>
++#include <FDM/JSBsim/FGPosition.h>
++#include <FDM/JSBsim/FGRotation.h>
++#include <FDM/JSBsim/FGState.h>
++#include <FDM/JSBsim/FGTranslation.h>
++
++#include "JSBsim.hxx"
++
++
++// The default aircraft
++FGFDMExec FDMExec;
++
++
++// Initialize the JSBsim flight model, dt is the time increment for
++// each subsequent iteration through the EOM
++int fgJSBsimInit(double dt) {
++ FG_LOG( FG_FLIGHT, FG_INFO, "Starting initializing JSBsim" );
++
++ FG_LOG( FG_FLIGHT, FG_INFO, " created FDMExec" );
++
++ string aircraft_path = current_options.get_fg_root() + "/Aircraft";
++ string engine_path = current_options.get_fg_root() + "/Engine";
++
++ FDMExec.GetAircraft()->LoadAircraft(aircraft_path, engine_path, "X15");
++ FG_LOG( FG_FLIGHT, FG_INFO, " loaded aircraft" );
++
++ FDMExec.GetState()->Reset(aircraft_path, "Reset00");
++ FG_LOG( FG_FLIGHT, FG_INFO, " loaded initial conditions" );
++
++ FDMExec.GetState()->Setdt(dt);
++ FG_LOG( FG_FLIGHT, FG_INFO, " set dt" );
++
++ FG_LOG( FG_FLIGHT, FG_INFO, "Finished initializing JSBsim" );
++
++ return 1;
++}
++
++
++// Run an iteration of the EOM (equations of motion)
++int fgJSBsimUpdate(FGInterface& f, int multiloop) {
++ double save_alt = 0.0;
++
++ // lets try to avoid really screwing up the JSBsim model
++ if ( f.get_Altitude() < -9000 ) {
++ save_alt = f.get_Altitude();
++ f.set_Altitude( 0.0 );
++ }
++
++ // copy control positions into the JSBsim structure
++ FDMExec.GetFCS()->SetDa( controls.get_aileron() );
++ FDMExec.GetFCS()->SetDe( controls.get_elevator()
++ + controls.get_elevator_trim() );
++ FDMExec.GetFCS()->SetDr( controls.get_rudder() );
++ FDMExec.GetFCS()->SetDf( 0.0 );
++ FDMExec.GetFCS()->SetDs( 0.0 );
++ FDMExec.GetFCS()->SetThrottle( FGControls::ALL_ENGINES,
++ controls.get_throttle( 0 ) );
++ // FCS->SetBrake( controls.get_brake( 0 ) );
++
++ // Inform JSBsim of the local terrain altitude
++ // Runway_altitude = f.get_Runway_altitude();
++
++ // old -- FGInterface_2_JSBsim() not needed except for Init()
++ // translate FG to JSBsim structure
++ // FGInterface_2_JSBsim(f);
++ // printf("FG_Altitude = %.2f\n", FG_Altitude * 0.3048);
++ // printf("Altitude = %.2f\n", Altitude * 0.3048);
++ // printf("Radius to Vehicle = %.2f\n", Radius_to_vehicle * 0.3048);
++
++ /* FDMExec.GetState()->Setsim_time(State->Getsim_time()
++ + State->Getdt() * multiloop); */
++
++ for ( int i = 0; i < multiloop; i++ ) {
++ FDMExec.Run();
++ }
++
++ // printf("%d FG_Altitude = %.2f\n", i, FG_Altitude * 0.3048);
++ // printf("%d Altitude = %.2f\n", i, Altitude * 0.3048);
++
++ // translate JSBsim back to FG structure so that the
++ // autopilot (and the rest of the sim can use the updated
++ // values
++
++ fgJSBsim_2_FGInterface(f);
++
++ // but lets restore our original bogus altitude when we are done
++ if ( save_alt < -9000.0 ) {
++ f.set_Altitude( save_alt );
++ }
++
++ return 1;
++}
++
++
++// Convert from the FGInterface struct to the JSBsim generic_ struct
++int FGInterface_2_JSBsim (FGInterface& f) {
++
++ return 1;
++}
++
++
++// Convert from the JSBsim generic_ struct to the FGInterface struct
++int fgJSBsim_2_FGInterface (FGInterface& f) {
++
++ // Velocities
++ f.set_Velocities_Local( FDMExec.GetPosition()->GetVn(),
++ FDMExec.GetPosition()->GetVe(),
++ FDMExec.GetPosition()->GetVd() );
++ // f.set_Velocities_Ground( V_north_rel_ground, V_east_rel_ground,
++ // V_down_rel_ground );
++ // f.set_Velocities_Local_Airmass( V_north_airmass, V_east_airmass,
++ // V_down_airmass );
++ // f.set_Velocities_Local_Rel_Airmass( V_north_rel_airmass,
++ // V_east_rel_airmass, V_down_rel_airmass );
++ // f.set_Velocities_Gust( U_gust, V_gust, W_gust );
++ // f.set_Velocities_Wind_Body( U_body, V_body, W_body );
++
++ // f.set_V_rel_wind( V_rel_wind );
++ // f.set_V_true_kts( V_true_kts );
++ // f.set_V_rel_ground( V_rel_ground );
++ // f.set_V_inertial( V_inertial );
++ // f.set_V_ground_speed( V_ground_speed );
++ // f.set_V_equiv( V_equiv );
++
++ /* ***FIXME*** */ f.set_V_equiv_kts( FDMExec.GetState()->GetVt() );
++ // f.set_V_calibrated( V_calibrated );
++ // f.set_V_calibrated_kts( V_calibrated_kts );
++
++ f.set_Omega_Body( FDMExec.GetRotation()->GetP(),
++ FDMExec.GetRotation()->GetQ(),
++ FDMExec.GetRotation()->GetR() );
++ // f.set_Omega_Local( P_local, Q_local, R_local );
++ // f.set_Omega_Total( P_total, Q_total, R_total );
++
++ // f.set_Euler_Rates( Phi_dot, Theta_dot, Psi_dot );
++ // ***FIXME*** f.set_Geocentric_Rates( Latitude_dot, Longitude_dot, Radius_dot );
++
++ // Positions
++ double lat_geoc = FDMExec.GetState()->Getlatitude();
++ double lon = FDMExec.GetState()->Getlongitude();
++ double alt = FDMExec.GetState()->Geth();
++ double lat_geod, tmp_alt, sl_radius1, sl_radius2, tmp_lat_geoc;
++ fgGeocToGeod( lat_geoc, EQUATORIAL_RADIUS_M + alt * FEET_TO_METER,
++ &lat_geod, &tmp_alt, &sl_radius1 );
++ fgGeodToGeoc( lat_geod, alt * FEET_TO_METER, &sl_radius2, &tmp_lat_geoc );
++
++ FG_LOG( FG_FLIGHT, FG_DEBUG, "lon = " << lon << " lat_geod = " << lat_geod
++ << " lat_geoc = " << lat_geoc
++ << " alt = " << alt << " tmp_alt = " << tmp_alt * METER_TO_FEET
++ << " sl_radius1 = " << sl_radius1 * METER_TO_FEET
++ << " sl_radius2 = " << sl_radius2 * METER_TO_FEET
++ << " Equator = " << EQUATORIAL_RADIUS_FT );
++
++ f.set_Geocentric_Position( lat_geoc, lon,
++ sl_radius2 * METER_TO_FEET + alt );
++ f.set_Geodetic_Position( lat_geod, lon, alt );
++ f.set_Euler_Angles( FDMExec.GetRotation()->Getphi(),
++ FDMExec.GetRotation()->Gettht(),
++ FDMExec.GetRotation()->Getpsi() );
++
++ // Miscellaneous quantities
++ // f.set_T_Local_to_Body(T_local_to_body_m);
++ // f.set_Gravity( Gravity );
++ // f.set_Centrifugal_relief( Centrifugal_relief );
++
++ f.set_Alpha( FDMExec.GetTranslation()->Getalpha() );
++ f.set_Beta( FDMExec.GetTranslation()->Getbeta() );
++ // f.set_Alpha_dot( Alpha_dot );
++ // f.set_Beta_dot( Beta_dot );
++
++ // f.set_Cos_alpha( Cos_alpha );
++ // f.set_Sin_alpha( Sin_alpha );
++ // f.set_Cos_beta( Cos_beta );
++ // f.set_Sin_beta( Sin_beta );
++
++ // f.set_Cos_phi( Cos_phi );
++ // f.set_Sin_phi( Sin_phi );
++ // f.set_Cos_theta( Cos_theta );
++ // f.set_Sin_theta( Sin_theta );
++ // f.set_Cos_psi( Cos_psi );
++ // f.set_Sin_psi( Sin_psi );
++
++ // ***ATTENDTOME*** f.set_Gamma_vert_rad( Gamma_vert_rad );
++ // f.set_Gamma_horiz_rad( Gamma_horiz_rad );
++
++ // f.set_Sigma( Sigma );
++ // f.set_Density( Density );
++ // f.set_V_sound( V_sound );
++ // f.set_Mach_number( Mach_number );
++
++ // f.set_Static_pressure( Static_pressure );
++ // f.set_Total_pressure( Total_pressure );
++ // f.set_Impact_pressure( Impact_pressure );
++ // f.set_Dynamic_pressure( Dynamic_pressure );
++
++ // f.set_Static_temperature( Static_temperature );
++ // f.set_Total_temperature( Total_temperature );
++
++ /* **FIXME*** */ f.set_Sea_level_radius( sl_radius2 * METER_TO_FEET );
++ /* **FIXME*** */ f.set_Earth_position_angle( 0.0 );
++
++ /* ***FIXME*** */ f.set_Runway_altitude( 0.0 );
++ // f.set_Runway_latitude( Runway_latitude );
++ // f.set_Runway_longitude( Runway_longitude );
++ // f.set_Runway_heading( Runway_heading );
++ // f.set_Radius_to_rwy( Radius_to_rwy );
++
++ // f.set_CG_Rwy_Local( D_cg_north_of_rwy, D_cg_east_of_rwy, D_cg_above_rwy);
++ // f.set_CG_Rwy_Rwy( X_cg_rwy, Y_cg_rwy, H_cg_rwy );
++ // f.set_Pilot_Rwy_Local( D_pilot_north_of_rwy, D_pilot_east_of_rwy,
++ // D_pilot_above_rwy );
++ // f.set_Pilot_Rwy_Rwy( X_pilot_rwy, Y_pilot_rwy, H_pilot_rwy );
++
++ f.set_sin_lat_geocentric( lat_geoc );
++ f.set_cos_lat_geocentric( lat_geoc );
++ f.set_sin_cos_longitude( lon );
++ f.set_sin_cos_latitude( lat_geod );
++
++ return 0;
++}
++
++
++// $Log$
++// Revision 1.4 1999/04/03 04:20:01 curt
++// Optimizations (tm) by Norman Vine.
++//
++// Revision 1.3 1999/02/26 22:09:10 curt
++// Added initial support for native SGI compilers.
++// Integrated Jon's next version of JSBsim.
++//
++// Revision 1.2 1999/02/11 21:09:40 curt
++// Interface with Jon's submitted JSBsim changes.
++//
++// Revision 1.1 1999/02/05 21:29:38 curt
++// Incorporating Jon S. Berndt's flight model code.
++//
--- /dev/null
--- /dev/null
++// JSBsim.hxx -- interface to the "JSBsim" flight model
++//
++// Written by Curtis Olson, started February 1999.
++//
++// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#ifndef _JSBSIM_HXX
++#define _JSBSIM_HXX
++
++#include <FDM/JSBsim/FGFDMExec.h>
++#undef MAX_ENGINES
++
++#include <Aircraft/aircraft.hxx>
++
++
++// reset flight params to a specific position
++int fgJSBsimInit(double dt);
++
++// update position based on inputs, positions, velocities, etc.
++int fgJSBsimUpdate(FGInterface& f, int multiloop);
++
++// Convert from the FGInterface struct to the JSBsim generic_ struct
++int FGInterface_2_JSBsim (FGInterface& f);
++
++// Convert from the JSBsim generic_ struct to the FGInterface struct
++int fgJSBsim_2_FGInterface (FGInterface& f);
++
++
++#endif // _JSBSIM_HXX
++
++
++// $Log$
++// Revision 1.2 1999/02/11 21:09:41 curt
++// Interface with Jon's submitted JSBsim changes.
++//
++// Revision 1.1 1999/02/05 21:29:38 curt
++// Incorporating Jon S. Berndt's flight model code.
++//
--- /dev/null
--- /dev/null
++// LaRCsim.cxx -- interface to the LaRCsim flight model
++//
++// Written by Curtis Olson, started October 1998.
++//
++// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#include "LaRCsim.hxx"
++
++#include <Aircraft/aircraft.hxx>
++#include <Controls/controls.hxx>
++#include <Debug/logstream.hxx>
++#include <FDM/flight.hxx>
++#include <FDM/LaRCsim/ls_cockpit.h>
++#include <FDM/LaRCsim/ls_generic.h>
++#include <FDM/LaRCsim/ls_interface.h>
++
++
++// Initialize the LaRCsim flight model, dt is the time increment for
++// each subsequent iteration through the EOM
++int fgLaRCsimInit(double dt) {
++ ls_toplevel_init(dt);
++
++ return(1);
++}
++
++
++// Run an iteration of the EOM (equations of motion)
++int fgLaRCsimUpdate(FGInterface& f, int multiloop) {
++ double save_alt = 0.0;
++
++ // lets try to avoid really screwing up the LaRCsim model
++ if ( f.get_Altitude() < -9000.0 ) {
++ save_alt = f.get_Altitude();
++ f.set_Altitude( 0.0 );
++ }
++
++ // copy control positions into the LaRCsim structure
++ Lat_control = controls.get_aileron();
++ Long_control = controls.get_elevator();
++ Long_trim = controls.get_elevator_trim();
++ Rudder_pedal = controls.get_rudder();
++ Throttle_pct = controls.get_throttle( 0 );
++ Brake_pct = controls.get_brake( 0 );
++
++ // Inform LaRCsim of the local terrain altitude
++ Runway_altitude = f.get_Runway_altitude();
++
++ // old -- FGInterface_2_LaRCsim() not needed except for Init()
++ // translate FG to LaRCsim structure
++ // FGInterface_2_LaRCsim(f);
++ // printf("FG_Altitude = %.2f\n", FG_Altitude * 0.3048);
++ // printf("Altitude = %.2f\n", Altitude * 0.3048);
++ // printf("Radius to Vehicle = %.2f\n", Radius_to_vehicle * 0.3048);
++
++ ls_update(multiloop);
++
++ // printf("%d FG_Altitude = %.2f\n", i, FG_Altitude * 0.3048);
++ // printf("%d Altitude = %.2f\n", i, Altitude * 0.3048);
++
++ // translate LaRCsim back to FG structure so that the
++ // autopilot (and the rest of the sim can use the updated
++ // values
++ fgLaRCsim_2_FGInterface(f);
++
++ // but lets restore our original bogus altitude when we are done
++ if ( save_alt < -9000.0 ) {
++ f.set_Altitude( save_alt );
++ }
++
++ return 1;
++}
++
++
++// Convert from the FGInterface struct to the LaRCsim generic_ struct
++int FGInterface_2_LaRCsim (FGInterface& f) {
++
++ Mass = f.get_Mass();
++ I_xx = f.get_I_xx();
++ I_yy = f.get_I_yy();
++ I_zz = f.get_I_zz();
++ I_xz = f.get_I_xz();
++ // Dx_pilot = f.get_Dx_pilot();
++ // Dy_pilot = f.get_Dy_pilot();
++ // Dz_pilot = f.get_Dz_pilot();
++ Dx_cg = f.get_Dx_cg();
++ Dy_cg = f.get_Dy_cg();
++ Dz_cg = f.get_Dz_cg();
++ // F_X = f.get_F_X();
++ // F_Y = f.get_F_Y();
++ // F_Z = f.get_F_Z();
++ // F_north = f.get_F_north();
++ // F_east = f.get_F_east();
++ // F_down = f.get_F_down();
++ // F_X_aero = f.get_F_X_aero();
++ // F_Y_aero = f.get_F_Y_aero();
++ // F_Z_aero = f.get_F_Z_aero();
++ // F_X_engine = f.get_F_X_engine();
++ // F_Y_engine = f.get_F_Y_engine();
++ // F_Z_engine = f.get_F_Z_engine();
++ // F_X_gear = f.get_F_X_gear();
++ // F_Y_gear = f.get_F_Y_gear();
++ // F_Z_gear = f.get_F_Z_gear();
++ // M_l_rp = f.get_M_l_rp();
++ // M_m_rp = f.get_M_m_rp();
++ // M_n_rp = f.get_M_n_rp();
++ // M_l_cg = f.get_M_l_cg();
++ // M_m_cg = f.get_M_m_cg();
++ // M_n_cg = f.get_M_n_cg();
++ // M_l_aero = f.get_M_l_aero();
++ // M_m_aero = f.get_M_m_aero();
++ // M_n_aero = f.get_M_n_aero();
++ // M_l_engine = f.get_M_l_engine();
++ // M_m_engine = f.get_M_m_engine();
++ // M_n_engine = f.get_M_n_engine();
++ // M_l_gear = f.get_M_l_gear();
++ // M_m_gear = f.get_M_m_gear();
++ // M_n_gear = f.get_M_n_gear();
++ // V_dot_north = f.get_V_dot_north();
++ // V_dot_east = f.get_V_dot_east();
++ // V_dot_down = f.get_V_dot_down();
++ // U_dot_body = f.get_U_dot_body();
++ // V_dot_body = f.get_V_dot_body();
++ // W_dot_body = f.get_W_dot_body();
++ // A_X_cg = f.get_A_X_cg();
++ // A_Y_cg = f.get_A_Y_cg();
++ // A_Z_cg = f.get_A_Z_cg();
++ // A_X_pilot = f.get_A_X_pilot();
++ // A_Y_pilot = f.get_A_Y_pilot();
++ // A_Z_pilot = f.get_A_Z_pilot();
++ // N_X_cg = f.get_N_X_cg();
++ // N_Y_cg = f.get_N_Y_cg();
++ // N_Z_cg = f.get_N_Z_cg();
++ // N_X_pilot = f.get_N_X_pilot();
++ // N_Y_pilot = f.get_N_Y_pilot();
++ // N_Z_pilot = f.get_N_Z_pilot();
++ // P_dot_body = f.get_P_dot_body();
++ // Q_dot_body = f.get_Q_dot_body();
++ // R_dot_body = f.get_R_dot_body();
++ V_north = f.get_V_north();
++ V_east = f.get_V_east();
++ V_down = f.get_V_down();
++ // V_north_rel_ground = f.get_V_north_rel_ground();
++ // V_east_rel_ground = f.get_V_east_rel_ground();
++ // V_down_rel_ground = f.get_V_down_rel_ground();
++ // V_north_airmass = f.get_V_north_airmass();
++ // V_east_airmass = f.get_V_east_airmass();
++ // V_down_airmass = f.get_V_down_airmass();
++ // V_north_rel_airmass = f.get_V_north_rel_airmass();
++ // V_east_rel_airmass = f.get_V_east_rel_airmass();
++ // V_down_rel_airmass = f.get_V_down_rel_airmass();
++ // U_gust = f.get_U_gust();
++ // V_gust = f.get_V_gust();
++ // W_gust = f.get_W_gust();
++ // U_body = f.get_U_body();
++ // V_body = f.get_V_body();
++ // W_body = f.get_W_body();
++ // V_rel_wind = f.get_V_rel_wind();
++ // V_true_kts = f.get_V_true_kts();
++ // V_rel_ground = f.get_V_rel_ground();
++ // V_inertial = f.get_V_inertial();
++ // V_ground_speed = f.get_V_ground_speed();
++ // V_equiv = f.get_V_equiv();
++ // V_equiv_kts = f.get_V_equiv_kts();
++ // V_calibrated = f.get_V_calibrated();
++ // V_calibrated_kts = f.get_V_calibrated_kts();
++ P_body = f.get_P_body();
++ Q_body = f.get_Q_body();
++ R_body = f.get_R_body();
++ // P_local = f.get_P_local();
++ // Q_local = f.get_Q_local();
++ // R_local = f.get_R_local();
++ // P_total = f.get_P_total();
++ // Q_total = f.get_Q_total();
++ // R_total = f.get_R_total();
++ // Phi_dot = f.get_Phi_dot();
++ // Theta_dot = f.get_Theta_dot();
++ // Psi_dot = f.get_Psi_dot();
++ // Latitude_dot = f.get_Latitude_dot();
++ // Longitude_dot = f.get_Longitude_dot();
++ // Radius_dot = f.get_Radius_dot();
++ Lat_geocentric = f.get_Lat_geocentric();
++ Lon_geocentric = f.get_Lon_geocentric();
++ Radius_to_vehicle = f.get_Radius_to_vehicle();
++ Latitude = f.get_Latitude();
++ Longitude = f.get_Longitude();
++ Altitude = f.get_Altitude();
++ Phi = f.get_Phi();
++ Theta = f.get_Theta();
++ Psi = f.get_Psi();
++ // T_local_to_body_11 = f.get_T_local_to_body_11();
++ // T_local_to_body_12 = f.get_T_local_to_body_12();
++ // T_local_to_body_13 = f.get_T_local_to_body_13();
++ // T_local_to_body_21 = f.get_T_local_to_body_21();
++ // T_local_to_body_22 = f.get_T_local_to_body_22();
++ // T_local_to_body_23 = f.get_T_local_to_body_23();
++ // T_local_to_body_31 = f.get_T_local_to_body_31();
++ // T_local_to_body_32 = f.get_T_local_to_body_32();
++ // T_local_to_body_33 = f.get_T_local_to_body_33();
++ // Gravity = f.get_Gravity();
++ // Centrifugal_relief = f.get_Centrifugal_relief();
++ // Alpha = f.get_Alpha();
++ // Beta = f.get_Beta();
++ // Alpha_dot = f.get_Alpha_dot();
++ // Beta_dot = f.get_Beta_dot();
++ // Cos_alpha = f.get_Cos_alpha();
++ // Sin_alpha = f.get_Sin_alpha();
++ // Cos_beta = f.get_Cos_beta();
++ // Sin_beta = f.get_Sin_beta();
++ // Cos_phi = f.get_Cos_phi();
++ // Sin_phi = f.get_Sin_phi();
++ // Cos_theta = f.get_Cos_theta();
++ // Sin_theta = f.get_Sin_theta();
++ // Cos_psi = f.get_Cos_psi();
++ // Sin_psi = f.get_Sin_psi();
++ // Gamma_vert_rad = f.get_Gamma_vert_rad();
++ // Gamma_horiz_rad = f.get_Gamma_horiz_rad();
++ // Sigma = f.get_Sigma();
++ // Density = f.get_Density();
++ // V_sound = f.get_V_sound();
++ // Mach_number = f.get_Mach_number();
++ // Static_pressure = f.get_Static_pressure();
++ // Total_pressure = f.get_Total_pressure();
++ // Impact_pressure = f.get_Impact_pressure();
++ // Dynamic_pressure = f.get_Dynamic_pressure();
++ // Static_temperature = f.get_Static_temperature();
++ // Total_temperature = f.get_Total_temperature();
++ Sea_level_radius = f.get_Sea_level_radius();
++ Earth_position_angle = f.get_Earth_position_angle();
++ Runway_altitude = f.get_Runway_altitude();
++ // Runway_latitude = f.get_Runway_latitude();
++ // Runway_longitude = f.get_Runway_longitude();
++ // Runway_heading = f.get_Runway_heading();
++ // Radius_to_rwy = f.get_Radius_to_rwy();
++ // D_cg_north_of_rwy = f.get_D_cg_north_of_rwy();
++ // D_cg_east_of_rwy = f.get_D_cg_east_of_rwy();
++ // D_cg_above_rwy = f.get_D_cg_above_rwy();
++ // X_cg_rwy = f.get_X_cg_rwy();
++ // Y_cg_rwy = f.get_Y_cg_rwy();
++ // H_cg_rwy = f.get_H_cg_rwy();
++ // D_pilot_north_of_rwy = f.get_D_pilot_north_of_rwy();
++ // D_pilot_east_of_rwy = f.get_D_pilot_east_of_rwy();
++ // D_pilot_above_rwy = f.get_D_pilot_above_rwy();
++ // X_pilot_rwy = f.get_X_pilot_rwy();
++ // Y_pilot_rwy = f.get_Y_pilot_rwy();
++ // H_pilot_rwy = f.get_H_pilot_rwy();
++
++ return( 0 );
++}
++
++
++// Convert from the LaRCsim generic_ struct to the FGInterface struct
++int fgLaRCsim_2_FGInterface (FGInterface& f) {
++
++ // Mass properties and geometry values
++ f.set_Inertias( Mass, I_xx, I_yy, I_zz, I_xz );
++ // f.set_Pilot_Location( Dx_pilot, Dy_pilot, Dz_pilot );
++ f.set_CG_Position( Dx_cg, Dy_cg, Dz_cg );
++
++ // Forces
++ // f.set_Forces_Body_Total( F_X, F_Y, F_Z );
++ // f.set_Forces_Local_Total( F_north, F_east, F_down );
++ // f.set_Forces_Aero( F_X_aero, F_Y_aero, F_Z_aero );
++ // f.set_Forces_Engine( F_X_engine, F_Y_engine, F_Z_engine );
++ // f.set_Forces_Gear( F_X_gear, F_Y_gear, F_Z_gear );
++
++ // Moments
++ // f.set_Moments_Total_RP( M_l_rp, M_m_rp, M_n_rp );
++ // f.set_Moments_Total_CG( M_l_cg, M_m_cg, M_n_cg );
++ // f.set_Moments_Aero( M_l_aero, M_m_aero, M_n_aero );
++ // f.set_Moments_Engine( M_l_engine, M_m_engine, M_n_engine );
++ // f.set_Moments_Gear( M_l_gear, M_m_gear, M_n_gear );
++
++ // Accelerations
++ // f.set_Accels_Local( V_dot_north, V_dot_east, V_dot_down );
++ // f.set_Accels_Body( U_dot_body, V_dot_body, W_dot_body );
++ // f.set_Accels_CG_Body( A_X_cg, A_Y_cg, A_Z_cg );
++ // f.set_Accels_Pilot_Body( A_X_pilot, A_Y_pilot, A_Z_pilot );
++ // f.set_Accels_CG_Body_N( N_X_cg, N_Y_cg, N_Z_cg );
++ // f.set_Accels_Pilot_Body_N( N_X_pilot, N_Y_pilot, N_Z_pilot );
++ // f.set_Accels_Omega( P_dot_body, Q_dot_body, R_dot_body );
++
++ // Velocities
++ f.set_Velocities_Local( V_north, V_east, V_down );
++ // f.set_Velocities_Ground( V_north_rel_ground, V_east_rel_ground,
++ // V_down_rel_ground );
++ // f.set_Velocities_Local_Airmass( V_north_airmass, V_east_airmass,
++ // V_down_airmass );
++ // f.set_Velocities_Local_Rel_Airmass( V_north_rel_airmass,
++ // V_east_rel_airmass, V_down_rel_airmass );
++ // f.set_Velocities_Gust( U_gust, V_gust, W_gust );
++ // f.set_Velocities_Wind_Body( U_body, V_body, W_body );
++
++ // f.set_V_rel_wind( V_rel_wind );
++ // f.set_V_true_kts( V_true_kts );
++ // f.set_V_rel_ground( V_rel_ground );
++ // f.set_V_inertial( V_inertial );
++ // f.set_V_ground_speed( V_ground_speed );
++ // f.set_V_equiv( V_equiv );
++ f.set_V_equiv_kts( V_equiv_kts );
++ // f.set_V_calibrated( V_calibrated );
++ // f.set_V_calibrated_kts( V_calibrated_kts );
++
++ f.set_Omega_Body( P_body, Q_body, R_body );
++ // f.set_Omega_Local( P_local, Q_local, R_local );
++ // f.set_Omega_Total( P_total, Q_total, R_total );
++
++ // f.set_Euler_Rates( Phi_dot, Theta_dot, Psi_dot );
++ f.set_Geocentric_Rates( Latitude_dot, Longitude_dot, Radius_dot );
++
++ FG_LOG( FG_FLIGHT, FG_DEBUG, "lon = " << Longitude
++ << " lat_geoc = " << Lat_geocentric << " lat_geod = " << Latitude
++ << " alt = " << Altitude << " sl_radius = " << Sea_level_radius
++ << " radius_to_vehicle = " << Radius_to_vehicle );
++
++ // Positions
++ f.set_Geocentric_Position( Lat_geocentric, Lon_geocentric,
++ Radius_to_vehicle );
++ f.set_Geodetic_Position( Latitude, Longitude, Altitude );
++ f.set_Euler_Angles( Phi, Theta, Psi );
++
++ // Miscellaneous quantities
++ f.set_T_Local_to_Body(T_local_to_body_m);
++ // f.set_Gravity( Gravity );
++ // f.set_Centrifugal_relief( Centrifugal_relief );
++
++ f.set_Alpha( Alpha );
++ f.set_Beta( Beta );
++ // f.set_Alpha_dot( Alpha_dot );
++ // f.set_Beta_dot( Beta_dot );
++
++ // f.set_Cos_alpha( Cos_alpha );
++ // f.set_Sin_alpha( Sin_alpha );
++ // f.set_Cos_beta( Cos_beta );
++ // f.set_Sin_beta( Sin_beta );
++
++ // f.set_Cos_phi( Cos_phi );
++ // f.set_Sin_phi( Sin_phi );
++ // f.set_Cos_theta( Cos_theta );
++ // f.set_Sin_theta( Sin_theta );
++ // f.set_Cos_psi( Cos_psi );
++ // f.set_Sin_psi( Sin_psi );
++
++ f.set_Gamma_vert_rad( Gamma_vert_rad );
++ // f.set_Gamma_horiz_rad( Gamma_horiz_rad );
++
++ // f.set_Sigma( Sigma );
++ // f.set_Density( Density );
++ // f.set_V_sound( V_sound );
++ // f.set_Mach_number( Mach_number );
++
++ // f.set_Static_pressure( Static_pressure );
++ // f.set_Total_pressure( Total_pressure );
++ // f.set_Impact_pressure( Impact_pressure );
++ // f.set_Dynamic_pressure( Dynamic_pressure );
++
++ // f.set_Static_temperature( Static_temperature );
++ // f.set_Total_temperature( Total_temperature );
++
++ f.set_Sea_level_radius( Sea_level_radius );
++ f.set_Earth_position_angle( Earth_position_angle );
++
++ f.set_Runway_altitude( Runway_altitude );
++ // f.set_Runway_latitude( Runway_latitude );
++ // f.set_Runway_longitude( Runway_longitude );
++ // f.set_Runway_heading( Runway_heading );
++ // f.set_Radius_to_rwy( Radius_to_rwy );
++
++ // f.set_CG_Rwy_Local( D_cg_north_of_rwy, D_cg_east_of_rwy, D_cg_above_rwy);
++ // f.set_CG_Rwy_Rwy( X_cg_rwy, Y_cg_rwy, H_cg_rwy );
++ // f.set_Pilot_Rwy_Local( D_pilot_north_of_rwy, D_pilot_east_of_rwy,
++ // D_pilot_above_rwy );
++ // f.set_Pilot_Rwy_Rwy( X_pilot_rwy, Y_pilot_rwy, H_pilot_rwy );
++
++ f.set_sin_lat_geocentric(Lat_geocentric);
++ f.set_cos_lat_geocentric(Lat_geocentric);
++ f.set_sin_cos_longitude(Longitude);
++ f.set_sin_cos_latitude(Latitude);
++
++ // printf("sin_lat_geo %f cos_lat_geo %f\n", sin_Lat_geoc, cos_Lat_geoc);
++ // printf("sin_lat %f cos_lat %f\n",
++ // f.get_sin_latitude(), f.get_cos_latitude());
++ // printf("sin_lon %f cos_lon %f\n",
++ // f.get_sin_longitude(), f.get_cos_longitude());
++
++ return 0;
++}
++
++
++// $Log$
++// Revision 1.12 1999/04/03 04:20:02 curt
++// Optimizations (tm) by Norman Vine.
++//
++// Revision 1.11 1999/02/05 21:28:58 curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.10 1999/02/01 21:33:30 curt
++// Renamed FlightGear/Simulator/Flight to FlightGear/Simulator/FDM since
++// Jon accepted my offer to do this and thought it was a good idea.
++//
++// Revision 1.9 1999/01/08 19:27:36 curt
++// Fixed AOA reading on HUD.
++// Continued work on time jitter compensation.
++//
++// Revision 1.8 1998/12/18 23:37:06 curt
++// Collapsed out the FGState variables not currently needed. They are just
++// commented out and can be readded easily at any time. The point of this
++// exersize is to determine which variables were or were not currently being
++// used.
++//
++// Revision 1.7 1998/12/14 13:31:06 curt
++// LaRCsim maintains all it's variables internally. I had been copying all of
++// them back and forth to the FG struture everytime I updated the flight model.
++// However, I have realized that this is not necessary. I just need to copy
++// the control positions and environmental parameters into the LaRCsim structure
++// before updating the FDM, then copy every thing back out into the publick FGFS
++// structure afterwords. This seems to solve (or at least help) a westward
++// drift problem some poeple had been observing.
++//
++// Revision 1.6 1998/12/05 15:54:08 curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.5 1998/12/03 04:25:02 curt
++// Working on fixing up new fgFLIGHT class.
++//
++// Revision 1.4 1998/12/03 01:16:37 curt
++// Converted fgFLIGHT to a class.
++//
++// Revision 1.3 1998/10/25 14:08:43 curt
++// Turned "struct fgCONTROLS" into a class, with inlined accessor functions.
++//
++// Revision 1.2 1998/10/17 01:34:11 curt
++// C++ ifying ...
++//
++// Revision 1.1 1998/10/17 00:43:58 curt
++// Initial revision.
++//
++//
--- /dev/null
--- /dev/null
++//*************************************************************************
++// LaRCsim.hxx -- interface to the "LaRCsim" flight model
++//
++// Written by Curtis Olson, started May 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$
++// (Log is kept at end of this file)
++//*************************************************************************/
++
++
++#ifndef _LARCSIM_HXX
++#define _LARCSIM_HXX
++
++
++#include "flight.hxx"
++
++
++// reset flight params to a specific position
++int fgLaRCsimInit(double dt);
++
++// update position based on inputs, positions, velocities, etc.
++int fgLaRCsimUpdate(FGInterface& f, int multiloop);
++
++// Convert from the FGInterface struct to the LaRCsim generic_ struct
++int FGInterface_2_LaRCsim (FGInterface& f);
++
++// Convert from the LaRCsim generic_ struct to the FGInterface struct
++int fgLaRCsim_2_FGInterface (FGInterface& f);
++
++
++#endif // _LARCSIM_HXX
++
++
++// $Log$
++// Revision 1.5 1999/02/05 21:28:59 curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.4 1998/12/05 15:54:09 curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.3 1998/12/03 01:16:38 curt
++// Converted fgFLIGHT to a class.
++//
++// Revision 1.2 1998/10/17 01:34:13 curt
++// C++ ifying ...
++//
++// Revision 1.1 1998/10/17 00:43:58 curt
++// Initial revision.
++//
--- /dev/null
--- /dev/null
++SUBDIRS = External JSBsim LaRCsim Slew
++
++noinst_LIBRARIES = libFlight.a
++
++libFlight_a_SOURCES = flight.cxx flight.hxx \
++ JSBsim.cxx JSBsim.hxx \
++ LaRCsim.cxx LaRCsim.hxx
++
++INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib -I$(top_builddir)/Simulator
++
++DEFS += -DFGFS
--- /dev/null
--- /dev/null
++// flight.c -- a general interface to the various flight models
++//
++// Written by Curtis Olson, started May 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$
++// (Log is kept at end of this file)
++
++
++#include <stdio.h>
++
++#include <Debug/logstream.hxx>
++#include <FDM/External/external.hxx>
++#include <FDM/LaRCsim/ls_interface.h>
++#include <Include/fg_constants.h>
++#include <Math/fg_geodesy.hxx>
++#include <Time/timestamp.hxx>
++
++#include "flight.hxx"
++#include "JSBsim.hxx"
++#include "LaRCsim.hxx"
++
++
++// base_fdm_state is the internal state that is updated in integer
++// multiples of "dt". This leads to "jitter" with respect to the real
++// world time, so we introduce cur_fdm_state which is extrapolated by
++// the difference between sim time and real world time
++
++FGInterface cur_fdm_state;
++FGInterface base_fdm_state;
++
++
++// Extrapolate fdm based on time_offset (in usec)
++void FGInterface::extrapolate( int time_offset ) {
++ double dt = time_offset / 1000000.0;
++ cout << "extrapolating FDM by dt = " << dt << endl;
++
++ double lat = geodetic_position_v[0] + geocentric_rates_v[0] * dt;
++ double lat_geoc = geocentric_position_v[0] + geocentric_rates_v[0] * dt;
++
++ double lon = geodetic_position_v[1] + geocentric_rates_v[1] * dt;
++ double lon_geoc = geocentric_position_v[1] + geocentric_rates_v[1] * dt;
++
++ double alt = geodetic_position_v[2] + geocentric_rates_v[2] * dt;
++ double radius = geocentric_position_v[2] + geocentric_rates_v[2] * dt;
++
++ geodetic_position_v[0] = lat;
++ geocentric_position_v[0] = lat_geoc;
++
++ geodetic_position_v[1] = lon;
++ geocentric_position_v[1] = lon_geoc;
++
++ geodetic_position_v[2] = alt;
++ geocentric_position_v[2] = radius;
++}
++
++
++// Initialize the flight model parameters
++int fgFDMInit(int model, FGInterface& f, double dt) {
++ double save_alt = 0.0;
++
++ FG_LOG( FG_FLIGHT ,FG_INFO, "Initializing flight model" );
++
++ base_fdm_state = f;
++
++ if ( model == FGInterface::FG_SLEW ) {
++ // fgSlewInit(dt);
++ } else if ( model == FGInterface::FG_JSBSIM ) {
++ fgJSBsimInit(dt);
++ fgJSBsim_2_FGInterface(base_fdm_state);
++ } else if ( model == FGInterface::FG_LARCSIM ) {
++ // lets try to avoid really screwing up the LaRCsim model
++ if ( base_fdm_state.get_Altitude() < -9000.0 ) {
++ save_alt = base_fdm_state.get_Altitude();
++ base_fdm_state.set_Altitude( 0.0 );
++ }
++
++ // translate FG to LaRCsim structure
++ FGInterface_2_LaRCsim(base_fdm_state);
++
++ // initialize LaRCsim
++ fgLaRCsimInit(dt);
++
++ FG_LOG( FG_FLIGHT, FG_INFO, "FG pos = " <<
++ base_fdm_state.get_Latitude() );
++
++ // translate LaRCsim back to FG structure
++ fgLaRCsim_2_FGInterface(base_fdm_state);
++
++ // but lets restore our original bogus altitude when we are done
++ if ( save_alt < -9000.0 ) {
++ base_fdm_state.set_Altitude( save_alt );
++ }
++ } else if ( model == FGInterface::FG_EXTERNAL ) {
++ fgExternalInit(base_fdm_state);
++ } else {
++ FG_LOG( FG_FLIGHT, FG_WARN,
++ "Unimplemented flight model == " << model );
++ }
++
++ // set valid time for this record
++ base_fdm_state.stamp_time();
++
++ f = base_fdm_state;
++
++ return 1;
++}
++
++
++// Run multiloop iterations of the flight model
++int fgFDMUpdate(int model, FGInterface& f, int multiloop, int time_offset) {
++ double time_step, start_elev, end_elev;
++
++ // printf("Altitude = %.2f\n", FG_Altitude * 0.3048);
++
++ // set valid time for this record
++ base_fdm_state.stamp_time();
++
++ time_step = (1.0 / DEFAULT_MODEL_HZ) * multiloop;
++ start_elev = base_fdm_state.get_Altitude();
++
++ if ( model == FGInterface::FG_SLEW ) {
++ // fgSlewUpdate(f, multiloop);
++ } else if ( model == FGInterface::FG_JSBSIM ) {
++ fgJSBsimUpdate(base_fdm_state, multiloop);
++ f = base_fdm_state;
++ } else if ( model == FGInterface::FG_LARCSIM ) {
++ fgLaRCsimUpdate(base_fdm_state, multiloop);
++ // extrapolate position based on actual time
++ // f = extrapolate_fdm( base_fdm_state, time_offset );
++ f = base_fdm_state;
++ } else if ( model == FGInterface::FG_EXTERNAL ) {
++ // fgExternalUpdate(f, multiloop);
++ FGTimeStamp current;
++ current.stamp();
++ f = base_fdm_state;
++ f.extrapolate( current - base_fdm_state.get_time_stamp() );
++ } else {
++ FG_LOG( FG_FLIGHT, FG_WARN,
++ "Unimplemented flight model == " << model );
++ }
++
++ end_elev = base_fdm_state.get_Altitude();
++
++ if ( time_step > 0.0 ) {
++ // feet per second
++ base_fdm_state.set_Climb_Rate( (end_elev - start_elev) / time_step );
++ }
++
++ return 1;
++}
++
++
++// Set the altitude (force)
++void fgFDMForceAltitude(int model, double alt_meters) {
++ double sea_level_radius_meters;
++ double lat_geoc;
++
++ // Set the FG variables first
++ fgGeodToGeoc( base_fdm_state.get_Latitude(), alt_meters,
++ &sea_level_radius_meters, &lat_geoc);
++
++ base_fdm_state.set_Altitude( alt_meters * METER_TO_FEET );
++ base_fdm_state.set_Radius_to_vehicle( base_fdm_state.get_Altitude() +
++ (sea_level_radius_meters *
++ METER_TO_FEET) );
++
++ // additional work needed for some flight models
++ if ( model == FGInterface::FG_LARCSIM ) {
++ ls_ForceAltitude( base_fdm_state.get_Altitude() );
++ }
++}
++
++
++// Set the local ground elevation
++void fgFDMSetGroundElevation(int model, double ground_meters) {
++ base_fdm_state.set_Runway_altitude( ground_meters * METER_TO_FEET );
++ cur_fdm_state.set_Runway_altitude( ground_meters * METER_TO_FEET );
++}
++
++
++// $Log$
++// Revision 1.17 1999/04/03 04:20:03 curt
++// Optimizations (tm) by Norman Vine.
++//
++// Revision 1.16 1999/02/26 22:09:12 curt
++// Added initial support for native SGI compilers.
++// Integrated Jon's next version of JSBsim.
++//
++// Revision 1.15 1999/02/05 21:29:01 curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.14 1999/02/01 21:33:31 curt
++// Renamed FlightGear/Simulator/Flight to FlightGear/Simulator/FDM since
++// Jon accepted my offer to do this and thought it was a good idea.
++//
++// Revision 1.13 1999/01/27 04:48:39 curt
++// Set the runway height in cur_fdm_state as well as base_fdm_state.
++//
++// Revision 1.12 1999/01/20 13:42:22 curt
++// Tweaked FDM interface.
++// Testing check sum support for NMEA serial output.
++//
++// Revision 1.11 1999/01/19 17:52:06 curt
++// Working on being able to extrapolate a new position and orientation
++// based on a position, orientation, and time offset.
++//
++// Revision 1.10 1999/01/09 13:37:32 curt
++// Convert fgTIMESTAMP to FGTimeStamp which holds usec instead of ms.
++//
++// Revision 1.9 1999/01/08 19:27:37 curt
++// Fixed AOA reading on HUD.
++// Continued work on time jitter compensation.
++//
++// Revision 1.8 1999/01/08 03:23:51 curt
++// Beginning work on compensating for sim time vs. real world time "jitter".
++//
++// Revision 1.7 1998/12/18 23:37:07 curt
++// Collapsed out the FGState variables not currently needed. They are just
++// commented out and can be readded easily at any time. The point of this
++// exersize is to determine which variables were or were not currently being
++// used.
++//
++// Revision 1.6 1998/12/05 15:54:11 curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.5 1998/12/04 01:29:39 curt
++// Stubbed in a new flight model called "External" which is expected to be driven
++// from some external source.
++//
++// Revision 1.4 1998/12/03 01:16:40 curt
++// Converted fgFLIGHT to a class.
++//
++// Revision 1.3 1998/11/06 21:18:03 curt
++// Converted to new logstream debugging facility. This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUGNDEBUG flag.
++//
++// Revision 1.2 1998/10/16 23:27:40 curt
++// C++-ifying.
++//
++// Revision 1.1 1998/10/16 20:16:41 curt
++// Renamed flight.[ch] to flight.[ch]xx
++//
++// Revision 1.19 1998/09/29 14:57:38 curt
++// c++-ified comments.
++//
++// Revision 1.18 1998/09/29 02:02:40 curt
++// Added a rate of climb calculation.
++//
++// Revision 1.17 1998/08/24 20:09:07 curt
++// .
++//
++// Revision 1.16 1998/08/22 14:49:55 curt
++// Attempting to iron out seg faults and crashes.
++// Did some shuffling to fix a initialization order problem between view
++// position, scenery elevation.
++//
++// Revision 1.15 1998/07/30 23:44:36 curt
++// Beginning to add support for multiple flight models.
++//
++// Revision 1.14 1998/07/12 03:08:27 curt
++// Added fgFlightModelSetAltitude() to force the altitude to something
++// other than the current altitude. LaRCsim doesn't let you do this by just
++// changing FG_Altitude.
++//
++// Revision 1.13 1998/04/25 22:06:28 curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.12 1998/04/21 16:59:33 curt
++// Integrated autopilot.
++// Prepairing for C++ integration.
++//
++// Revision 1.11 1998/04/18 04:14:04 curt
++// Moved fg_debug.c to it's own library.
++//
++// Revision 1.10 1998/02/07 15:29:37 curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.9 1998/01/27 00:47:53 curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.8 1998/01/19 19:27:03 curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.7 1998/01/19 18:40:23 curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.6 1998/01/19 18:35:43 curt
++// Minor tweaks and fixes for cygwin32.
++//
++// Revision 1.5 1997/12/30 20:47:37 curt
++// Integrated new event manager with subsystem initializations.
++//
++// Revision 1.4 1997/12/10 22:37:42 curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.3 1997/08/27 03:30:04 curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.2 1997/05/29 22:39:57 curt
++// Working on incorporating the LaRCsim flight model.
++//
++// Revision 1.1 1997/05/29 02:35:04 curt
++// Initial revision.
++//
--- /dev/null
--- /dev/null
++// flight.hxx -- define shared flight model parameters
++//
++// Written by Curtis Olson, started May 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$
++// (Log is kept at end of this file)
++
++
++#ifndef _FLIGHT_HXX
++#define _FLIGHT_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++
++/* Required get_()
++
++ `FGInterface::get_Longitude ()'
++ `FGInterface::get_Latitude ()'
++ `FGInterface::get_Altitude ()'
++ `FGInterface::get_Phi ()'
++ `FGInterface::get_Theta ()'
++ `FGInterface::get_Psi ()'
++ `FGInterface::get_V_equiv_kts ()'
++
++ `FGInterface::get_Mass ()'
++ `FGInterface::get_I_xx ()'
++ `FGInterface::get_I_yy ()'
++ `FGInterface::get_I_zz ()'
++ `FGInterface::get_I_xz ()'
++
++ `FGInterface::get_V_north ()'
++ `FGInterface::get_V_east ()'
++ `FGInterface::get_V_down ()'
++
++ `FGInterface::get_P_Body ()'
++ `FGInterface::get_Q_Body ()'
++ `FGInterface::get_R_Body ()'
++
++ `FGInterface::get_Gamma_vert_rad ()'
++ `FGInterface::get_Climb_Rate ()'
++ `FGInterface::get_Alpha ()'
++ `FGInterface::get_Beta ()'
++
++ `FGInterface::get_Runway_altitude ()'
++
++ `FGInterface::get_Lon_geocentric ()'
++ `FGInterface::get_Lat_geocentric ()'
++ `FGInterface::get_Sea_level_radius ()'
++ `FGInterface::get_Earth_position_angle ()'
++
++ `FGInterface::get_Latitude_dot()'
++ `FGInterface::get_Longitude_dot()'
++ `FGInterface::get_Radius_dot()'
++
++ `FGInterface::get_Dx_cg ()'
++ `FGInterface::get_Dy_cg ()'
++ `FGInterface::get_Dz_cg ()'
++
++ `FGInterface::get_T_local_to_body_11 ()' ... `FGInterface::get_T_local_to_body_33 ()'
++
++ `FGInterface::get_Radius_to_vehicle ()'
++
++ */
++
++
++#include <Time/timestamp.hxx>
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++
++typedef double FG_VECTOR_3[3];
++
++
++// This is based heavily on LaRCsim/ls_generic.h
++class FGInterface {
++
++public:
++
++ // Define the various supported flight models (many not yet implemented)
++ enum {
++ // Slew (in MS terminology)
++ FG_SLEW = 0,
++
++ // The NASA LaRCsim (Navion) flight model
++ FG_LARCSIM = 1,
++
++ // Jon S. Berndt's new FDM written from the ground up in C++
++ FG_JSBSIM = 2,
++
++ // The following aren't implemented but are here to spark
++ // thoughts and discussions, and maybe even action.
++ FG_ACM = 3,
++ FG_SUPER_SONIC = 4,
++ FG_HELICOPTER = 5,
++ FG_AUTOGYRO = 6,
++ FG_BALLOON = 7,
++ FG_PARACHUTE = 8,
++
++ // Driven externally via a serial port, net, file, etc.
++ FG_EXTERNAL = 9
++ };
++
++/*================== Mass properties and geometry values ==================*/
++
++ // Inertias
++ double mass, i_xx, i_yy, i_zz, i_xz;
++ inline double get_Mass() const { return mass; }
++ inline double get_I_xx() const { return i_xx; }
++ inline double get_I_yy() const { return i_yy; }
++ inline double get_I_zz() const { return i_zz; }
++ inline double get_I_xz() const { return i_xz; }
++ inline void set_Inertias( double m, double xx, double yy,
++ double zz, double xz)
++ {
++ mass = m;
++ i_xx = xx;
++ i_yy = yy;
++ i_zz = zz;
++ i_xz = xz;
++ }
++
++ // Pilot location rel to ref pt
++ FG_VECTOR_3 d_pilot_rp_body_v;
++ // inline double * get_D_pilot_rp_body_v() {
++ // return d_pilot_rp_body_v;
++ // }
++ // inline double get_Dx_pilot() const { return d_pilot_rp_body_v[0]; }
++ // inline double get_Dy_pilot() const { return d_pilot_rp_body_v[1]; }
++ // inline double get_Dz_pilot() const { return d_pilot_rp_body_v[2]; }
++ /* inline void set_Pilot_Location( double dx, double dy, double dz ) {
++ d_pilot_rp_body_v[0] = dx;
++ d_pilot_rp_body_v[1] = dy;
++ d_pilot_rp_body_v[2] = dz;
++ } */
++
++ // CG position w.r.t. ref. point
++ FG_VECTOR_3 d_cg_rp_body_v;
++ // inline double * get_D_cg_rp_body_v() { return d_cg_rp_body_v; }
++ inline double get_Dx_cg() const { return d_cg_rp_body_v[0]; }
++ inline double get_Dy_cg() const { return d_cg_rp_body_v[1]; }
++ inline double get_Dz_cg() const { return d_cg_rp_body_v[2]; }
++ inline void set_CG_Position( double dx, double dy, double dz ) {
++ d_cg_rp_body_v[0] = dx;
++ d_cg_rp_body_v[1] = dy;
++ d_cg_rp_body_v[2] = dz;
++ }
++
++/*================================ Forces =================================*/
++
++ FG_VECTOR_3 f_body_total_v;
++ // inline double * get_F_body_total_v() { return f_body_total_v; }
++ // inline double get_F_X() const { return f_body_total_v[0]; }
++ // inline double get_F_Y() const { return f_body_total_v[1]; }
++ // inline double get_F_Z() const { return f_body_total_v[2]; }
++ /* inline void set_Forces_Body_Total( double x, double y, double z ) {
++ f_body_total_v[0] = x;
++ f_body_total_v[1] = y;
++ f_body_total_v[2] = z;
++ } */
++
++ FG_VECTOR_3 f_local_total_v;
++ // inline double * get_F_local_total_v() { return f_local_total_v; }
++ // inline double get_F_north() const { return f_local_total_v[0]; }
++ // inline double get_F_east() const { return f_local_total_v[1]; }
++ // inline double get_F_down() const { return f_local_total_v[2]; }
++ /* inline void set_Forces_Local_Total( double x, double y, double z ) {
++ f_local_total_v[0] = x;
++ f_local_total_v[1] = y;
++ f_local_total_v[2] = z;
++ } */
++
++ FG_VECTOR_3 f_aero_v;
++ // inline double * get_F_aero_v() { return f_aero_v; }
++ // inline double get_F_X_aero() const { return f_aero_v[0]; }
++ // inline double get_F_Y_aero() const { return f_aero_v[1]; }
++ // inline double get_F_Z_aero() const { return f_aero_v[2]; }
++ /* inline void set_Forces_Aero( double x, double y, double z ) {
++ f_aero_v[0] = x;
++ f_aero_v[1] = y;
++ f_aero_v[2] = z;
++ } */
++
++ FG_VECTOR_3 f_engine_v;
++ // inline double * get_F_engine_v() { return f_engine_v; }
++ // inline double get_F_X_engine() const { return f_engine_v[0]; }
++ // inline double get_F_Y_engine() const { return f_engine_v[1]; }
++ // inline double get_F_Z_engine() const { return f_engine_v[2]; }
++ /* inline void set_Forces_Engine( double x, double y, double z ) {
++ f_engine_v[0] = x;
++ f_engine_v[1] = y;
++ f_engine_v[2] = z;
++ } */
++
++ FG_VECTOR_3 f_gear_v;
++ // inline double * get_F_gear_v() { return f_gear_v; }
++ // inline double get_F_X_gear() const { return f_gear_v[0]; }
++ // inline double get_F_Y_gear() const { return f_gear_v[1]; }
++ // inline double get_F_Z_gear() const { return f_gear_v[2]; }
++ /* inline void set_Forces_Gear( double x, double y, double z ) {
++ f_gear_v[0] = x;
++ f_gear_v[1] = y;
++ f_gear_v[2] = z;
++ } */
++
++ /*================================ Moments ================================*/
++
++ FG_VECTOR_3 m_total_rp_v;
++ // inline double * get_M_total_rp_v() { return m_total_rp_v; }
++ // inline double get_M_l_rp() const { return m_total_rp_v[0]; }
++ // inline double get_M_m_rp() const { return m_total_rp_v[1]; }
++ // inline double get_M_n_rp() const { return m_total_rp_v[2]; }
++ /* inline void set_Moments_Total_RP( double l, double m, double n ) {
++ m_total_rp_v[0] = l;
++ m_total_rp_v[1] = m;
++ m_total_rp_v[2] = n;
++ } */
++
++ FG_VECTOR_3 m_total_cg_v;
++ // inline double * get_M_total_cg_v() { return m_total_cg_v; }
++ // inline double get_M_l_cg() const { return m_total_cg_v[0]; }
++ // inline double get_M_m_cg() const { return m_total_cg_v[1]; }
++ // inline double get_M_n_cg() const { return m_total_cg_v[2]; }
++ /* inline void set_Moments_Total_CG( double l, double m, double n ) {
++ m_total_cg_v[0] = l;
++ m_total_cg_v[1] = m;
++ m_total_cg_v[2] = n;
++ } */
++
++ FG_VECTOR_3 m_aero_v;
++ // inline double * get_M_aero_v() { return m_aero_v; }
++ // inline double get_M_l_aero() const { return m_aero_v[0]; }
++ // inline double get_M_m_aero() const { return m_aero_v[1]; }
++ // inline double get_M_n_aero() const { return m_aero_v[2]; }
++ /* inline void set_Moments_Aero( double l, double m, double n ) {
++ m_aero_v[0] = l;
++ m_aero_v[1] = m;
++ m_aero_v[2] = n;
++ } */
++
++ FG_VECTOR_3 m_engine_v;
++ // inline double * get_M_engine_v() { return m_engine_v; }
++ // inline double get_M_l_engine() const { return m_engine_v[0]; }
++ // inline double get_M_m_engine() const { return m_engine_v[1]; }
++ // inline double get_M_n_engine() const { return m_engine_v[2]; }
++ /* inline void set_Moments_Engine( double l, double m, double n ) {
++ m_engine_v[0] = l;
++ m_engine_v[1] = m;
++ m_engine_v[2] = n;
++ } */
++
++ FG_VECTOR_3 m_gear_v;
++ // inline double * get_M_gear_v() { return m_gear_v; }
++ // inline double get_M_l_gear() const { return m_gear_v[0]; }
++ // inline double get_M_m_gear() const { return m_gear_v[1]; }
++ // inline double get_M_n_gear() const { return m_gear_v[2]; }
++ /* inline void set_Moments_Gear( double l, double m, double n ) {
++ m_gear_v[0] = l;
++ m_gear_v[1] = m;
++ m_gear_v[2] = n;
++ } */
++
++ /*============================== Accelerations ============================*/
++
++ FG_VECTOR_3 v_dot_local_v;
++ // inline double * get_V_dot_local_v() { return v_dot_local_v; }
++ // inline double get_V_dot_north() const { return v_dot_local_v[0]; }
++ // inline double get_V_dot_east() const { return v_dot_local_v[1]; }
++ // inline double get_V_dot_down() const { return v_dot_local_v[2]; }
++ /* inline void set_Accels_Local( double north, double east, double down ) {
++ v_dot_local_v[0] = north;
++ v_dot_local_v[1] = east;
++ v_dot_local_v[2] = down;
++ } */
++
++ FG_VECTOR_3 v_dot_body_v;
++ // inline double * get_V_dot_body_v() { return v_dot_body_v; }
++ // inline double get_U_dot_body() const { return v_dot_body_v[0]; }
++ // inline double get_V_dot_body() const { return v_dot_body_v[1]; }
++ // inline double get_W_dot_body() const { return v_dot_body_v[2]; }
++ /* inline void set_Accels_Body( double u, double v, double w ) {
++ v_dot_local_v[0] = u;
++ v_dot_local_v[1] = v;
++ v_dot_local_v[2] = w;
++ } */
++
++ FG_VECTOR_3 a_cg_body_v;
++ // inline double * get_A_cg_body_v() { return a_cg_body_v; }
++ // inline double get_A_X_cg() const { return a_cg_body_v[0]; }
++ // inline double get_A_Y_cg() const { return a_cg_body_v[1]; }
++ // inline double get_A_Z_cg() const { return a_cg_body_v[2]; }
++ /* inline void set_Accels_CG_Body( double x, double y, double z ) {
++ a_cg_body_v[0] = x;
++ a_cg_body_v[1] = y;
++ a_cg_body_v[2] = z;
++ } */
++
++ FG_VECTOR_3 a_pilot_body_v;
++ // inline double * get_A_pilot_body_v() { return a_pilot_body_v; }
++ // inline double get_A_X_pilot() const { return a_pilot_body_v[0]; }
++ // inline double get_A_Y_pilot() const { return a_pilot_body_v[1]; }
++ // inline double get_A_Z_pilot() const { return a_pilot_body_v[2]; }
++ /* inline void set_Accels_Pilot_Body( double x, double y, double z ) {
++ a_pilot_body_v[0] = x;
++ a_pilot_body_v[1] = y;
++ a_pilot_body_v[2] = z;
++ } */
++
++ FG_VECTOR_3 n_cg_body_v;
++ // inline double * get_N_cg_body_v() { return n_cg_body_v; }
++ // inline double get_N_X_cg() const { return n_cg_body_v[0]; }
++ // inline double get_N_Y_cg() const { return n_cg_body_v[1]; }
++ // inline double get_N_Z_cg() const { return n_cg_body_v[2]; }
++ /* inline void set_Accels_CG_Body_N( double x, double y, double z ) {
++ n_cg_body_v[0] = x;
++ n_cg_body_v[1] = y;
++ n_cg_body_v[2] = z;
++ } */
++
++ FG_VECTOR_3 n_pilot_body_v;
++ // inline double * get_N_pilot_body_v() { return n_pilot_body_v; }
++ // inline double get_N_X_pilot() const { return n_pilot_body_v[0]; }
++ // inline double get_N_Y_pilot() const { return n_pilot_body_v[1]; }
++ // inline double get_N_Z_pilot() const { return n_pilot_body_v[2]; }
++ /* inline void set_Accels_Pilot_Body_N( double x, double y, double z ) {
++ n_pilot_body_v[0] = x;
++ n_pilot_body_v[1] = y;
++ n_pilot_body_v[2] = z;
++ } */
++
++ FG_VECTOR_3 omega_dot_body_v;
++ // inline double * get_Omega_dot_body_v() { return omega_dot_body_v; }
++ // inline double get_P_dot_body() const { return omega_dot_body_v[0]; }
++ // inline double get_Q_dot_body() const { return omega_dot_body_v[1]; }
++ // inline double get_R_dot_body() const { return omega_dot_body_v[2]; }
++ /* inline void set_Accels_Omega( double p, double q, double r ) {
++ omega_dot_body_v[0] = p;
++ omega_dot_body_v[1] = q;
++ omega_dot_body_v[2] = r;
++ } */
++
++
++ /*============================== Velocities ===============================*/
++
++ FG_VECTOR_3 v_local_v;
++ // inline double * get_V_local_v() { return v_local_v; }
++ inline double get_V_north() const { return v_local_v[0]; }
++ inline double get_V_east() const { return v_local_v[1]; }
++ inline double get_V_down() const { return v_local_v[2]; }
++ inline void set_Velocities_Local( double north, double east, double down ) {
++ v_local_v[0] = north;
++ v_local_v[1] = east;
++ v_local_v[2] = down;
++ }
++
++ FG_VECTOR_3 v_local_rel_ground_v; // V rel w.r.t. earth surface
++ // inline double * get_V_local_rel_ground_v() { return v_local_rel_ground_v; }
++ // inline double get_V_north_rel_ground() const {
++ // return v_local_rel_ground_v[0];
++ // }
++ // inline double get_V_east_rel_ground() const {
++ // return v_local_rel_ground_v[1];
++ // }
++ // inline double get_V_down_rel_ground() const {
++ // return v_local_rel_ground_v[2];
++ // }
++ /* inline void set_Velocities_Ground(double north, double east, double down) {
++ v_local_rel_ground_v[0] = north;
++ v_local_rel_ground_v[1] = east;
++ v_local_rel_ground_v[2] = down;
++ } */
++
++ FG_VECTOR_3 v_local_airmass_v; // velocity of airmass (steady winds)
++ // inline double * get_V_local_airmass_v() { return v_local_airmass_v; }
++ // inline double get_V_north_airmass() const { return v_local_airmass_v[0]; }
++ // inline double get_V_east_airmass() const { return v_local_airmass_v[1]; }
++ // inline double get_V_down_airmass() const { return v_local_airmass_v[2]; }
++ /* inline void set_Velocities_Local_Airmass( double north, double east,
++ double down)
++ {
++ v_local_airmass_v[0] = north;
++ v_local_airmass_v[1] = east;
++ v_local_airmass_v[2] = down;
++ } */
++
++ FG_VECTOR_3 v_local_rel_airmass_v; // velocity of veh. relative to
++ // airmass
++ // inline double * get_V_local_rel_airmass_v() {
++ //return v_local_rel_airmass_v;
++ //}
++ // inline double get_V_north_rel_airmass() const {
++ //return v_local_rel_airmass_v[0];
++ //}
++ // inline double get_V_east_rel_airmass() const {
++ //return v_local_rel_airmass_v[1];
++ //}
++ // inline double get_V_down_rel_airmass() const {
++ //return v_local_rel_airmass_v[2];
++ //}
++ /* inline void set_Velocities_Local_Rel_Airmass( double north, double east,
++ double down)
++ {
++ v_local_rel_airmass_v[0] = north;
++ v_local_rel_airmass_v[1] = east;
++ v_local_rel_airmass_v[2] = down;
++ } */
++
++ FG_VECTOR_3 v_local_gust_v; // linear turbulence components, L frame
++ // inline double * get_V_local_gust_v() { return v_local_gust_v; }
++ // inline double get_U_gust() const { return v_local_gust_v[0]; }
++ // inline double get_V_gust() const { return v_local_gust_v[1]; }
++ // inline double get_W_gust() const { return v_local_gust_v[2]; }
++ /* inline void set_Velocities_Gust( double u, double v, double w)
++ {
++ v_local_gust_v[0] = u;
++ v_local_gust_v[1] = v;
++ v_local_gust_v[2] = w;
++ } */
++
++ FG_VECTOR_3 v_wind_body_v; // Wind-relative velocities in body axis
++ // inline double * get_V_wind_body_v() { return v_wind_body_v; }
++ // inline double get_U_body() const { return v_wind_body_v[0]; }
++ // inline double get_V_body() const { return v_wind_body_v[1]; }
++ // inline double get_W_body() const { return v_wind_body_v[2]; }
++ /* inline void set_Velocities_Wind_Body( double u, double v, double w)
++ {
++ v_wind_body_v[0] = u;
++ v_wind_body_v[1] = v;
++ v_wind_body_v[2] = w;
++ } */
++
++ double v_rel_wind, v_true_kts, v_rel_ground, v_inertial;
++ double v_ground_speed, v_equiv, v_equiv_kts;
++ double v_calibrated, v_calibrated_kts;
++
++ // inline double get_V_rel_wind() const { return v_rel_wind; }
++ // inline void set_V_rel_wind(double wind) { v_rel_wind = wind; }
++
++ // inline double get_V_true_kts() const { return v_true_kts; }
++ // inline void set_V_true_kts(double kts) { v_true_kts = kts; }
++
++ // inline double get_V_rel_ground() const { return v_rel_ground; }
++ // inline void set_V_rel_ground( double v ) { v_rel_ground = v; }
++
++ // inline double get_V_inertial() const { return v_inertial; }
++ // inline void set_V_inertial(double v) { v_inertial = v; }
++
++ // inline double get_V_ground_speed() const { return v_ground_speed; }
++ // inline void set_V_ground_speed( double v) { v_ground_speed = v; }
++
++ // inline double get_V_equiv() const { return v_equiv; }
++ // inline void set_V_equiv( double v ) { v_equiv = v; }
++
++ inline double get_V_equiv_kts() const { return v_equiv_kts; }
++ inline void set_V_equiv_kts( double kts ) { v_equiv_kts = kts; }
++
++ // inline double get_V_calibrated() const { return v_calibrated; }
++ // inline void set_V_calibrated( double v ) { v_calibrated = v; }
++
++ // inline double get_V_calibrated_kts() const { return v_calibrated_kts; }
++ // inline void set_V_calibrated_kts( double kts ) { v_calibrated_kts = kts; }
++
++ FG_VECTOR_3 omega_body_v; // Angular B rates
++ // inline double * get_Omega_body_v() { return omega_body_v; }
++ inline double get_P_body() const { return omega_body_v[0]; }
++ inline double get_Q_body() const { return omega_body_v[1]; }
++ inline double get_R_body() const { return omega_body_v[2]; }
++ inline void set_Omega_Body( double p, double q, double r ) {
++ omega_body_v[0] = p;
++ omega_body_v[1] = q;
++ omega_body_v[2] = r;
++ }
++
++ FG_VECTOR_3 omega_local_v; // Angular L rates
++ // inline double * get_Omega_local_v() { return omega_local_v; }
++ // inline double get_P_local() const { return omega_local_v[0]; }
++ // inline double get_Q_local() const { return omega_local_v[1]; }
++ // inline double get_R_local() const { return omega_local_v[2]; }
++ /* inline void set_Omega_Local( double p, double q, double r ) {
++ omega_local_v[0] = p;
++ omega_local_v[1] = q;
++ omega_local_v[2] = r;
++ } */
++
++ FG_VECTOR_3 omega_total_v; // Diff btw B & L
++ // inline double * get_Omega_total_v() { return omega_total_v; }
++ // inline double get_P_total() const { return omega_total_v[0]; }
++ // inline double get_Q_total() const { return omega_total_v[1]; }
++ // inline double get_R_total() const { return omega_total_v[2]; }
++ /* inline void set_Omega_Total( double p, double q, double r ) {
++ omega_total_v[0] = p;
++ omega_total_v[1] = q;
++ omega_total_v[2] = r;
++ } */
++
++ FG_VECTOR_3 euler_rates_v;
++ // inline double * get_Euler_rates_v() { return euler_rates_v; }
++ // inline double get_Phi_dot() const { return euler_rates_v[0]; }
++ // inline double get_Theta_dot() const { return euler_rates_v[1]; }
++ // inline double get_Psi_dot() const { return euler_rates_v[2]; }
++ /* inline void set_Euler_Rates( double phi, double theta, double psi ) {
++ euler_rates_v[0] = phi;
++ euler_rates_v[1] = theta;
++ euler_rates_v[2] = psi;
++ } */
++
++ FG_VECTOR_3 geocentric_rates_v; // Geocentric linear velocities
++ // inline double * get_Geocentric_rates_v() { return geocentric_rates_v; }
++ inline double get_Latitude_dot() const { return geocentric_rates_v[0]; }
++ inline double get_Longitude_dot() const { return geocentric_rates_v[1]; }
++ inline double get_Radius_dot() const { return geocentric_rates_v[2]; }
++ inline void set_Geocentric_Rates( double lat, double lon, double rad ) {
++ geocentric_rates_v[0] = lat;
++ geocentric_rates_v[1] = lon;
++ geocentric_rates_v[2] = rad;
++ }
++
++ /*=============================== Positions ===============================*/
++
++ FG_VECTOR_3 geocentric_position_v;
++ // inline double * get_Geocentric_position_v() {
++ // return geocentric_position_v;
++ // }
++ inline double get_Lat_geocentric() const {
++ return geocentric_position_v[0];
++ }
++ inline double get_Lon_geocentric() const {
++ return geocentric_position_v[1];
++ }
++ inline double get_Radius_to_vehicle() const {
++ return geocentric_position_v[2];
++ }
++ inline void set_Radius_to_vehicle(double radius) {
++ geocentric_position_v[2] = radius;
++ }
++
++ inline void set_Geocentric_Position( double lat, double lon, double rad ) {
++ geocentric_position_v[0] = lat;
++ geocentric_position_v[1] = lon;
++ geocentric_position_v[2] = rad;
++ }
++
++ FG_VECTOR_3 geodetic_position_v;
++ // inline double * get_Geodetic_position_v() { return geodetic_position_v; }
++ inline double get_Latitude() const { return geodetic_position_v[0]; }
++ inline void set_Latitude(double lat) { geodetic_position_v[0] = lat; }
++ inline double get_Longitude() const { return geodetic_position_v[1]; }
++ inline void set_Longitude(double lon) { geodetic_position_v[1] = lon; }
++ inline double get_Altitude() const { return geodetic_position_v[2]; }
++ inline void set_Altitude(double altitude) {
++ geodetic_position_v[2] = altitude;
++ }
++ inline void set_Geodetic_Position( double lat, double lon, double alt ) {
++ geodetic_position_v[0] = lat;
++ geodetic_position_v[1] = lon;
++ geodetic_position_v[2] = alt;
++ }
++
++ FG_VECTOR_3 euler_angles_v;
++ // inline double * get_Euler_angles_v() { return euler_angles_v; }
++ inline double get_Phi() const { return euler_angles_v[0]; }
++ inline double get_Theta() const { return euler_angles_v[1]; }
++ inline double get_Psi() const { return euler_angles_v[2]; }
++ inline void set_Euler_Angles( double phi, double theta, double psi ) {
++ euler_angles_v[0] = phi;
++ euler_angles_v[1] = theta;
++ euler_angles_v[2] = psi;
++ }
++
++
++ /*======================= Miscellaneous quantities ========================*/
++
++ double t_local_to_body_m[3][3]; // Transformation matrix L to B
++ // inline double * get_T_local_to_body_m() { return t_local_to_body_m; }
++ inline double get_T_local_to_body_11() const {
++ return t_local_to_body_m[0][0];
++ }
++ inline double get_T_local_to_body_12() const {
++ return t_local_to_body_m[0][1];
++ }
++ inline double get_T_local_to_body_13() const {
++ return t_local_to_body_m[0][2];
++ }
++ inline double get_T_local_to_body_21() const {
++ return t_local_to_body_m[1][0];
++ }
++ inline double get_T_local_to_body_22() const {
++ return t_local_to_body_m[1][1];
++ }
++ inline double get_T_local_to_body_23() const {
++ return t_local_to_body_m[1][2];
++ }
++ inline double get_T_local_to_body_31() const {
++ return t_local_to_body_m[2][0];
++ }
++ inline double get_T_local_to_body_32() const {
++ return t_local_to_body_m[2][1];
++ }
++ inline double get_T_local_to_body_33() const {
++ return t_local_to_body_m[2][2];
++ }
++ inline void set_T_Local_to_Body( double m[3][3] ) {
++ int i, j;
++ for ( i = 0; i < 3; i++ ) {
++ for ( j = 0; j < 3; j++ ) {
++ t_local_to_body_m[i][j] = m[i][j];
++ }
++ }
++ }
++
++ double gravity; // Local acceleration due to G
++ // inline double get_Gravity() const { return gravity; }
++ // inline void set_Gravity(double g) { gravity = g; }
++
++ double centrifugal_relief; // load factor reduction due to speed
++ // inline double get_Centrifugal_relief() const { return centrifugal_relief; }
++ // inline void set_Centrifugal_relief(double cr) { centrifugal_relief = cr; }
++
++ double alpha, beta, alpha_dot, beta_dot; // in radians
++ inline double get_Alpha() const { return alpha; }
++ inline void set_Alpha( double a ) { alpha = a; }
++ inline double get_Beta() const { return beta; }
++ inline void set_Beta( double b ) { beta = b; }
++ // inline double get_Alpha_dot() const { return alpha_dot; }
++ // inline void set_Alpha_dot( double ad ) { alpha_dot = ad; }
++ // inline double get_Beta_dot() const { return beta_dot; }
++ // inline void set_Beta_dot( double bd ) { beta_dot = bd; }
++
++ double cos_alpha, sin_alpha, cos_beta, sin_beta;
++ // inline double get_Cos_alpha() const { return cos_alpha; }
++ // inline void set_Cos_alpha( double ca ) { cos_alpha = ca; }
++ // inline double get_Sin_alpha() const { return sin_alpha; }
++ // inline void set_Sin_alpha( double sa ) { sin_alpha = sa; }
++ // inline double get_Cos_beta() const { return cos_beta; }
++ // inline void set_Cos_beta( double cb ) { cos_beta = cb; }
++ // inline double get_Sin_beta() const { return sin_beta; }
++ // inline void set_Sin_beta( double sb ) { sin_beta = sb; }
++
++ double cos_phi, sin_phi, cos_theta, sin_theta, cos_psi, sin_psi;
++ // inline double get_Cos_phi() const { return cos_phi; }
++ // inline void set_Cos_phi( double cp ) { cos_phi = cp; }
++ // inline double get_Sin_phi() const { return sin_phi; }
++ // inline void set_Sin_phi( double sp ) { sin_phi = sp; }
++ // inline double get_Cos_theta() const { return cos_theta; }
++ // inline void set_Cos_theta( double ct ) { cos_theta = ct; }
++ // inline double get_Sin_theta() const { return sin_theta; }
++ // inline void set_Sin_theta( double st ) { sin_theta = st; }
++ // inline double get_Cos_psi() const { return cos_psi; }
++ // inline void set_Cos_psi( double cp ) { cos_psi = cp; }
++ // inline double get_Sin_psi() const { return sin_psi; }
++ // inline void set_Sin_psi( double sp ) { sin_psi = sp; }
++
++ double gamma_vert_rad, gamma_horiz_rad; // Flight path angles
++ inline double get_Gamma_vert_rad() const { return gamma_vert_rad; }
++ inline void set_Gamma_vert_rad( double gv ) { gamma_vert_rad = gv; }
++ // inline double get_Gamma_horiz_rad() const { return gamma_horiz_rad; }
++ // inline void set_Gamma_horiz_rad( double gh ) { gamma_horiz_rad = gh; }
++
++ double sigma, density, v_sound, mach_number;
++ // inline double get_Sigma() const { return sigma; }
++ // inline void set_Sigma( double s ) { sigma = s; }
++ // inline double get_Density() const { return density; }
++ // inline void set_Density( double d ) { density = d; }
++ // inline double get_V_sound() const { return v_sound; }
++ // inline void set_V_sound( double v ) { v_sound = v; }
++ // inline double get_Mach_number() const { return mach_number; }
++ // inline void set_Mach_number( double m ) { mach_number = m; }
++
++ double static_pressure, total_pressure, impact_pressure;
++ double dynamic_pressure;
++ // inline double get_Static_pressure() const { return static_pressure; }
++ // inline void set_Static_pressure( double sp ) { static_pressure = sp; }
++ // inline double get_Total_pressure() const { return total_pressure; }
++ // inline void set_Total_pressure( double tp ) { total_pressure = tp; }
++ // inline double get_Impact_pressure() const { return impact_pressure; }
++ // inline void set_Impact_pressure( double ip ) { impact_pressure = ip; }
++ // inline double get_Dynamic_pressure() const { return dynamic_pressure; }
++ // inline void set_Dynamic_pressure( double dp ) { dynamic_pressure = dp; }
++
++ double static_temperature, total_temperature;
++ // inline double get_Static_temperature() const { return static_temperature; }
++ // inline void set_Static_temperature( double t ) { static_temperature = t; }
++ // inline double get_Total_temperature() const { return total_temperature; }
++ // inline void set_Total_temperature( double t ) { total_temperature = t; }
++
++ double sea_level_radius, earth_position_angle;
++ inline double get_Sea_level_radius() const { return sea_level_radius; }
++ inline void set_Sea_level_radius( double r ) { sea_level_radius = r; }
++ inline double get_Earth_position_angle() const {
++ return earth_position_angle;
++ }
++ inline void set_Earth_position_angle(double a) {
++ earth_position_angle = a;
++ }
++
++ double runway_altitude, runway_latitude, runway_longitude;
++ double runway_heading;
++ inline double get_Runway_altitude() const { return runway_altitude; }
++ inline void set_Runway_altitude( double alt ) { runway_altitude = alt; }
++ // inline double get_Runway_latitude() const { return runway_latitude; }
++ // inline void set_Runway_latitude( double lat ) { runway_latitude = lat; }
++ // inline double get_Runway_longitude() const { return runway_longitude; }
++ // inline void set_Runway_longitude( double lon ) { runway_longitude = lon; }
++ // inline double get_Runway_heading() const { return runway_heading; }
++ // inline void set_Runway_heading( double h ) { runway_heading = h; }
++
++ double radius_to_rwy;
++ // inline double get_Radius_to_rwy() const { return radius_to_rwy; }
++ // inline void set_Radius_to_rwy( double r ) { radius_to_rwy = r; }
++
++ FG_VECTOR_3 d_cg_rwy_local_v; // CG rel. to rwy in local coords
++ // inline double * get_D_cg_rwy_local_v() { return d_cg_rwy_local_v; }
++ // inline double get_D_cg_north_of_rwy() const { return d_cg_rwy_local_v[0]; }
++ // inline double get_D_cg_east_of_rwy() const { return d_cg_rwy_local_v[1]; }
++ // inline double get_D_cg_above_rwy() const { return d_cg_rwy_local_v[2]; }
++ /* inline void set_CG_Rwy_Local( double north, double east, double above )
++ {
++ d_cg_rwy_local_v[0] = north;
++ d_cg_rwy_local_v[1] = east;
++ d_cg_rwy_local_v[2] = above;
++ } */
++
++ FG_VECTOR_3 d_cg_rwy_rwy_v; // CG relative to rwy, in rwy coordinates
++ // inline double * get_D_cg_rwy_rwy_v() { return d_cg_rwy_rwy_v; }
++ // inline double get_X_cg_rwy() const { return d_cg_rwy_rwy_v[0]; }
++ // inline double get_Y_cg_rwy() const { return d_cg_rwy_rwy_v[1]; }
++ // inline double get_H_cg_rwy() const { return d_cg_rwy_rwy_v[2]; }
++ /* inline void set_CG_Rwy_Rwy( double x, double y, double h )
++ {
++ d_cg_rwy_rwy_v[0] = x;
++ d_cg_rwy_rwy_v[1] = y;
++ d_cg_rwy_rwy_v[2] = h;
++ } */
++
++ FG_VECTOR_3 d_pilot_rwy_local_v; // pilot rel. to rwy in local coords
++ // inline double * get_D_pilot_rwy_local_v() { return d_pilot_rwy_local_v; }
++ // inline double get_D_pilot_north_of_rwy() const {
++ //return d_pilot_rwy_local_v[0];
++ // }
++ // inline double get_D_pilot_east_of_rwy() const {
++// return d_pilot_rwy_local_v[1];
++// }
++ // inline double get_D_pilot_above_rwy() const {
++ //return d_pilot_rwy_local_v[2];
++ // }
++ /* inline void set_Pilot_Rwy_Local( double north, double east, double above )
++ {
++ d_pilot_rwy_local_v[0] = north;
++ d_pilot_rwy_local_v[1] = east;
++ d_pilot_rwy_local_v[2] = above;
++ } */
++
++ FG_VECTOR_3 d_pilot_rwy_rwy_v; // pilot rel. to rwy, in rwy coords.
++ // inline double * get_D_pilot_rwy_rwy_v() { return d_pilot_rwy_rwy_v; }
++ // inline double get_X_pilot_rwy() const { return d_pilot_rwy_rwy_v[0]; }
++ // inline double get_Y_pilot_rwy() const { return d_pilot_rwy_rwy_v[1]; }
++ // inline double get_H_pilot_rwy() const { return d_pilot_rwy_rwy_v[2]; }
++ /* inline void set_Pilot_Rwy_Rwy( double x, double y, double h )
++ {
++ d_pilot_rwy_rwy_v[0] = x;
++ d_pilot_rwy_rwy_v[1] = y;
++ d_pilot_rwy_rwy_v[2] = h;
++ } */
++
++ double climb_rate; // in feet per second
++ inline double get_Climb_Rate() const { return climb_rate; }
++ inline void set_Climb_Rate(double rate) { climb_rate = rate; }
++
++ FGTimeStamp valid_stamp; // time this record is valid
++ FGTimeStamp next_stamp; // time this record is valid
++ inline FGTimeStamp get_time_stamp() const { return valid_stamp; }
++ inline void stamp_time() { valid_stamp = next_stamp; next_stamp.stamp(); }
++
++ // Extrapolate FDM based on time_offset (in usec)
++ void extrapolate( int time_offset );
++
++ // sin/cos lat_geocentric
++ double sin_lat_geocentric;
++ double cos_lat_geocentric;
++ inline void set_sin_lat_geocentric(double parm) {
++ sin_lat_geocentric = sin(parm);
++ }
++ inline void set_cos_lat_geocentric(double parm) {
++ cos_lat_geocentric = cos(parm);
++ }
++ inline double get_sin_lat_geocentric(void) const {
++ return sin_lat_geocentric;
++ }
++ inline double get_cos_lat_geocentric(void) const {
++ return cos_lat_geocentric;
++ }
++
++ double sin_longitude;
++ double cos_longitude;
++ inline void set_sin_cos_longitude(double parm) {
++ sin_longitude = sin(parm);
++ cos_longitude = cos(parm);
++ }
++ inline double get_sin_longitude(void) const {
++ return sin_longitude;
++ }
++ inline double get_cos_longitude(void) const {
++ return cos_longitude;
++ }
++
++ double sin_latitude;
++ double cos_latitude;
++ inline void set_sin_cos_latitude(double parm) {
++ sin_latitude = sin(parm);
++ cos_latitude = cos(parm);
++ }
++ inline double get_sin_latitude(void) const {
++ return sin_latitude;
++ }
++ inline double get_cos_latitude(void) const {
++ return cos_latitude;
++ }
++};
++
++
++extern FGInterface cur_fdm_state;
++
++
++// General interface to the flight model routines
++
++// Initialize the flight model parameters
++int fgFDMInit(int model, FGInterface& f, double dt);
++
++// Run multiloop iterations of the flight model
++int fgFDMUpdate(int model, FGInterface& f, int multiloop, int jitter);
++
++// Set the altitude (force)
++void fgFDMForceAltitude(int model, double alt_meters);
++
++// Set the local ground elevation
++void fgFDMSetGroundElevation(int model, double alt_meters);
++
++
++#endif // _FLIGHT_HXX
++
++
++// $Log$
++// Revision 1.14 1999/04/03 04:20:04 curt
++// Optimizations (tm) by Norman Vine.
++//
++// Revision 1.13 1999/02/05 21:29:02 curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.12 1999/01/20 13:42:23 curt
++// Tweaked FDM interface.
++// Testing check sum support for NMEA serial output.
++//
++// Revision 1.11 1999/01/19 17:52:07 curt
++// Working on being able to extrapolate a new position and orientation
++// based on a position, orientation, and time offset.
++//
++// Revision 1.10 1999/01/09 13:37:33 curt
++// Convert fgTIMESTAMP to FGTimeStamp which holds usec instead of ms.
++//
++// Revision 1.9 1999/01/08 19:27:38 curt
++// Fixed AOA reading on HUD.
++// Continued work on time jitter compensation.
++//
++// Revision 1.8 1999/01/08 03:23:52 curt
++// Beginning work on compensating for sim time vs. real world time "jitter".
++//
++// Revision 1.7 1998/12/18 23:37:09 curt
++// Collapsed out the FGState variables not currently needed. They are just
++// commented out and can be readded easily at any time. The point of this
++// exersize is to determine which variables were or were not currently being
++// used.
++//
++// Revision 1.6 1998/12/05 15:54:12 curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.5 1998/12/04 01:29:40 curt
++// Stubbed in a new flight model called "External" which is expected to be driven
++// from some external source.
++//
++// Revision 1.4 1998/12/03 04:25:03 curt
++// Working on fixing up new fgFLIGHT class.
++//
++// Revision 1.3 1998/12/03 01:16:41 curt
++// Converted fgFLIGHT to a class.
++//
++// Revision 1.2 1998/10/16 23:27:41 curt
++// C++-ifying.
++//
++// Revision 1.1 1998/10/16 20:16:44 curt
++// Renamed flight.[ch] to flight.[ch]xx
++//
++// Revision 1.20 1998/09/29 14:57:39 curt
++// c++-ified comments.
++//
++// Revision 1.19 1998/09/29 02:02:41 curt
++// Added a rate of climb calculation.
++//
++// Revision 1.18 1998/07/30 23:44:36 curt
++// Beginning to add support for multiple flight models.
++//
++// Revision 1.17 1998/07/12 03:08:28 curt
++// Added fgFlightModelSetAltitude() to force the altitude to something
++// other than the current altitude. LaRCsim doesn't let you do this by just
++// changing FG_Altitude.
++//
++// Revision 1.16 1998/04/22 13:26:20 curt
++// C++ - ifing the code a bit.
++//
++// Revision 1.15 1998/04/21 16:59:33 curt
++// Integrated autopilot.
++// Prepairing for C++ integration.
++//
++// Revision 1.14 1998/02/07 15:29:37 curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.13 1998/01/24 00:04:59 curt
++// misc. tweaks.
++//
++// Revision 1.12 1998/01/22 02:59:32 curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.11 1998/01/19 19:27:03 curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.10 1997/12/10 22:37:43 curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.9 1997/09/04 02:17:33 curt
++// Shufflin' stuff.
++//
++// Revision 1.8 1997/08/27 03:30:06 curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.7 1997/07/23 21:52:19 curt
++// Put comments around the text after an #endif for increased portability.
++//
++// Revision 1.6 1997/06/21 17:52:22 curt
++// Continue directory shuffling ... everything should be compilable/runnable
++// again.
++//
++// Revision 1.5 1997/06/21 17:12:49 curt
++// Capitalized subdirectory names.
++//
++// Revision 1.4 1997/05/29 22:39:57 curt
++// Working on incorporating the LaRCsim flight model.
++//
++// Revision 1.3 1997/05/29 02:32:25 curt
++// Starting to build generic flight model interface.
++//
++// Revision 1.2 1997/05/23 15:40:37 curt
++// Added GNU copyright headers.
++//
++// Revision 1.1 1997/05/16 16:04:45 curt
++// Initial revision.
++//
--- /dev/null
--- /dev/null
++if ENABLE_XMESA_FX
++DEFS += -DXMESA -DFX
++endif
++
++noinst_LIBRARIES = libGUI.a
++
++libGUI_a_SOURCES = gui.cxx gui.h
++
++INCLUDES += -I$(top_builddir) \
++ -I$(top_builddir)/Lib \
++ -I$(top_builddir)/Lib/plib/include \
++ -I$(top_builddir)/Simulator
--- /dev/null
--- /dev/null
++/**************************************************************************
++ * gui.cxx
++ *
++ * Written 1998 by Durk Talsma, started Juni, 1998. For the flight gear
++ * project.
++ *
++ * 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$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++
++#include <Include/compiler.h>
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#if defined(FX) && defined(XMESA)
++# include <GL/xmesa.h>
++#endif
++
++#include STL_STRING
++
++#include <stdlib.h>
++#include <string.h>
++
++#include <Include/general.hxx>
++#include <Main/options.hxx>
++
++#include "gui.h"
++
++FG_USING_STD(string);
++
++
++puMenuBar *mainMenuBar;
++puButton *hideMenuButton;
++puDialogBox *dialogBox;
++puText *dialogBoxMessage;
++puOneShot *dialogBoxOkButton;
++puText *timerText;
++
++/* --------------------------------------------------------------------
++ Mouse stuff
++ ---------------------------------------------------------------------*/
++
++void guiMotionFunc ( int x, int y )
++{
++ puMouse ( x, y ) ;
++ glutPostRedisplay () ;
++}
++
++
++void guiMouseFunc(int button, int updown, int x, int y)
++{
++ puMouse (button, updown, x,y);
++ glutPostRedisplay ();
++}
++
++/* -----------------------------------------------------------------------
++ the Gui callback functions
++ ____________________________________________________________________*/
++
++void hideMenuCb (puObject *cb)
++{
++ if (cb -> getValue () )
++ {
++ mainMenuBar -> reveal();
++ printf("Showing Menu");
++ hideMenuButton -> setLegend ("Hide Menu");
++ }
++ else
++ {
++ mainMenuBar -> hide ();
++ printf("Hiding Menu");
++ hideMenuButton -> setLegend ("Show Menu");
++ }
++}
++
++ void goAwayCb (puObject *)
++{
++ delete dialogBox;
++ dialogBox = NULL;
++}
++
++void mkDialog (char *txt)
++{
++ dialogBox = new puDialogBox (150, 50);
++ {
++ new puFrame (0,0,400, 100);
++ dialogBoxMessage = new puText (10, 70);
++ dialogBoxMessage -> setLabel (txt);
++ dialogBoxOkButton = new puOneShot (180, 10, 240, 50);
++ dialogBoxOkButton -> setLegend ("OK");
++ dialogBoxOkButton -> makeReturnDefault (TRUE );
++ dialogBoxOkButton -> setCallback (goAwayCb);
++ }
++ dialogBox -> close();
++ dialogBox -> reveal();
++}
++
++void notCb (puObject *)
++{
++ mkDialog ("This function isn't implemented yet");
++}
++
++void helpCb (puObject *)
++{
++#if defined(FX) && !defined(WIN32)
++# if defined(XMESA_FX_FULLSCREEN) && defined(XMESA_FX_WINDOW)
++ if ( global_fullscreen ) {
++ global_fullscreen = false;
++ XMesaSetFXmode( XMESA_FX_WINDOW );
++ }
++# endif
++#endif
++
++#if !defined(WIN32)
++ string url = "http://www.flightgear.org/Docs/InstallGuide/getstart.html";
++ string command;
++
++ if ( system("xwininfo -name Netscape > /dev/null 2>&1") == 0 ) {
++ command = "netscape -remote \"openURL(" + url + ")\" &";
++ } else {
++ command = "netscape " + url + " &";
++ }
++
++ system( command.c_str() );
++ string text = "Help started in netscape window.";
++#else
++ string text = "Help not yet implimented for Win32.";
++#endif
++
++ mkDialog ( (char*)text.c_str() );
++}
++
++/* -----------------------------------------------------------------------
++ The menu stuff
++ ---------------------------------------------------------------------*/
++char *fileSubmenu [] = { "Exit", "Close", "---------", "Print", "---------", "Save", "New", NULL };
++char *editSubmenu [] = { "Edit text", NULL };
++char *viewSubmenu [] = { "Cockpit View > ", "View >","------------", "View options...", NULL };
++char *aircraftSubmenu [] = { "Autopilot ...", "Engine ...", "Navigation", "Communication", NULL};
++char *environmentSubmenu [] = { "Time & Date...", "Terrain ...", "Weather", NULL};
++char *optionsSubmenu [] = { "Preferences", "Realism & Reliablity...", NULL};
++char *helpSubmenu [] = { "About...", "Help", NULL };
++
++puCallback fileSubmenuCb [] = { notCb, notCb, NULL, notCb, NULL, notCb, notCb, NULL};
++puCallback editSubmenuCb [] = { notCb, NULL };
++puCallback viewSubmenuCb [] = { notCb, notCb, NULL, notCb, NULL };
++puCallback aircraftSubmenuCb [] = { notCb, notCb, notCb,notCb, NULL };
++puCallback environmentSubmenuCb [] = { notCb, notCb, notCb, NULL };
++puCallback optionsSubmenuCb [] = { notCb, notCb, NULL};
++puCallback helpSubmenuCb [] = { notCb, helpCb, NULL };
++
++
++
++/* -------------------------------------------------------------------------
++ init the gui
++ _____________________________________________________________________*/
++
++
++
++void guiInit()
++{
++ char *mesa_win_state;
++
++ // Initialize PUI
++ puInit();
++
++ if ( current_options.get_mouse_pointer() == 0 ) {
++ // no preference specified for mouse pointer, attempt to autodetect...
++ // Determine if we need to render the cursor, or if the windowing
++ // system will do it. First test if we are rendering with glide.
++ 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') ) {
++ puShowCursor ();
++ }
++ }
++ }
++ } else if ( current_options.get_mouse_pointer() == 1 ) {
++ // don't show pointer
++ } else if ( current_options.get_mouse_pointer() == 2 ) {
++ // force showing pointer
++ puShowCursor();
++ }
++
++ // puSetDefaultStyle ( PUSTYLE_SMALL_BEVELLED );
++ puSetDefaultStyle ( PUSTYLE_DEFAULT );
++ // puSetDefaultColourScheme (0.2, 0.4, 0.8, 0.5);
++ puSetDefaultColourScheme (0.8, 0.8, 0.8, 0.5);
++
++ /* OK the rest is largerly put in here to mimick Steve Baker's
++ "complex" example It should change in future versions */
++
++ // timerText = new puText (300, 10);
++ // timerText -> setColour (PUCOL_LABEL, 1.0, 1.0, 1.0);
++
++ /* Make a button to hide the menu bar */
++ hideMenuButton = new puButton (10,10, 150, 50);
++ hideMenuButton -> setValue (TRUE);
++ hideMenuButton -> setLegend ("Hide Menu");
++ hideMenuButton -> setCallback (hideMenuCb);
++ hideMenuButton -> makeReturnDefault (TRUE);
++ hideMenuButton -> hide();
++
++ // Make the menu bar
++ mainMenuBar = new puMenuBar ();
++ mainMenuBar -> add_submenu ("File", fileSubmenu, fileSubmenuCb);
++ mainMenuBar -> add_submenu ("Edit", editSubmenu, editSubmenuCb);
++ mainMenuBar -> add_submenu ("View", viewSubmenu, viewSubmenuCb);
++ mainMenuBar -> add_submenu ("Aircraft", aircraftSubmenu, aircraftSubmenuCb);
++ mainMenuBar -> add_submenu ("Environment", environmentSubmenu,
++ environmentSubmenuCb);
++ mainMenuBar -> add_submenu ("Options", optionsSubmenu, optionsSubmenuCb);
++ mainMenuBar -> add_submenu ("Help", helpSubmenu, helpSubmenuCb);
++ mainMenuBar-> close ();
++}
--- /dev/null
--- /dev/null
++/**************************************************************************
++ * gui.h
++ *
++ * Written 1998 by Durk Talsma, started Juni, 1998. For the flight gear
++ * project.
++ *
++ * 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$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++
++#ifndef _GUI_H_
++#define _GUI_H_
++
++#include <pu.h>
++
++extern puMenuBar *mainMenuBar;
++extern puButton *hideMenuButton;
++extern puDialogBox *dialogBox;
++extern puText *dialogBoxMessage;
++extern puOneShot *dialogBoxOkButton;
++extern puText *timerText;
++
++extern void guiMotionFunc ( int x, int y );
++extern void guiMouseFunc(int button, int updown, int x, int y);
++extern void guiInit();
++
++extern void mkDialog (char *txt);
++
++#endif // _GUI_H_
--- /dev/null
--- /dev/null
++/*******************************************************************************
++
++ Module: FGAircraft.cpp
++ Author: Jon S. Berndt
++ Date started: 12/12/98
++ Purpose: Encapsulates an aircraft
++ Called by: FGFDMExec
++
++ ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ 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., 59 Temple
++ Place - Suite 330, Boston, MA 02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++Models the aircraft reactions and forces. This class is instantiated by the
++FGFDMExec class and scheduled as an FDM entry. LoadAircraft() is supplied with a
++name of a valid, registered aircraft, and the data file is parsed.
++
++HISTORY
++--------------------------------------------------------------------------------
++12/12/98 JSB Created
++
++********************************************************************************
++COMMENTS, REFERENCES, and NOTES
++********************************************************************************
++[1] Cooke, Zyda, Pratt, and McGhee, "NPSNET: Flight Simulation Dynamic Modeling
++ Using Quaternions", Presence, Vol. 1, No. 4, pp. 404-420 Naval Postgraduate
++ School, January 1994
++[2] D. M. Henderson, "Euler Angles, Quaternions, and Transformation Matrices",
++ JSC 12960, July 1977
++[3] Richard E. McFarland, "A Standard Kinematic Model for Flight Simulation at
++ NASA-Ames", NASA CR-2497, January 1975
++[4] Barnes W. McCormick, "Aerodynamics, Aeronautics, and Flight Mechanics",
++ Wiley & Sons, 1979 ISBN 0-471-03032-5
++[5] Bernard Etkin, "Dynamics of Flight, Stability and Control", Wiley & Sons,
++ 1982 ISBN 0-471-08936-2
++
++The aerodynamic coefficients used in this model are:
++
++Longitudinal
++ CL0 - Reference lift at zero alpha
++ CD0 - Reference drag at zero alpha
++ CDM - Drag due to Mach
++ CLa - Lift curve slope (w.r.t. alpha)
++ CDa - Drag curve slope (w.r.t. alpha)
++ CLq - Lift due to pitch rate
++ CLM - Lift due to Mach
++ CLadt - Lift due to alpha rate
++
++ Cmadt - Pitching Moment due to alpha rate
++ Cm0 - Reference Pitching moment at zero alpha
++ Cma - Pitching moment slope (w.r.t. alpha)
++ Cmq - Pitch damping (pitch moment due to pitch rate)
++ CmM - Pitch Moment due to Mach
++
++Lateral
++ Cyb - Side force due to sideslip
++ Cyr - Side force due to yaw rate
++
++ Clb - Dihedral effect (roll moment due to sideslip)
++ Clp - Roll damping (roll moment due to roll rate)
++ Clr - Roll moment due to yaw rate
++ Cnb - Weathercocking stability (yaw moment due to sideslip)
++ Cnp - Rudder adverse yaw (yaw moment due to roll rate)
++ Cnr - Yaw damping (yaw moment due to yaw rate)
++
++Control
++ CLDe - Lift due to elevator
++ CDDe - Drag due to elevator
++ CyDr - Side force due to rudder
++ CyDa - Side force due to aileron
++
++ CmDe - Pitch moment due to elevator
++ ClDa - Roll moment due to aileron
++ ClDr - Roll moment due to rudder
++ CnDr - Yaw moment due to rudder
++ CnDa - Yaw moment due to aileron
++
++This class expects to be run in a directory which contains the subdirectory
++structure shown below (where example aircraft X-15 is shown):
++
++aircraft/
++ X-15/
++ X-15.dat reset00 reset01 reset02 ...
++ CDRAG/
++ a0 a M De
++ CSIDE/
++ b r Dr Da
++ CLIFT/
++ a0 a M adt De
++ CROLL/
++ b p r Da Dr
++ CPITCH/
++ a0 a adt q M De
++ CYAW/
++ b p r Dr Da
++ F-16/
++ F-16.dat reset00 reset01 ...
++ CDRAG/
++ a0 a M De
++ ...
++
++The General Idea
++
++The file structure is arranged so that various modeled aircraft are stored in
++their own subdirectory. Each aircraft subdirectory is named after the aircraft.
++There should be a file present in the specific aircraft subdirectory (e.g.
++aircraft/X-15) with the same name as the directory with a .dat appended. This
++file contains mass properties information, name of aircraft, etc. for the
++aircraft. In that same directory are reset files numbered starting from 0 (two
++digit numbers), e.g. reset03. Within each reset file are values for important
++state variables for specific flight conditions (altitude, airspeed, etc.). Also
++within this directory are the directories containing lookup tables for the
++stability derivatives for the aircraft.
++
++********************************************************************************
++INCLUDES
++*******************************************************************************/
++#include <dirent.h>
++#include <sys/stat.h>
++#include <sys/types.h>
++
++#ifdef FGFS
++# include <Include/compiler.h>
++# ifdef FG_HAVE_STD_INCLUDES
++# include <cmath>
++# else
++# include <math.h>
++# endif
++#else
++# include <cmath>
++#endif
++
++#include "FGAircraft.h"
++#include "FGTranslation.h"
++#include "FGRotation.h"
++#include "FGAtmosphere.h"
++#include "FGState.h"
++#include "FGFDMExec.h"
++#include "FGFCS.h"
++#include "FGPosition.h"
++#include "FGAuxiliary.h"
++#include "FGOutput.h"
++
++/*******************************************************************************
++************************************ CODE **************************************
++*******************************************************************************/
++
++FGAircraft::FGAircraft(FGFDMExec* fdmex) : FGModel(fdmex)
++{
++ int i;
++
++ Name = "FGAircraft";
++
++ for (i=0;i<6;i++) coeff_ctr[i] = 0;
++
++ Axis[LiftCoeff] = "CLIFT";
++ Axis[DragCoeff] = "CDRAG";
++ Axis[SideCoeff] = "CSIDE";
++ Axis[RollCoeff] = "CROLL";
++ Axis[PitchCoeff] = "CPITCH";
++ Axis[YawCoeff] = "CYAW";
++}
++
++
++FGAircraft::~FGAircraft(void)
++{
++}
++
++
++bool FGAircraft::LoadAircraft(string aircraft_path, string engine_path, string fname)
++{
++ string path;
++ string fullpath;
++ string filename;
++ string aircraftDef;
++ string tag;
++ DIR* dir;
++ DIR* coeffdir;
++ struct dirent* dirEntry;
++ struct dirent* coeffdirEntry;
++ struct stat st;
++ struct stat st2;
++ ifstream coeffInFile;
++
++ aircraftDef = aircraft_path + "/" + fname + "/" + fname + ".dat";
++ ifstream aircraftfile(aircraftDef.c_str());
++
++ if (aircraftfile) {
++ aircraftfile >> AircraftName; // String with no embedded spaces
++ aircraftfile >> WingArea; // square feet
++ aircraftfile >> WingSpan; // feet
++ aircraftfile >> cbar; // feet
++ aircraftfile >> Ixx; // slug ft^2
++ aircraftfile >> Iyy; // "
++ aircraftfile >> Izz; // "
++ aircraftfile >> Ixz; // "
++ aircraftfile >> EmptyWeight; // pounds
++ EmptyMass = EmptyWeight / GRAVITY;
++ aircraftfile >> tag;
++
++ numTanks = numEngines = 0;
++ numSelectedOxiTanks = numSelectedFuelTanks = 0;
++
++ while ( !(tag == "EOF") ) {
++ if (tag == "CGLOC") {
++ aircraftfile >> Xcg; // inches
++ aircraftfile >> Ycg; // inches
++ aircraftfile >> Zcg; // inches
++ } else if (tag == "EYEPOINTLOC") {
++ aircraftfile >> Xep; // inches
++ aircraftfile >> Yep; // inches
++ aircraftfile >> Zep; // inches
++ } else if (tag == "TANK") {
++ Tank[numTanks] = new FGTank(aircraftfile);
++ switch(Tank[numTanks]->GetType()) {
++ case FGTank::ttFUEL:
++ numSelectedFuelTanks++;
++ break;
++ case FGTank::ttOXIDIZER:
++ numSelectedOxiTanks++;
++ break;
++ }
++ numTanks++;
++ } else if (tag == "ENGINE") {
++ aircraftfile >> tag;
++ Engine[numEngines] = new FGEngine(FDMExec, engine_path, tag, numEngines);
++ numEngines++;
++ }
++ aircraftfile >> tag;
++ }
++ aircraftfile.close();
++ PutState();
++
++ // Read subdirectory for this aircraft for stability derivative lookup tables:
++ //
++ // Build up the path name to the aircraft file by appending the aircraft
++ // name to the "aircraft/" initial path. Initialize the directory entry
++ // structure dirEntry in preparation for reading through the directory.
++ // Build up a path to each file in the directory sequentially and "stat" it
++ // to see if the entry is a directory or a file. If the entry is a file, then
++ // compare it to each string in the Axis[] array to see which axis the
++ // directory represents: Lift, Drag, Side, Roll, Pitch, Yaw. When the match
++ // is found, go into that directory and search for any coefficient files.
++ // Build a new coefficient by passing the full pathname to the coefficient
++ // file to the FGCoefficient constructor.
++ //
++ // Note: axis_ctr=0 for the Lift "axis", 1 for Drag, 2 for Side force, 3 for
++ // Roll, 4 for Pitch, and 5 for Yaw. The term coeff_ctr merely keeps
++ // track of the number of coefficients registered for each of the
++ // previously mentioned axis.
++
++ path = aircraft_path + "/" + AircraftName + "/";
++ if (dir = opendir(path.c_str())) {
++
++ while (dirEntry = readdir(dir)) {
++ fullpath = path + dirEntry->d_name;
++ stat(fullpath.c_str(),&st);
++ if ((st.st_mode & S_IFMT) == S_IFDIR) {
++ for (int axis_ctr=0; axis_ctr < 6; axis_ctr++) {
++ if (dirEntry->d_name == Axis[axis_ctr]) {
++ if (coeffdir = opendir(fullpath.c_str())) {
++ while (coeffdirEntry = readdir(coeffdir)) {
++ if (coeffdirEntry->d_name[0] != '.') {
++ filename = path + Axis[axis_ctr] + "/" + coeffdirEntry->d_name;
++ stat(filename.c_str(),&st2);
++ if (st2.st_size > 6) {
++ Coeff[axis_ctr][coeff_ctr[axis_ctr]] = new FGCoefficient(FDMExec, filename);
++ coeff_ctr[axis_ctr]++;
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ }
++ } else {
++ cerr << "Could not open directory " << path << " for reading" << endl;
++ }
++ return true;
++
++ } else {
++ cerr << "Unable to open aircraft definition file " << fname << endl;
++ return false;
++ }
++
++}
++
++
++bool FGAircraft::Run(void)
++{
++ if (!FGModel::Run()) { // if false then execute this Run()
++ GetState();
++
++ for (int i = 0; i < 3; i++) Forces[i] = Moments[i] = 0.0;
++
++ MassChange();
++
++ FProp(); FAero(); FGear(); FMass();
++ MProp(); MAero(); MGear(); MMass();
++
++ PutState();
++ } else { // skip Run() execution this time
++ }
++ return false;
++}
++
++
++void FGAircraft::MassChange()
++{
++ // UPDATE TANK CONTENTS
++ //
++ // For each engine, cycle through the tanks and draw an equal amount of
++ // fuel (or oxidizer) from each active tank. The needed amount of fuel is
++ // determined by the engine in the FGEngine class. If more fuel is needed
++ // than is available in the tank, then that amount is considered a shortage,
++ // and will be drawn from the next tank. If the engine cannot be fed what it
++ // needs, it will be considered to be starved, and will shut down.
++
++ float Oshortage, Fshortage;
++
++ for (int e=0; e<numEngines; e++) {
++ Fshortage = Oshortage = 0.0;
++ for (int t=0; t<numTanks; t++) {
++ switch(Engine[e]->GetType()) {
++ case FGEngine::etRocket:
++
++ switch(Tank[t]->GetType()) {
++ case FGTank::ttFUEL:
++ if (Tank[t]->GetSelected()) {
++ Fshortage = Tank[t]->Reduce((Engine[e]->CalcFuelNeed()/
++ numSelectedFuelTanks)*(dt*rate) + Fshortage);
++ }
++ break;
++ case FGTank::ttOXIDIZER:
++ if (Tank[t]->GetSelected()) {
++ Oshortage = Tank[t]->Reduce((Engine[e]->CalcOxidizerNeed()/
++ numSelectedOxiTanks)*(dt*rate) + Oshortage);
++ }
++ break;
++ }
++ break;
++
++ case FGEngine::etPiston:
++ case FGEngine::etTurboJet:
++ case FGEngine::etTurboProp:
++
++ if (Tank[t]->GetSelected()) {
++ Fshortage = Tank[t]->Reduce((Engine[e]->CalcFuelNeed()/
++ numSelectedFuelTanks)*(dt*rate) + Fshortage);
++ }
++ break;
++ }
++ }
++ if ((Fshortage <= 0.0) || (Oshortage <= 0.0)) Engine[e]->SetStarved();
++ else Engine[e]->SetStarved(false);
++ }
++
++ Weight = EmptyWeight;
++ for (int t=0; t<numTanks; t++)
++ Weight += Tank[t]->GetContents();
++
++ Mass = Weight / GRAVITY;
++}
++
++
++void FGAircraft::FAero(void)
++{
++ float F[3];
++
++ F[0] = F[1] = F[2] = 0.0;
++
++ for (int axis_ctr = 0; axis_ctr < 3; axis_ctr++)
++ for (int ctr=0; ctr < coeff_ctr[axis_ctr]; ctr++)
++ F[axis_ctr] += Coeff[axis_ctr][ctr]->Value();
++
++ Forces[0] += F[LiftCoeff]*sin(alpha) - F[DragCoeff]*cos(alpha) - F[SideCoeff]*sin(beta);
++ Forces[1] += F[SideCoeff]*cos(beta);
++ Forces[2] += -F[LiftCoeff]*cos(alpha) - F[DragCoeff]*sin(alpha);
++}
++
++
++void FGAircraft::FGear(void)
++{
++ if (GearUp) {
++ } else {
++ }
++}
++
++
++void FGAircraft::FMass(void)
++{
++ Forces[0] += -GRAVITY*sin(tht) * Mass;
++ Forces[1] += GRAVITY*sin(phi)*cos(tht) * Mass;
++ Forces[2] += GRAVITY*cos(phi)*cos(tht) * Mass;
++}
++
++
++void FGAircraft::FProp(void)
++{
++ for (int i=0;i<numEngines;i++) {
++ Forces[0] += Engine[i]->CalcThrust();
++ }
++}
++
++
++void FGAircraft::MAero(void)
++{
++ for (int axis_ctr = 0; axis_ctr < 3; axis_ctr++)
++ for (int ctr = 0; ctr < coeff_ctr[axis_ctr+3]; ctr++)
++ Moments[axis_ctr] += Coeff[axis_ctr+3][ctr]->Value();
++}
++
++
++void FGAircraft::MGear(void)
++{
++ if (GearUp) {
++ } else {
++ }
++}
++
++
++void FGAircraft::MMass(void)
++{
++}
++
++
++void FGAircraft::MProp(void)
++{
++}
++
++
++void FGAircraft::GetState(void)
++{
++ dt = State->Getdt();
++
++ alpha = Translation->Getalpha();
++ beta = Translation->Getbeta();
++ phi = Rotation->Getphi();
++ tht = Rotation->Gettht();
++ psi = Rotation->Getpsi();
++}
++
++
++void FGAircraft::PutState(void)
++{
++}
++
--- /dev/null
--- /dev/null
++/*******************************************************************************
++
++ Header: FGAircraft.h
++ Author: Jon S. Berndt
++ Date started: 12/12/98
++
++ ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ 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., 59 Temple
++ Place - Suite 330, Boston, MA 02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++HISTORY
++--------------------------------------------------------------------------------
++12/12/98 JSB Created
++
++********************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGAIRCRAFT_H
++#define FGAIRCRAFT_H
++
++/*******************************************************************************
++COMMENTS, REFERENCES, and NOTES
++*******************************************************************************/
++/**
++The aerodynamic coefficients used in this model typically are:
++<PRE>
++<b>Longitudinal</b>
++ CL0 - Reference lift at zero alpha
++ CD0 - Reference drag at zero alpha
++ CDM - Drag due to Mach
++ CLa - Lift curve slope (w.r.t. alpha)
++ CDa - Drag curve slope (w.r.t. alpha)
++ CLq - Lift due to pitch rate
++ CLM - Lift due to Mach
++ CLadt - Lift due to alpha rate
++
++ Cmadt - Pitching Moment due to alpha rate
++ Cm0 - Reference Pitching moment at zero alpha
++ Cma - Pitching moment slope (w.r.t. alpha)
++ Cmq - Pitch damping (pitch moment due to pitch rate)
++ CmM - Pitch Moment due to Mach
++
++<b>Lateral</b>
++ Cyb - Side force due to sideslip
++ Cyr - Side force due to yaw rate
++
++ Clb - Dihedral effect (roll moment due to sideslip)
++ Clp - Roll damping (roll moment due to roll rate)
++ Clr - Roll moment due to yaw rate
++ Cnb - Weathercocking stability (yaw moment due to sideslip)
++ Cnp - Rudder adverse yaw (yaw moment due to roll rate)
++ Cnr - Yaw damping (yaw moment due to yaw rate)
++
++<b>Control</b>
++ CLDe - Lift due to elevator
++ CDDe - Drag due to elevator
++ CyDr - Side force due to rudder
++ CyDa - Side force due to aileron
++
++ CmDe - Pitch moment due to elevator
++ ClDa - Roll moment due to aileron
++ ClDr - Roll moment due to rudder
++ CnDr - Yaw moment due to rudder
++ CnDa - Yaw moment due to aileron
++</PRE>
++This class expects to be run in a directory which contains the subdirectory
++structure shown below (where example aircraft X-15 is shown):
++
++<PRE>
++aircraft/
++ X-15/
++ X-15.dat reset00 reset01 reset02 ...
++ CDRAG/
++ a0 a M De
++ CSIDE/
++ b r Dr Da
++ CLIFT/
++ a0 a M adt De
++ CROLL/
++ b p r Da Dr
++ CPITCH/
++ a0 a adt q M De
++ CYAW/
++ b p r Dr Da
++ F-16/
++ F-16.dat reset00 reset01 ...
++ CDRAG/
++ a0 a M De
++ ...
++</PRE>
++
++The General Idea
++
++The file structure is arranged so that various modeled aircraft are stored in
++their own subdirectory. Each aircraft subdirectory is named after the aircraft.
++There should be a file present in the specific aircraft subdirectory (e.g.
++aircraft/X-15) with the same name as the directory with a .dat appended. This
++file contains mass properties information, name of aircraft, etc. for the
++aircraft. In that same directory are reset files numbered starting from 0 (two
++digit numbers), e.g. reset03. Within each reset file are values for important
++state variables for specific flight conditions (altitude, airspeed, etc.). Also
++within this directory are the directories containing lookup tables for the
++stability derivatives for the aircraft.
++@author Jon S. Berndt
++@memo Encompasses all aircraft functionality and objects
++@see <ll>
++<li>[1] Cooke, Zyda, Pratt, and McGhee, "NPSNET: Flight Simulation Dynamic Modeling
++ Using Quaternions", Presence, Vol. 1, No. 4, pp. 404-420 Naval Postgraduate
++ School, January 1994</li>
++<li>[2] D. M. Henderson, "Euler Angles, Quaternions, and Transformation Matrices",
++ JSC 12960, July 1977</li>
++<li>[3] Richard E. McFarland, "A Standard Kinematic Model for Flight Simulation at
++ NASA-Ames", NASA CR-2497, January 1975</li>
++<li>[4] Barnes W. McCormick, "Aerodynamics, Aeronautics, and Flight Mechanics",
++ Wiley & Sons, 1979 ISBN 0-471-03032-5</li>
++<li>[5] Bernard Etkin, "Dynamics of Flight, Stability and Control", Wiley & Sons,
++ 1982 ISBN 0-471-08936-2</li>
++</ll>
++*/
++
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#ifdef FGFS
++# include <Include/compiler.h>
++# ifdef FG_HAVE_STD_INCLUDES
++# include <fstream>
++# else
++# include <fstream.h>
++# endif
++#else
++# include <fstream>
++#endif
++
++#include "FGModel.h"
++#include "FGCoefficient.h"
++#include "FGEngine.h"
++#include "FGTank.h"
++
++/*******************************************************************************
++DEFINITIONS
++*******************************************************************************/
++
++/*******************************************************************************
++CLASS DECLARATION
++*******************************************************************************/
++
++class FGAircraft : public FGModel
++{
++public:
++ // ***************************************************************************
++ /** @memo Constructor
++ @param FGFDMExec* - a pointer to the "owning" FDM Executive
++ */
++ FGAircraft(FGFDMExec*);
++
++ // ***************************************************************************
++ /** Destructor */
++ ~FGAircraft(void);
++
++ // ***************************************************************************
++ /** This must be called for each dt to execute the model algorithm */
++ bool Run(void);
++
++ // ***************************************************************************
++ /** This function must be called with the name of an aircraft which
++ has an associated .dat file in the appropriate subdirectory. The paths
++ to the appropriate subdirectories are given as the first two parameters.
++ @memo Loads the given aircraft.
++ @param string Path to the aircraft files
++ @param string Path to the engine files
++ @param string The name of the aircraft to be loaded, e.g. "X15".
++ @return True - if successful
++ */
++ bool LoadAircraft(string, string, string);
++
++ // ***************************************************************************
++ /** @memo Gets the aircraft name as defined in the aircraft config file.
++ @param
++ @return string Aircraft name.
++ */
++ inline string GetAircraftName(void) {return AircraftName;}
++
++ // ***************************************************************************
++ /** @memo Sets the GearUp flag
++ @param boolean true or false
++ @return
++ */
++ inline void SetGearUp(bool tt) {GearUp = tt;}
++
++ // ***************************************************************************
++ /** @memo Returns the state of the GearUp flag
++ @param
++ @return boolean true or false
++ */
++ inline bool GetGearUp(void) {return GearUp;}
++
++ // ***************************************************************************
++ /** @memo Returns the area of the wing
++ @param
++ @return float wing area S, in square feet
++ */
++ inline float GetWingArea(void) {return WingArea;}
++
++ // ***************************************************************************
++ /** @memo Returns the wing span
++ @param
++ @return float wing span in feet
++ */
++ inline float GetWingSpan(void) {return WingSpan;}
++
++ // ***************************************************************************
++ /** @memo Returns the average wing chord
++ @param
++ @return float wing chord in feet
++ */
++ inline float Getcbar(void) {return cbar;}
++
++ // ***************************************************************************
++ /** @memo Returns an engine object
++ @param int The engine number
++ @return FGEengine* The pointer to the requested engine object.
++ */
++ inline FGEngine* GetEngine(int tt) {return Engine[tt];}
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ inline FGTank* GetTank(int tt) {return Tank[tt];}
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ inline float GetWeight(void) {return Weight;}
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ inline float GetMass(void) {return Mass;}
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ inline float GetL(void) {return Moments[0];}
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ inline float GetM(void) {return Moments[1];}
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ inline float GetN(void) {return Moments[2];}
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ inline float GetFx(void) {return Forces[0];}
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ inline float GetFy(void) {return Forces[1];}
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ inline float GetFz(void) {return Forces[2];}
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ inline float GetIxx(void) {return Ixx;}
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ inline float GetIyy(void) {return Iyy;}
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ inline float GetIzz(void) {return Izz;}
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ inline float GetIxz(void) {return Ixz;}
++
++private:
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ void GetState(void);
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ void PutState(void);
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ void FAero(void);
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ void FGear(void);
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ void FMass(void);
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ void FProp(void);
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ void MAero(void);
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ void MGear(void);
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ void MMass(void);
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ void MProp(void);
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ void MassChange(void);
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ float Moments[3];
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ float Forces[3];
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ string AircraftName;
++
++ // ***************************************************************************
++ ///
++ float Ixx, Iyy, Izz, Ixz, EmptyMass, Mass;
++ ///
++ float Xcg, Ycg, Zcg;
++ ///
++ float Xep, Yep, Zep;
++ ///
++ float rho, qbar, Vt;
++ ///
++ float alpha, beta;
++ ///
++ float WingArea, WingSpan, cbar;
++ ///
++ float phi, tht, psi;
++ ///
++ float Weight, EmptyWeight;
++ ///
++ float dt;
++
++ ///
++ int numTanks;
++ ///
++ int numEngines;
++ ///
++ int numSelectedOxiTanks;
++ ///
++ int numSelectedFuelTanks;
++ ///
++ FGTank* Tank[MAX_TANKS];
++ ///
++ FGEngine *Engine[MAX_ENGINES];
++
++ ///
++ FGCoefficient *Coeff[6][10];
++ ///
++ int coeff_ctr[6];
++
++ ///
++ bool GearUp;
++
++ ///
++ enum Param {LiftCoeff,
++ DragCoeff,
++ SideCoeff,
++ RollCoeff,
++ PitchCoeff,
++ YawCoeff,
++ numCoeffs};
++
++ ///
++ string Axis[6];
++
++protected:
++
++};
++
++/******************************************************************************/
++#endif
--- /dev/null
--- /dev/null
++/*******************************************************************************
++
++ Module: FGAtmosphere.cpp
++ Author: Jon Berndt
++ Date started: 11/24/98
++ Purpose: Models the atmosphere
++ Called by: FGSimExec
++
++ ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ 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., 59 Temple
++ Place - Suite 330, Boston, MA 02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++Models the atmosphere. The equation used below was determined by a third order
++curve fit using Excel. The data is from the ICAO atmosphere model.
++
++HISTORY
++--------------------------------------------------------------------------------
++11/24/98 JSB Created
++
++********************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#include "FGAtmosphere.h"
++#include "FGState.h"
++#include "FGFDMExec.h"
++#include "FGFCS.h"
++#include "FGAircraft.h"
++#include "FGTranslation.h"
++#include "FGRotation.h"
++#include "FGPosition.h"
++#include "FGAuxiliary.h"
++#include "FGOutput.h"
++
++/*******************************************************************************
++************************************ CODE **************************************
++*******************************************************************************/
++
++FGAtmosphere::FGAtmosphere(FGFDMExec* fdmex) : FGModel(fdmex)
++{
++ Name = "FGAtmosphere";
++}
++
++
++FGAtmosphere::~FGAtmosphere()
++{
++}
++
++
++bool FGAtmosphere::Run(void)
++{
++ if (!FGModel::Run()) { // if false then execute this Run()
++ rho = 0.002377 - 7.0E-08*State->Geth()
++ + 7.0E-13*State->Geth()*State->Geth()
++ - 2.0E-18*State->Geth()*State->Geth()*State->Geth();
++
++ State->SetMach(State->GetVt()/State->Geta());
++ } else { // skip Run() execution this time
++ }
++ return false;
++}
--- /dev/null
--- /dev/null
++/*******************************************************************************
++
++ Header: FGAtmosphere.h
++ Author: Jon Berndt
++ Date started: 11/24/98
++
++ ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ 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., 59 Temple
++ Place - Suite 330, Boston, MA 02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++HISTORY
++--------------------------------------------------------------------------------
++11/24/98 JSB Created
++
++********************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGATMOSPHERE_H
++#define FGATMOSPHERE_H
++
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#include "FGModel.h"
++
++/*******************************************************************************
++COMMENTS, REFERENCES, and NOTES
++*******************************************************************************/
++/**
++The equation used in this model was determined by a third order curve fit using
++Excel. The data is from the ICAO atmosphere model.
++@memo Models the atmosphere.
++@author Jon S. Berndt
++*/
++/*******************************************************************************
++CLASS DECLARATION
++*******************************************************************************/
++
++class FGAtmosphere : public FGModel
++{
++public:
++ // ***************************************************************************
++ /** @memo Constructor
++ @param FGFDMExec* - a pointer to the "owning" FDM Executive
++ */
++ FGAtmosphere(FGFDMExec*);
++
++ // ***************************************************************************
++ /** @memo Destructor
++ */
++ ~FGAtmosphere(void);
++
++ // ***************************************************************************
++ /** This must be called for each dt to execute the model algorithm */
++ bool Run(void);
++
++ // ***************************************************************************
++ /** @memo Returns the air density
++ @return float air density in slugs/cubic foot
++ */
++ inline float Getrho(void) {return rho;}
++
++protected:
++
++private:
++ float rho;
++};
++
++/******************************************************************************/
++#endif
--- /dev/null
--- /dev/null
++/*******************************************************************************
++
++ Module: FGAuxiliary.cpp
++ Author: Jon Berndt
++ Date started: 01/26/99
++ Purpose: Calculates additional parameters needed by the visual system, etc.
++ Called by: FGSimExec
++
++ ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ 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., 59 Temple
++ Place - Suite 330, Boston, MA 02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++This class calculates various auxiliary parameters, mostly used by the visual
++system
++
++HISTORY
++--------------------------------------------------------------------------------
++01/26/99 JSB Created
++
++********************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#include "FGAuxiliary.h"
++#include "FGTranslation.h"
++#include "FGRotation.h"
++#include "FGAtmosphere.h"
++#include "FGState.h"
++#include "FGFDMExec.h"
++#include "FGFCS.h"
++#include "FGAircraft.h"
++#include "FGPosition.h"
++#include "FGOutput.h"
++
++/*******************************************************************************
++************************************ CODE **************************************
++*******************************************************************************/
++
++FGAuxiliary::FGAuxiliary(FGFDMExec* fdmex) : FGModel(fdmex)
++{
++ Name = "FGAuxiliary";
++}
++
++
++FGAuxiliary::~FGAuxiliary()
++{
++}
++
++
++bool FGAuxiliary::Run()
++{
++ if (!FGModel::Run()) {
++ } else {
++ }
++ return false;
++}
++
++
--- /dev/null
--- /dev/null
++/*******************************************************************************
++
++ Header: FGAuxiliary.h
++ Author: Jon Berndt
++ Date started: 01/26/99
++
++ ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ 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., 59 Temple
++ Place - Suite 330, Boston, MA 02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++HISTORY
++--------------------------------------------------------------------------------
++11/22/98 JSB Created
++
++********************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGAUXILIARY_H
++#define FGAUXILIARY_H
++
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++#include "FGModel.h"
++
++/*******************************************************************************
++DEFINES
++*******************************************************************************/
++
++/*******************************************************************************
++CLASS DECLARATION
++*******************************************************************************/
++
++class FGAuxiliary : public FGModel
++{
++public:
++ FGAuxiliary(FGFDMExec*);
++ ~FGAuxiliary(void);
++
++ bool Run(void);
++
++protected:
++
++private:
++
++};
++
++/******************************************************************************/
++#endif
--- /dev/null
--- /dev/null
++/*******************************************************************************
++
++ Module: FGCoefficient.cpp
++ Author: Jon S. Berndt
++ Date started: 12/28/98
++ Purpose: Encapsulates the stability derivative class FGCoefficient;
++ Called by: FGAircraft
++
++ ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ 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., 59 Temple
++ Place - Suite 330, Boston, MA 02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++This class models the stability derivative coefficient lookup tables or
++equations. Note that the coefficients need not be calculated each delta-t.
++
++The coefficient files are located in the axis subdirectory for each aircraft.
++For instance, for the X-15, you would find subdirectories under the
++aircraft/X-15/ directory named CLIFT, CDRAG, CSIDE, CROLL, CPITCH, CYAW. Under
++each of these directories would be files named a, a0, q, and so on. The file
++named "a" under the CLIFT directory would contain data for the stability
++derivative modeling lift due to a change in alpha. See the FGAircraft.cpp file
++for additional information. The coefficient files have the following format:
++
++<name of coefficient>
++<short description of coefficient with no embedded spaces>
++<method used in calculating the coefficient: TABLE | EQUATION | VECTOR | VALUE>
++ <parameter identifier for table row (if required)>
++ <parameter identifier for table column (if required)>
++<OR'ed list of parameter identifiers needed to turn this coefficient into a force>
++<number of rows in table (if required)>
++<number of columns in table (if required)>
++
++<value of parameter indexing into the column of a table or vector - or value
++ itself for a VALUE coefficient>
++<values of parameter indexing into row of a table if TABLE type> <Value of
++ coefficient at this row and column>
++
++<... repeat above for each column of data in table ...>
++
++As an example for the X-15, for the lift due to mach:
++
++CLa0
++Lift_at_zero_alpha
++Table 8 3
++16384
++32768
++16387
++
++0.00
++0.0 0.0
++0.5 0.4
++0.9 0.9
++1.0 1.6
++1.1 1.3
++1.4 1.0
++2.0 0.5
++3.0 0.5
++
++30000.00
++0.0 0.0
++0.5 0.5
++0.9 1.0
++1.0 1.7
++1.1 1.4
++1.4 1.1
++2.0 0.6
++3.0 0.6
++
++70000.00
++0.0 0.0
++0.5 0.6
++0.9 1.1
++1.0 1.7
++1.1 1.5
++1.4 1.2
++2.0 0.7
++3.0 0.7
++
++Note that the values in a row which index into the table must be the same value
++for each column of data, so the first column of numbers for each altitude are
++seen to be equal, and there are the same number of values for each altitude.
++
++See the header file FGCoefficient.h for the values of the identifiers.
++
++HISTORY
++--------------------------------------------------------------------------------
++12/28/98 JSB Created
++
++********************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#include "FGCoefficient.h"
++#include "FGAtmosphere.h"
++#include "FGState.h"
++#include "FGFDMExec.h"
++#include "FGFCS.h"
++#include "FGAircraft.h"
++#include "FGTranslation.h"
++#include "FGRotation.h"
++#include "FGPosition.h"
++#include "FGAuxiliary.h"
++#include "FGOutput.h"
++
++/*******************************************************************************
++************************************ CODE **************************************
++*******************************************************************************/
++
++FGCoefficient::FGCoefficient(FGFDMExec* fdex)
++{
++ FDMExec = fdex;
++ State = FDMExec->GetState();
++ Atmosphere = FDMExec->GetAtmosphere();
++ FCS = FDMExec->GetFCS();
++ Aircraft = FDMExec->GetAircraft();
++ Translation = FDMExec->GetTranslation();
++ Rotation = FDMExec->GetRotation();
++ Position = FDMExec->GetPosition();
++ Auxiliary = FDMExec->GetAuxiliary();
++ Output = FDMExec->GetOutput();
++
++ rows = columns = 0;
++}
++
++
++FGCoefficient::FGCoefficient(FGFDMExec* fdex, string fname)
++{
++ int r, c;
++ float ftrashcan;
++
++ FDMExec = fdex;
++ State = FDMExec->GetState();
++ Atmosphere = FDMExec->GetAtmosphere();
++ FCS = FDMExec->GetFCS();
++ Aircraft = FDMExec->GetAircraft();
++ Translation = FDMExec->GetTranslation();
++ Rotation = FDMExec->GetRotation();
++ Position = FDMExec->GetPosition();
++ Auxiliary = FDMExec->GetAuxiliary();
++ Output = FDMExec->GetOutput();
++
++ ifstream coeffDefFile(fname.c_str());
++
++ if (coeffDefFile) {
++ if (!coeffDefFile.fail()) {
++ coeffDefFile >> name;
++ coeffDefFile >> description;
++ coeffDefFile >> method;
++
++ if (method == "EQUATION") type = EQUATION;
++ else if (method == "TABLE") type = TABLE;
++ else if (method == "VECTOR") type = VECTOR;
++ else if (method == "VALUE") type = VALUE;
++ else type = UNKNOWN;
++
++ if (type == VECTOR || type == TABLE) {
++ coeffDefFile >> rows;
++ if (type == TABLE) {
++ coeffDefFile >> columns;
++ }
++ coeffDefFile >> LookupR;
++ }
++
++ if (type == TABLE) {
++ coeffDefFile >> LookupC;
++ }
++
++ coeffDefFile >> multipliers;
++
++ mult_count = 0;
++ if (multipliers & FG_QBAR) {
++ mult_idx[mult_count] = FG_QBAR;
++ mult_count++;
++ }
++ if (multipliers & FG_WINGAREA) {
++ mult_idx[mult_count] = FG_WINGAREA;
++ mult_count++;
++ }
++ if (multipliers & FG_WINGSPAN) {
++ mult_idx[mult_count] = FG_WINGSPAN;
++ mult_count++;
++ }
++ if (multipliers & FG_CBAR) {
++ mult_idx[mult_count] = FG_CBAR;
++ mult_count++;
++ }
++ if (multipliers & FG_ALPHA) {
++ mult_idx[mult_count] = FG_ALPHA;
++ mult_count++;
++ }
++ if (multipliers & FG_ALPHADOT) {
++ mult_idx[mult_count] = FG_ALPHADOT;
++ mult_count++;
++ }
++ if (multipliers & FG_BETA) {
++ mult_idx[mult_count] = FG_BETA;
++ mult_count++;
++ }
++ if (multipliers & FG_BETADOT) {
++ mult_idx[mult_count] = FG_BETADOT;
++ mult_count++;
++ }
++ if (multipliers & FG_PITCHRATE) {
++ mult_idx[mult_count] = FG_PITCHRATE;
++ mult_count++;
++ }
++ if (multipliers & FG_ROLLRATE) {
++ mult_idx[mult_count] = FG_ROLLRATE;
++ mult_count++;
++ }
++ if (multipliers & FG_YAWRATE) {
++ mult_idx[mult_count] = FG_YAWRATE;
++ mult_count++;
++ }
++ if (multipliers & FG_ELEVATOR) {
++ mult_idx[mult_count] = FG_ELEVATOR;
++ mult_count++;
++ }
++ if (multipliers & FG_AILERON) {
++ mult_idx[mult_count] = FG_AILERON;
++ mult_count++;
++ }
++ if (multipliers & FG_RUDDER) {
++ mult_idx[mult_count] = FG_RUDDER;
++ mult_count++;
++ }
++ if (multipliers & FG_MACH) {
++ mult_idx[mult_count] = FG_MACH;
++ mult_count++;
++ }
++ if (multipliers & FG_ALTITUDE) {
++ mult_idx[mult_count] = FG_ALTITUDE;
++ mult_count++;
++ }
++
++ switch(type) {
++ case VALUE:
++ coeffDefFile >> StaticValue;
++ break;
++ case VECTOR:
++ Allocate(rows,2);
++
++ for (r=1;r<=rows;r++) {
++ coeffDefFile >> Table3D[r][0];
++ coeffDefFile >> Table3D[r][1];
++ }
++ break;
++ case TABLE:
++ Allocate(rows, columns);
++
++ for (c=1;c<=columns;c++) {
++ coeffDefFile >> Table3D[0][c];
++ for (r=1;r<=rows;r++) {
++ if ( c==1 ) coeffDefFile >> Table3D[r][0];
++ else coeffDefFile >> ftrashcan;
++ coeffDefFile >> Table3D[r][c];
++ }
++ }
++ break;
++ }
++ } else {
++ cerr << "Empty file" << endl;
++ }
++ coeffDefFile.close();
++ }
++}
++
++
++FGCoefficient::FGCoefficient(FGFDMExec* fdex, int r, int c)
++{
++ FDMExec = fdex;
++ State = FDMExec->GetState();
++ Atmosphere = FDMExec->GetAtmosphere();
++ FCS = FDMExec->GetFCS();
++ Aircraft = FDMExec->GetAircraft();
++ Translation = FDMExec->GetTranslation();
++ Rotation = FDMExec->GetRotation();
++ Position = FDMExec->GetPosition();
++ Auxiliary = FDMExec->GetAuxiliary();
++ Output = FDMExec->GetOutput();
++
++ rows = r;
++ columns = c;
++ Allocate(r,c);
++}
++
++
++FGCoefficient::FGCoefficient(FGFDMExec* fdex, int n)
++{
++ FDMExec = fdex;
++ State = FDMExec->GetState();
++ Atmosphere = FDMExec->GetAtmosphere();
++ FCS = FDMExec->GetFCS();
++ Aircraft = FDMExec->GetAircraft();
++ Translation = FDMExec->GetTranslation();
++ Rotation = FDMExec->GetRotation();
++ Position = FDMExec->GetPosition();
++ Auxiliary = FDMExec->GetAuxiliary();
++ Output = FDMExec->GetOutput();
++
++ rows = n;
++ columns = 0;
++ Allocate(n);
++}
++
++
++FGCoefficient::~FGCoefficient(void)
++{
++}
++
++
++bool FGCoefficient::Allocate(int r, int c)
++{
++ rows = r;
++ columns = c;
++ Table3D = new float*[r+1];
++ for (int i=0;i<=r;i++) Table3D[i] = new float[c+1];
++ return true;
++}
++
++
++bool FGCoefficient::Allocate(int n)
++{
++ rows = n;
++ columns = 0;
++ Table2D = new float[n+1];
++ return true;
++}
++
++
++float FGCoefficient::Value(float rVal, float cVal)
++{
++ float rFactor, cFactor, col1temp, col2temp, Value;
++ int r, c, midx;
++
++ if (rows < 2 || columns < 2) return 0.0;
++
++ for (r=1;r<=rows;r++) if (Table3D[r][0] >= rVal) break;
++ for (c=1;c<=columns;c++) if (Table3D[0][c] >= cVal) break;
++
++ c = c < 2 ? 2 : (c > columns ? columns : c);
++ r = r < 2 ? 2 : (r > rows ? rows : r);
++
++ rFactor = (rVal - Table3D[r-1][0]) / (Table3D[r][0] - Table3D[r-1][0]);
++ cFactor = (cVal - Table3D[0][c-1]) / (Table3D[0][c] - Table3D[0][c-1]);
++
++ col1temp = rFactor*(Table3D[r][c-1] - Table3D[r-1][c-1]) + Table3D[r-1][c-1];
++ col2temp = rFactor*(Table3D[r][c] - Table3D[r-1][c]) + Table3D[r-1][c];
++
++ Value = col1temp + cFactor*(col2temp - col1temp);
++
++ for (midx=0;midx<mult_count;midx++) {
++ Value *= GetCoeffVal(mult_idx[midx]);
++ }
++
++ return Value;
++}
++
++
++float FGCoefficient::Value(float Val)
++{
++ float Factor, Value;
++ int r, midx;
++
++ if (rows < 2) return 0.0;
++
++ for (r=1;r<=rows;r++) if (Table3D[r][0] >= Val) break;
++ r = r < 2 ? 2 : (r > rows ? rows : r);
++
++ // make sure denominator below does not go to zero.
++ if (Table3D[r][0] != Table3D[r-1][0]) {
++ Factor = (Val - Table3D[r-1][0]) / (Table3D[r][0] - Table3D[r-1][0]);
++ } else {
++ Factor = 1.0;
++ }
++ Value = Factor*(Table3D[r][1] - Table3D[r-1][1]) + Table3D[r-1][1];
++
++ for (midx=0;midx<mult_count;midx++) {
++ Value *= GetCoeffVal(mult_idx[midx]);
++ }
++
++ return Value;
++}
++
++
++float FGCoefficient::Value()
++{
++ switch(type) {
++ case 0:
++ return -1;
++ case 1:
++ return (StaticValue);
++ case 2:
++ return (Value(GetCoeffVal(LookupR)));
++ case 3:
++ return (Value(GetCoeffVal(LookupR),GetCoeffVal(LookupC)));
++ case 4:
++ return 0.0;
++ }
++ return 0;
++}
++
++float FGCoefficient::GetCoeffVal(int val_idx)
++{
++ switch(val_idx) {
++ case FG_QBAR:
++ return State->Getqbar();
++ case FG_WINGAREA:
++ return Aircraft->GetWingArea();
++ case FG_WINGSPAN:
++ return Aircraft->GetWingSpan();
++ case FG_CBAR:
++ return Aircraft->Getcbar();
++ case FG_ALPHA:
++ return Translation->Getalpha();
++ case FG_ALPHADOT:
++ return State->Getadot();
++ case FG_BETA:
++ return Translation->Getbeta();
++ case FG_BETADOT:
++ return State->Getbdot();
++ case FG_PITCHRATE:
++ return Rotation->GetQ();
++ case FG_ROLLRATE:
++ return Rotation->GetP();
++ case FG_YAWRATE:
++ return Rotation->GetR();
++ case FG_ELEVATOR:
++ return FCS->GetDe();
++ case FG_AILERON:
++ return FCS->GetDa();
++ case FG_RUDDER:
++ return FCS->GetDr();
++ case FG_MACH:
++ return State->GetMach();
++ case FG_ALTITUDE:
++ return State->Geth();
++ }
++ return 0;
++}
--- /dev/null
--- /dev/null
++/*******************************************************************************
++
++ Header: FGCoefficient.h
++ Author: Jon Berndt
++ Date started: 12/28/98
++
++ ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ 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., 59 Temple
++ Place - Suite 330, Boston, MA 02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++HISTORY
++--------------------------------------------------------------------------------
++12/28/98 JSB Created
++
++********************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGCOEFFICIENT_H
++#define FGCOEFFICIENT_H
++
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++#ifdef FGFS
++# include <Include/compiler.h>
++# include STL_STRING
++# ifdef FG_HAVE_STD_INCLUDES
++# include <fstream>
++# else
++# include <fstream.h>
++# endif
++ FG_USING_STD(string);
++#else
++# include <string>
++# include <fstream>
++#endif
++
++/*******************************************************************************
++DEFINES
++*******************************************************************************/
++#define FG_QBAR 1
++#define FG_WINGAREA 2
++#define FG_WINGSPAN 4
++#define FG_CBAR 8
++#define FG_ALPHA 16
++#define FG_ALPHADOT 32
++#define FG_BETA 64
++#define FG_BETADOT 128
++#define FG_PITCHRATE 256
++#define FG_ROLLRATE 512
++#define FG_YAWRATE 1024
++#define FG_ELEVATOR 2048
++#define FG_AILERON 4096
++#define FG_RUDDER 8192
++#define FG_MACH 16384
++#define FG_ALTITUDE 32768L
++
++/*******************************************************************************
++FORWARD DECLARATIONS
++*******************************************************************************/
++class FGFDMExec;
++class FGState;
++class FGAtmosphere;
++class FGFCS;
++class FGAircraft;
++class FGTranslation;
++class FGRotation;
++class FGPosition;
++class FGAuxiliary;
++class FGOutput;
++
++/*******************************************************************************
++COMMENTS, REFERENCES, and NOTES
++*******************************************************************************/
++/**
++This class models the stability derivative coefficient lookup tables or
++equations. Note that the coefficients need not be calculated each delta-t.
++
++The coefficient files are located in the axis subdirectory for each aircraft.
++For instance, for the X-15, you would find subdirectories under the
++aircraft/X-15/ directory named CLIFT, CDRAG, CSIDE, CROLL, CPITCH, CYAW. Under
++each of these directories would be files named a, a0, q, and so on. The file
++named "a" under the CLIFT directory would contain data for the stability
++derivative modeling lift due to a change in alpha. See the FGAircraft.cpp file
++for additional information. The coefficient files have the following format:
++
++<name of coefficient>
++<short description of coefficient with no embedded spaces>
++<method used in calculating the coefficient: TABLE | EQUATION | VECTOR | VALUE>
++ <parameter identifier for table row (if required)>
++ <parameter identifier for table column (if required)>
++<OR'ed list of parameter identifiers needed to turn this coefficient into a force>
++<number of rows in table (if required)>
++<number of columns in table (if required)>
++
++<value of parameter indexing into the column of a table or vector - or value
++ itself for a VALUE coefficient>
++<values of parameter indexing into row of a table if TABLE type> <Value of
++ coefficient at this row and column>
++
++<... repeat above for each column of data in table ...>
++
++As an example for the X-15, for the lift due to mach:
++<PRE>
++
++CLa0
++Lift_at_zero_alpha
++Table 8 3
++16384
++32768
++16387
++
++0.00
++0.0 0.0
++0.5 0.4
++0.9 0.9
++1.0 1.6
++1.1 1.3
++1.4 1.0
++2.0 0.5
++3.0 0.5
++
++30000.00
++0.0 0.0
++0.5 0.5
++0.9 1.0
++1.0 1.7
++1.1 1.4
++1.4 1.1
++2.0 0.6
++3.0 0.6
++
++70000.00
++0.0 0.0
++0.5 0.6
++0.9 1.1
++1.0 1.7
++1.1 1.5
++1.4 1.2
++2.0 0.7
++3.0 0.7
++</PRE>
++
++Note that the values in a row which index into the table must be the same value
++for each column of data, so the first column of numbers for each altitude are
++seen to be equal, and there are the same number of values for each altitude.
++
++<PRE>
++FG_QBAR 1
++FG_WINGAREA 2
++FG_WINGSPAN 4
++FG_CBAR 8
++FG_ALPHA 16
++FG_ALPHADOT 32
++FG_BETA 64
++FG_BETADOT 128
++FG_PITCHRATE 256
++FG_ROLLRATE 512
++FG_YAWRATE 1024
++FG_ELEVATOR 2048
++FG_AILERON 4096
++FG_RUDDER 8192
++FG_MACH 16384
++FG_ALTITUDE 32768L
++</PRE>
++@author Jon S. Berndt
++@memo This class models the stability derivative coefficient lookup tables or equations.
++*/
++/*******************************************************************************
++CLASS DECLARATION
++*******************************************************************************/
++
++class FGCoefficient
++{
++public:
++ // ***************************************************************************
++ /** @memo Constructor
++ @param FGFDMExec* - pointer to owning simulation executive
++ */
++ FGCoefficient(FGFDMExec*);
++
++ // ***************************************************************************
++ /** @memo Constructor for two independent variable table
++ @param
++ @return
++ */
++ FGCoefficient(FGFDMExec*, int, int);
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ FGCoefficient(FGFDMExec*, int);
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ FGCoefficient(FGFDMExec*, string);
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ ~FGCoefficient(void);
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ bool Allocate(int);
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ bool Allocate(int, int);
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ float Value(float, float);
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ float Value(float);
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ float Value(void);
++
++ // ***************************************************************************
++ /** @memo
++ @param
++ @return
++ */
++ enum Type {UNKNOWN, VALUE, VECTOR, TABLE, EQUATION};
++
++protected:
++
++private:
++ string filename;
++ string description;
++ string name;
++ string method;
++ float StaticValue;
++ float *Table2D;
++ float **Table3D;
++ float LookupR, LookupC;
++ long int mult_idx[10];
++ int rows, columns;
++ Type type;
++ int multipliers;
++ int mult_count;
++
++ float GetCoeffVal(int);
++
++ FGFDMExec* FDMExec;
++ FGState* State;
++ FGAtmosphere* Atmosphere;
++ FGFCS* FCS;
++ FGAircraft* Aircraft;
++ FGTranslation* Translation;
++ FGRotation* Rotation;
++ FGPosition* Position;
++ FGAuxiliary* Auxiliary;
++ FGOutput* Output;
++};
++
++/******************************************************************************/
++#endif
--- /dev/null
--- /dev/null
++// controls.cxx -- defines a standard interface to all flight sim controls
++//
++// Written by Curtis Olson, started May 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$
++// (Log is kept at end of this file)
++
++
++#include "controls.hxx"
++
++
++FGControls controls;
++
++
++// Constructor
++FGControls::FGControls() :
++ aileron( 0.0 ),
++ elevator( 0.0 ),
++ elevator_trim( 1.969572E-03 ),
++ rudder( 0.0 )
++{
++ for ( int engine = 0; engine < MAX_ENGINES; engine++ ) {
++ throttle[engine] = 0.0;
++ }
++
++ for ( int wheel = 0; wheel < MAX_WHEELS; wheel++ ) {
++ brake[wheel] = 0.0;
++ }
++}
++
++
++// Destructor
++FGControls::~FGControls() {
++}
++
++
++// $Log$
++// Revision 1.1 1999/02/13 01:12:03 curt
++// Initial Revision.
++//
++// Revision 1.1 1999/02/09 04:51:32 jon
++// Initial revision
++//
++// Revision 1.3 1998/12/05 16:13:12 curt
++// Renamed class fgCONTROLS to class FGControls.
++//
++// Revision 1.2 1998/10/25 14:08:41 curt
++// Turned "struct fgCONTROLS" into a class, with inlined accessor functions.
++//
++// Revision 1.1 1998/10/18 01:51:05 curt
++// c++-ifying ...
++//
++// Revision 1.8 1998/09/29 02:01:31 curt
++// Added a brake.
++//
++// Revision 1.7 1998/02/07 15:29:36 curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.6 1998/01/19 19:27:02 curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.5 1998/01/19 18:40:22 curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.4 1997/12/10 22:37:41 curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.3 1997/08/27 03:30:01 curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.2 1997/06/21 17:12:48 curt
++// Capitalized subdirectory names.
++//
++// Revision 1.1 1997/05/31 19:24:04 curt
++// Initial revision.
++//
++
--- /dev/null
--- /dev/null
++// controls.hxx -- defines a standard interface to all flight sim controls
++//
++// Written by Curtis Olson, started May 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$
++// (Log is kept at end of this file)
++
++
++#ifndef _CONTROLS_HXX
++#define _CONTROLS_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++
++// Define a structure containing the control parameters
++
++class FGControls {
++
++public:
++
++ static const int ALL_ENGINES = -1;
++ static const int MAX_ENGINES = 10;
++
++ static const int ALL_WHEELS = -1;
++ static const int MAX_WHEELS = 3;
++
++private:
++
++ double aileron;
++ double elevator;
++ double elevator_trim;
++ double rudder;
++ double throttle[MAX_ENGINES];
++ double brake[MAX_WHEELS];
++
++public:
++
++ FGControls();
++ ~FGControls();
++
++ // Query functions
++ inline double get_aileron() const { return aileron; }
++ inline double get_elevator() const { return elevator; }
++ inline double get_elevator_trim() const { return elevator_trim; }
++ inline double get_rudder() const { return rudder; }
++ inline double get_throttle(int engine) const { return throttle[engine]; }
++ inline double get_brake(int wheel) const { return brake[wheel]; }
++
++ // Update functions
++ inline void set_aileron( double pos ) {
++ aileron = pos;
++ if ( aileron < -1.0 ) aileron = -1.0;
++ if ( aileron > 1.0 ) aileron = 1.0;
++ }
++ inline void move_aileron( double amt ) {
++ aileron += amt;
++ if ( aileron < -1.0 ) aileron = -1.0;
++ if ( aileron > 1.0 ) aileron = 1.0;
++ }
++ inline void set_elevator( double pos ) {
++ elevator = pos;
++ if ( elevator < -1.0 ) elevator = -1.0;
++ if ( elevator > 1.0 ) elevator = 1.0;
++ }
++ inline void move_elevator( double amt ) {
++ elevator += amt;
++ if ( elevator < -1.0 ) elevator = -1.0;
++ if ( elevator > 1.0 ) elevator = 1.0;
++ }
++ inline void set_elevator_trim( double pos ) {
++ elevator_trim = pos;
++ if ( elevator_trim < -1.0 ) elevator_trim = -1.0;
++ if ( elevator_trim > 1.0 ) elevator_trim = 1.0;
++ }
++ inline void move_elevator_trim( double amt ) {
++ elevator_trim += amt;
++ if ( elevator_trim < -1.0 ) elevator_trim = -1.0;
++ if ( elevator_trim > 1.0 ) elevator_trim = 1.0;
++ }
++ inline void set_rudder( double pos ) {
++ rudder = pos;
++ if ( rudder < -1.0 ) rudder = -1.0;
++ if ( rudder > 1.0 ) rudder = 1.0;
++ }
++ inline void move_rudder( double amt ) {
++ rudder += amt;
++ if ( rudder < -1.0 ) rudder = -1.0;
++ if ( rudder > 1.0 ) rudder = 1.0;
++ }
++ inline void set_throttle( int engine, double pos ) {
++ if ( engine == ALL_ENGINES ) {
++ for ( int i = 0; i < MAX_ENGINES; i++ ) {
++ throttle[i] = pos;
++ if ( throttle[i] < 0.0 ) throttle[i] = 0.0;
++ if ( throttle[i] > 1.0 ) throttle[i] = 1.0;
++ }
++ } else {
++ if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
++ throttle[engine] = pos;
++ if ( throttle[engine] < 0.0 ) throttle[engine] = 0.0;
++ if ( throttle[engine] > 1.0 ) throttle[engine] = 1.0;
++ }
++ }
++ }
++ inline void move_throttle( int engine, double amt ) {
++ if ( engine == ALL_ENGINES ) {
++ for ( int i = 0; i < MAX_ENGINES; i++ ) {
++ throttle[i] += amt;
++ if ( throttle[i] < 0.0 ) throttle[i] = 0.0;
++ if ( throttle[i] > 1.0 ) throttle[i] = 1.0;
++ }
++ } else {
++ if ( (engine >= 0) && (engine < MAX_ENGINES) ) {
++ throttle[engine] += amt;
++ if ( throttle[engine] < 0.0 ) throttle[engine] = 0.0;
++ if ( throttle[engine] > 1.0 ) throttle[engine] = 1.0;
++ }
++ }
++ }
++ inline void set_brake( int wheel, double pos ) {
++ if ( wheel == ALL_WHEELS ) {
++ for ( int i = 0; i < MAX_WHEELS; i++ ) {
++ brake[i] = pos;
++ if ( brake[i] < 0.0 ) brake[i] = 0.0;
++ if ( brake[i] > 1.0 ) brake[i] = 1.0;
++ }
++ } else {
++ if ( (wheel >= 0) && (wheel < MAX_WHEELS) ) {
++ brake[wheel] = pos;
++ if ( brake[wheel] < 0.0 ) brake[wheel] = 0.0;
++ if ( brake[wheel] > 1.0 ) brake[wheel] = 1.0;
++ }
++ }
++ }
++ inline void move_brake( int wheel, double amt ) {
++ if ( wheel == ALL_WHEELS ) {
++ for ( int i = 0; i < MAX_WHEELS; i++ ) {
++ brake[i] += amt;
++ if ( brake[i] < 0.0 ) brake[i] = 0.0;
++ if ( brake[i] > 1.0 ) brake[i] = 1.0;
++ }
++ } else {
++ if ( (wheel >= 0) && (wheel < MAX_WHEELS) ) {
++ brake[wheel] += amt;
++ if ( brake[wheel] < 0.0 ) brake[wheel] = 0.0;
++ if ( brake[wheel] > 1.0 ) brake[wheel] = 1.0;
++ }
++ }
++ }
++};
++
++
++extern FGControls controls;
++
++
++#endif // _CONTROLS_HXX
++
++
++// $Log$
++// Revision 1.1 1999/02/13 01:12:03 curt
++// Initial Revision.
++//
++// Revision 1.3 1998/12/05 16:13:13 curt
++// Renamed class fgCONTROLS to class FGControls.
++//
++// Revision 1.2 1998/10/25 14:08:42 curt
++// Turned "struct fgCONTROLS" into a class, with inlined accessor functions.
++//
++// Revision 1.1 1998/10/18 01:51:07 curt
++// c++-ifying ...
++//
++// Revision 1.17 1998/09/29 14:57:00 curt
++// c++-ified some comments.
++//
++// Revision 1.16 1998/09/29 02:01:32 curt
++// Added a brake.
++//
++// Revision 1.15 1998/04/25 22:06:27 curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.14 1998/04/22 13:26:19 curt
++// C++ - ifing the code a bit.
++//
++// Revision 1.13 1998/04/21 17:02:35 curt
++// Prepairing for C++ integration.
++//
++// Revision 1.12 1998/02/09 22:56:48 curt
++// Removed "depend" files from cvs control. Other minor make tweaks.
++//
++// Revision 1.11 1998/02/07 15:29:36 curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.10 1998/01/27 00:47:52 curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.9 1998/01/22 02:59:31 curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.8 1998/01/19 18:40:22 curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.7 1997/12/15 23:54:36 curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.6 1997/12/10 22:37:41 curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.5 1997/08/27 03:30:02 curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.4 1997/07/23 21:52:18 curt
++// Put comments around the text after an #endif for increased portability.
++//
++// Revision 1.3 1997/05/31 19:16:27 curt
++// Elevator trim added.
++//
++// Revision 1.2 1997/05/23 15:40:33 curt
++// Added GNU copyright headers.
++//
++// Revision 1.1 1997/05/16 15:59:48 curt
++// Initial revision.
++//
--- /dev/null
--- /dev/null
++/*******************************************************************************
++
++ Header: FGDefs.h
++ Author: Jon S. Berndt
++ Date started: 02/01/99
++
++ ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ 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., 59 Temple
++ Place - Suite 330, Boston, MA 02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++HISTORY
++--------------------------------------------------------------------------------
++02/01/99 JSB Created
++
++********************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGDEFS_H
++#define FGDEFS_H
++
++#define MAX_ENGINES 10
++#define MAX_TANKS 30
++#define GRAVITY 32.174
++#define EARTHRAD 20898908.00 // feet
++#define OMEGAEARTH 7.2685E-3 // rad/sec
++#define EARTHRADSQRD 437882827922500.0
++#define ONESECOND 4.848136811E-6
++#define ECCENT 0.996647186
++#define ECCENTSQRD 0.99330561
++#define INVECCENTSQRD 1.0067395
++#define INVECCENTSQRDM1 0.0067395
++#define EPS 0.081819221
++
++
++/******************************************************************************/
++#endif
--- /dev/null
--- /dev/null
++/*******************************************************************************
++
++ Module: FGEngine.cpp
++ Author: Jon Berndt
++ Date started: 01/21/99
++ Called by: FGAircraft
++
++ ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ 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., 59 Temple
++ Place - Suite 330, Boston, MA 02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++See header file.
++
++HISTORY
++--------------------------------------------------------------------------------
++01/21/99 JSB Created
++
++********************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#ifdef FGFS
++# include <Include/compiler.h>
++# ifdef FG_HAVE_STD_INCLUDES
++# include <fstream>
++# else
++# include <fstream.h>
++# endif
++#else
++# include <fstream>
++#endif
++
++#include "FGEngine.h"
++#include "FGState.h"
++#include "FGFDMExec.h"
++#include "FGAtmosphere.h"
++#include "FGFCS.h"
++#include "FGAircraft.h"
++#include "FGTranslation.h"
++#include "FGRotation.h"
++#include "FGPosition.h"
++#include "FGAuxiliary.h"
++#include "FGOutput.h"
++
++/*******************************************************************************
++************************************ CODE **************************************
++*******************************************************************************/
++
++
++FGEngine::FGEngine(FGFDMExec* fdex, string enginePath, string engineName, int num)
++{
++ string fullpath;
++ string tag;
++
++ FDMExec = fdex;
++
++ State = FDMExec->GetState();
++ Atmosphere = FDMExec->GetAtmosphere();
++ FCS = FDMExec->GetFCS();
++ Aircraft = FDMExec->GetAircraft();
++ Translation = FDMExec->GetTranslation();
++ Rotation = FDMExec->GetRotation();
++ Position = FDMExec->GetPosition();
++ Auxiliary = FDMExec->GetAuxiliary();
++ Output = FDMExec->GetOutput();
++
++ Name = engineName;
++ fullpath = enginePath + "/" + engineName + ".dat";
++ ifstream enginefile(fullpath.c_str());
++
++ if (enginefile) {
++ enginefile >> tag;
++
++ if (tag == "ROCKET") Type = etRocket;
++ else if (tag == "PISTON") Type = etPiston;
++ else if (tag == "TURBOPROP") Type = etTurboProp;
++ else if (tag == "TURBOJET") Type = etTurboJet;
++ else Type = etUnknown;
++
++ enginefile >> X;
++ enginefile >> Y;
++ enginefile >> Z;
++ enginefile >> SLThrustMax;
++ enginefile >> VacThrustMax;
++ enginefile >> MaxThrottle;
++ enginefile >> MinThrottle;
++ enginefile >> SLFuelFlowMax;
++ if (Type == 1)
++ enginefile >> SLOxiFlowMax;
++ enginefile.close();
++ } else {
++ cerr << "Unable to open engine definition file " << engineName << endl;
++ }
++
++ EngineNumber = num;
++ Thrust = 0.0;
++ Starved = Flameout = false;
++}
++
++
++FGEngine::~FGEngine(void)
++{
++}
++
++
++float FGEngine::CalcRocketThrust(void)
++{
++ float lastThrust;
++
++ Throttle = FCS->GetThrottle(EngineNumber);
++ lastThrust = Thrust; // last actual thrust
++
++ if (Throttle < MinThrottle || Starved) {
++ PctPower = Thrust = 0.0; // desired thrust
++ Flameout = true;
++ } else {
++ PctPower = Throttle / MaxThrottle;
++ Thrust = PctPower*((1.0 - Atmosphere->Getrho() / 0.002378)*(VacThrustMax - SLThrustMax) +
++ SLThrustMax); // desired thrust
++ Flameout = false;
++ }
++
++ Thrust += 0.8*(Thrust - lastThrust); // actual thrust
++
++ return Thrust;
++}
++
++
++float FGEngine::CalcPistonThrust(void)
++{
++ return Thrust;
++}
++
++
++float FGEngine::CalcThrust(void)
++{
++ switch(Type) {
++ case etRocket:
++ return CalcRocketThrust();
++ // break;
++ case etPiston:
++ return CalcPistonThrust();
++ // break;
++ default:
++ return 9999.0;
++ // break;
++ }
++}
++
++float FGEngine::CalcFuelNeed() {
++ FuelNeed = SLFuelFlowMax*PctPower;
++ return FuelNeed;
++}
++
++
++float FGEngine::CalcOxidizerNeed() {
++ OxidizerNeed = SLOxiFlowMax*PctPower;
++ return OxidizerNeed;
++}
++
--- /dev/null
--- /dev/null
++/*******************************************************************************
++
++ Header: FGEngine.h
++ Author: Jon S. Berndt
++ Date started: 01/21/99
++
++ ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ 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., 59 Temple
++ Place - Suite 330, Boston, MA 02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++
++Based on Flightgear code, which is based on LaRCSim. This class simulates
++a generic engine.
++
++HISTORY
++--------------------------------------------------------------------------------
++01/21/99 JSB Created
++
++********************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGEngine_H
++#define FGEngine_H
++
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#ifdef FGFS
++# include <Include/compiler.h>
++# include STL_STRING
++ FG_USING_STD(string);
++#else
++# include <string>
++#endif
++
++/*******************************************************************************
++DEFINES
++*******************************************************************************/
++
++/*******************************************************************************
++CLASS DECLARATION
++*******************************************************************************/
++
++class FGFDMExec;
++class FGState;
++class FGAtmosphere;
++class FGFCS;
++class FGAircraft;
++class FGTranslation;
++class FGRotation;
++class FGPosition;
++class FGAuxiliary;
++class FGOutput;
++
++class FGEngine
++{
++public:
++ FGEngine(FGFDMExec*, string, string, int);
++ ~FGEngine(void);
++
++ enum EngineType {etUnknown, etRocket, etPiston, etTurboProp, etTurboJet};
++
++ float GetThrottle(void) {return Throttle;}
++ float GetThrust(void) {return Thrust;}
++ bool GetStarved(void) {return Starved;}
++ bool GetFlameout(void) {return Flameout;}
++ int GetType(void) {return Type;}
++ string GetName() {return Name;}
++
++ void SetStarved(bool tt) {Starved = tt;}
++ void SetStarved(void) {Starved = true;}
++
++ float CalcThrust(void);
++ float CalcFuelNeed(void);
++ float CalcOxidizerNeed(void);
++
++private:
++ string Name;
++ EngineType Type;
++ float X, Y, Z;
++ float SLThrustMax;
++ float VacThrustMax;
++ float SLFuelFlowMax;
++ float SLOxiFlowMax;
++ float MaxThrottle;
++ float MinThrottle;
++
++ float Thrust;
++ float Throttle;
++ float FuelNeed, OxidizerNeed;
++ bool Starved;
++ bool Flameout;
++ float PctPower;
++ int EngineNumber;
++
++ FGFDMExec* FDMExec;
++ FGState* State;
++ FGAtmosphere* Atmosphere;
++ FGFCS* FCS;
++ FGAircraft* Aircraft;
++ FGTranslation* Translation;
++ FGRotation* Rotation;
++ FGPosition* Position;
++ FGAuxiliary* Auxiliary;
++ FGOutput* Output;
++
++protected:
++ float CalcRocketThrust(void);
++ float CalcPistonThrust(void);
++
++};
++
++/******************************************************************************/
++#endif
--- /dev/null
--- /dev/null
++/*******************************************************************************
++
++ Module: FGFCS.cpp
++ Author: Jon Berndt
++ Date started: 12/12/98
++ Purpose: Model the flight controls
++ Called by: FDMExec
++
++ ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ 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., 59 Temple
++ Place - Suite 330, Boston, MA 02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++This class models the flight controls for a specific airplane
++
++HISTORY
++--------------------------------------------------------------------------------
++12/12/98 JSB Created
++
++********************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#include "FGFCS.h"
++#include "FGState.h"
++#include "FGFDMExec.h"
++#include "FGAtmosphere.h"
++#include "FGAircraft.h"
++#include "FGTranslation.h"
++#include "FGRotation.h"
++#include "FGPosition.h"
++#include "FGAuxiliary.h"
++#include "FGOutput.h"
++
++/*******************************************************************************
++************************************ CODE **************************************
++*******************************************************************************/
++
++
++FGFCS::FGFCS(FGFDMExec* fdmex) : FGModel(fdmex)
++{
++ Name = "FGFCS";
++}
++
++
++FGFCS::~FGFCS(void)
++{
++}
++
++
++bool FGFCS::Run(void)
++{
++ if (!FGModel::Run()) {
++
++ } else {
++ }
++ return false;
++}
--- /dev/null
--- /dev/null
++/*******************************************************************************
++
++ Header: FGGFCS.h
++ Author: Jon S. Berndt
++ Date started: 12/12/98
++
++ ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ 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., 59 Temple
++ Place - Suite 330, Boston, MA 02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++HISTORY
++--------------------------------------------------------------------------------
++12/12/98 JSB Created
++
++********************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGFCS_H
++#define FGFCS_H
++
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#include "FGModel.h"
++
++/*******************************************************************************
++CLASS DECLARATION
++*******************************************************************************/
++
++
++class FGFCS : public FGModel
++{
++public:
++ FGFCS(FGFDMExec*);
++ ~FGFCS(void);
++
++ bool Run(void);
++
++ inline float GetDa(void) {return Da;}
++ inline float GetDe(void) {return De;}
++ inline float GetDr(void) {return Dr;}
++ inline float GetDf(void) {return Df;}
++ inline float GetDs(void) {return Ds;}
++ inline float GetThrottle(int ii) {return Throttle[ii];}
++
++ inline void SetDa(float tt) {Da = tt;}
++ inline void SetDe(float tt) {De = tt;}
++ inline void SetDr(float tt) {Dr = tt;}
++ inline void SetDf(float tt) {Df = tt;}
++ inline void SetDs(float tt) {Ds = tt;}
++ inline void SetThrottle(int ii, float tt) {Throttle[ii] = tt;}
++
++protected:
++
++private:
++ float Da, De, Dr, Df, Ds;
++ float Throttle[MAX_ENGINES];
++};
++
++/******************************************************************************/
++#endif
--- /dev/null
--- /dev/null
++/*******************************************************************************
++
++ Module: FGFDMExec.cpp
++ Author: Jon S. Berndt
++ Date started: 11/17/98
++ Purpose: Schedules and runs the model routines.
++ Called by: The GUI.
++
++ ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ 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., 59 Temple
++ Place - Suite 330, Boston, MA 02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++
++This class wraps up the simulation scheduling routines.
++
++HISTORY
++--------------------------------------------------------------------------------
++11/17/98 JSB Created
++
++********************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#ifdef FGFS
++# include <Include/compiler.h>
++# ifdef FG_HAVE_STD_INCLUDES
++# include <iostream>
++# include <ctime>
++# else
++# include <iostream.h>
++# include <time.h>
++# endif
++#else
++# include <iostream>
++# include <ctime>
++#endif
++
++#include "FGFDMExec.h"
++#include "FGState.h"
++#include "FGAtmosphere.h"
++#include "FGFCS.h"
++#include "FGAircraft.h"
++#include "FGTranslation.h"
++#include "FGRotation.h"
++#include "FGPosition.h"
++#include "FGAuxiliary.h"
++#include "FGOutput.h"
++
++/*******************************************************************************
++************************************ CODE **************************************
++*******************************************************************************/
++
++
++// Constructor
++
++FGFDMExec::FGFDMExec(void)
++{
++ FirstModel = 0;
++ Error = 0;
++ State = 0;
++ Atmosphere = 0;
++ FCS = 0;
++ Aircraft = 0;
++ Translation = 0;
++ Rotation = 0;
++ Position = 0;
++ Auxiliary = 0;
++ Output = 0;
++
++ // Instantiate this FDM Executive's Models
++
++ Atmosphere = new FGAtmosphere(this);
++ FCS = new FGFCS(this);
++ Aircraft = new FGAircraft(this);
++ Translation = new FGTranslation(this);
++ Rotation = new FGRotation(this);
++ Position = new FGPosition(this);
++ Auxiliary = new FGAuxiliary(this);
++ Output = new FGOutput(this);
++
++ State = new FGState(this);
++
++ // Initialize models so they can communicate with each other
++
++ if (!Atmosphere->InitModel()) {cerr << "Atmosphere model init failed"; Error+=1;}
++ if (!FCS->InitModel()) {cerr << "FCS model init failed"; Error+=2;}
++ if (!Aircraft->InitModel()) {cerr << "Aircraft model init failed"; Error+=4;}
++ if (!Translation->InitModel()){cerr << "Translation model init failed"; Error+=8;}
++ if (!Rotation->InitModel()) {cerr << "Rotation model init failed"; Error+=16;}
++ if (!Position->InitModel()) {cerr << "Position model init failed"; Error+=32;}
++ if (!Auxiliary->InitModel()) {cerr << "Auxiliary model init failed"; Error+=64;}
++ if (!Output->InitModel()) {cerr << "Output model init failed"; Error+=128;}
++
++ Schedule(Atmosphere, 5);
++ Schedule(FCS, 1);
++ Schedule(Aircraft, 1);
++ Schedule(Rotation, 1);
++ Schedule(Translation, 1);
++ Schedule(Position, 1);
++ Schedule(Auxiliary, 1);
++ Schedule(Output, 5);
++
++ terminate = false;
++ frozen = false;
++}
++
++
++FGFDMExec::~FGFDMExec(void)
++{
++}
++
++
++int FGFDMExec::Schedule(FGModel* model, int rate)
++{
++ FGModel* model_iterator;
++
++ model_iterator = FirstModel;
++
++ if (model_iterator == 0L) { // this is the first model
++
++ FirstModel = model;
++ FirstModel->NextModel = 0L;
++ FirstModel->SetRate(rate);
++
++ } else { // subsequent model
++
++ while (model_iterator->NextModel != 0L) {
++ model_iterator = model_iterator->NextModel;
++ }
++ model_iterator->NextModel = model;
++ model_iterator->NextModel->SetRate(rate);
++
++ }
++ return 0;
++}
++
++
++bool FGFDMExec::Run(void)
++{
++ FGModel* model_iterator;
++
++ if (frozen) return true;
++
++ model_iterator = FirstModel;
++ if (model_iterator == 0L) return false;
++
++ while (!model_iterator->Run())
++ {
++ model_iterator = model_iterator->NextModel;
++ if (model_iterator == 0L) break;
++ }
++
++ State->IncrTime();
++
++ return true;
++}
++
--- /dev/null
--- /dev/null
++/*******************************************************************************
++
++ Header: FGFDMExec.h
++ Author: Jon Berndt
++ Date started: 11/17/98
++
++ ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ 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., 59 Temple
++ Place - Suite 330, Boston, MA 02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++HISTORY
++--------------------------------------------------------------------------------
++11/17/98 JSB Created
++
++********************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGFDMEXEC_HEADER_H
++#define FGFDMEXEC_HEADER_H
++
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#include "FGModel.h"
++
++/*******************************************************************************
++CLASS DECLARATION
++*******************************************************************************/
++
++class FGState;
++class FGAtmosphere;
++class FGFCS;
++class FGAircraft;
++class FGTranslation;
++class FGRotation;
++class FGPosition;
++class FGAuxiliary;
++class FGOutput;
++
++class FGFDMExec
++{
++public:
++ FGFDMExec::FGFDMExec(void);
++ FGFDMExec::~FGFDMExec(void);
++
++ FGModel* FirstModel;
++
++ bool Initialize(void);
++ int Schedule(FGModel* model, int rate);
++ bool Run(void);
++ void Freeze(void) {frozen = true;}
++ void Resume(void) {frozen = false;}
++
++ inline FGState* GetState(void) {return State;}
++ inline FGAtmosphere* GetAtmosphere(void) {return Atmosphere;}
++ inline FGFCS* GetFCS(void) {return FCS;}
++ inline FGAircraft* GetAircraft(void) {return Aircraft;}
++ inline FGTranslation* GetTranslation(void) {return Translation;}
++ inline FGRotation* GetRotation(void) {return Rotation;}
++ inline FGPosition* GetPosition(void) {return Position;}
++ inline FGAuxiliary* GetAuxiliary(void) {return Auxiliary;}
++ inline FGOutput* GetOutput(void) {return Output;}
++
++private:
++ bool frozen;
++ bool terminate;
++ int Error;
++
++ FGState* State;
++ FGAtmosphere* Atmosphere;
++ FGFCS* FCS;
++ FGAircraft* Aircraft;
++ FGTranslation* Translation;
++ FGRotation* Rotation;
++ FGPosition* Position;
++ FGAuxiliary* Auxiliary;
++ FGOutput* Output;
++
++protected:
++};
++
++/******************************************************************************/
++#endif
--- /dev/null
--- /dev/null
++#include "FGFDMExec.h"
++#include "FGRotation.h"
++#include "FGAtmosphere.h"
++#include "FGState.h"
++#include "FGFCS.h"
++#include "FGAircraft.h"
++#include "FGTranslation.h"
++#include "FGPosition.h"
++#include "FGAuxiliary.h"
++#include "FGOutput.h"
++
++#include <iostream>
++#include <ctime>
++
++void main(int argc, char** argv)
++{
++ FGFDMExec* FDMExec;
++
++ struct timespec short_wait = {0,100000000};
++ struct timespec no_wait = {0,100000000};
++
++ if (argc != 3) {
++ cout << endl
++ << " You must enter the name of a registered aircraft and reset point:"
++ << endl << endl << " FDM <aircraft name> <reset file>" << endl;
++ exit(0);
++ }
++
++ FDMExec = new FGFDMExec();
++
++ FDMExec->GetAircraft()->LoadAircraft("aircraft", "engine", string(argv[1]));
++ FDMExec->GetState()->Reset("aircraft", string(argv[2]));
++
++ while (FDMExec->GetState()->Getsim_time() <= 25.0)
++ {
++ FDMExec->Run();
++ nanosleep(&short_wait,&no_wait);
++ }
++
++ delete FDMExec;
++}
--- /dev/null
--- /dev/null
++/*******************************************************************************
++
++Module: FGMatrix.cpp
++Author: Tony Peden [formatted here by JSB]
++Date started: ??
++Purpose: FGMatrix class
++Called by: Various
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++
++
++ARGUMENTS
++--------------------------------------------------------------------------------
++
++
++HISTORY
++--------------------------------------------------------------------------------
++??/??/?? TP Created
++
++********************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#include <stdlib.h>
++#include "FGMatrix.h"
++#include <iostream.h>
++#include <iomanip.h>
++#include <fstream.h>
++
++/*******************************************************************************
++DEFINES
++*******************************************************************************/
++
++#pragma warn -use
++
++/*******************************************************************************
++CONSTANTS
++*******************************************************************************/
++
++
++/*******************************************************************************
++TYPEDEFS
++*******************************************************************************/
++
++
++/*******************************************************************************
++GLOBALS
++*******************************************************************************/
++
++
++/*******************************************************************************
++************************************ CODE **************************************
++*******************************************************************************/
++
++double** alloc(int rows,int cols)
++{
++ double **A;
++
++ A = new double *[rows+1];
++ if (!A) return NULL;
++
++ for (int i=0;i<=rows;i++){
++ A[i]=new double[cols+1];
++ if (!A[i]) return NULL;
++ }
++ return A;
++}
++
++
++void dealloc(double **A, int rows, int cols)
++{
++ for(int i=0;i<=rows;i++){
++ delete[] A[i];
++ }
++
++ delete[] A;
++}
++
++
++FGMatrix::FGMatrix(unsigned rows, unsigned cols)
++{
++ this->rows=rows;
++ this->cols=cols;
++ keep=false;
++ data=alloc(rows,cols);
++}
++
++
++FGMatrix::FGMatrix(const FGMatrix& A)
++{
++ data=NULL;
++ *this=A;
++}
++
++
++FGMatrix::~FGMatrix(void)
++{
++ if (keep == false) {
++ dealloc(data,rows,cols);
++ rows=cols=0;
++ }
++}
++
++
++FGMatrix& FGMatrix::operator=(const FGMatrix& A)
++{
++ if (&A != this) {
++ if (data != NULL) dealloc(data,rows,cols);
++
++ width = A.width;
++ prec = A.prec;
++ delim = A.delim;
++ origin = A.origin;
++ rows = A.rows;
++ cols = A.cols;
++ keep = false;
++
++ if (A.keep == true) {
++ data = A.data;
++ } else {
++ data = alloc(rows,cols);
++ for (int i=0; i<=rows; i++) {
++ for (int j=0; j<=cols; j++) {
++ data[i][j] = A.data[i][j];
++ }
++ }
++ }
++ }
++ return *this;
++}
++
++
++double& FGMatrix::operator()(unsigned row, unsigned col)
++{
++ return data[row][col];
++}
++
++
++unsigned FGMatrix::Rows(void) const
++{
++ return rows;
++}
++
++
++unsigned FGMatrix::Cols(void) const
++{
++ return cols;
++}
++
++
++void FGMatrix::SetOParams(char delim,int width,int prec,int origin)
++{
++ FGMatrix::delim=delim;
++ FGMatrix::width=width;
++ FGMatrix::prec=prec;
++ FGMatrix::origin=origin;
++}
++
++
++void FGMatrix::InitMatrix(double value)
++{
++ if (data) {
++ for (int i=0;i<=rows;i++) {
++ for (int j=0;j<=cols;j++) {
++ operator()(i,j) = value;
++ }
++ }
++ }
++}
++
++
++void FGMatrix::InitMatrix(void)
++{
++ this->InitMatrix(0);
++}
++
++
++FGMatrix operator-(FGMatrix& A, FGMatrix& B)
++{
++ if ((A.Rows() != B.Rows()) || (A.Cols() != B.Cols())) {
++ cout << endl << "FGMatrix::operator-" << endl << '\t';
++ cout << "Subtraction not defined for matrices of different sizes";
++ cout << endl;
++ exit(1);
++ }
++
++ FGMatrix Diff(A.Rows(),A.Cols());
++ Diff.keep=true;
++ for (int i=1;i<=A.Rows();i++) {
++ for (int j=1;j<=A.Cols();j++) {
++ Diff(i,j)=A(i,j)-B(i,j);
++ }
++ }
++ return Diff;
++}
++
++
++void operator-=(FGMatrix &A,FGMatrix &B)
++{
++ if ((A.Rows() != B.Rows()) || (A.Cols() != B.Cols())) {
++ cout << endl << "FGMatrix::operator-" << endl << '\t';
++ cout << "Subtraction not defined for matrices of different sizes";
++ cout << endl;
++ exit(1);
++ }
++
++ for (int i=1;i<=A.Rows();i++) {
++ for (int j=1;j<=A.Cols();j++) {
++ A(i,j)-=B(i,j);
++ }
++ }
++}
++
++
++FGMatrix operator+(FGMatrix& A, FGMatrix& B)
++{
++ if ((A.Rows() != B.Rows()) || (A.Cols() != B.Cols())) {
++ cout << endl << "FGMatrix::operator+" << endl << '\t';
++ cout << "Addition not defined for matrices of different sizes";
++ cout << endl;
++ exit(1);
++ }
++
++ FGMatrix Sum(A.Rows(),A.Cols());
++ Sum.keep = true;
++ for (int i=1;i<=A.Rows();i++) {
++ for (int j=1;j<=A.Cols();j++) {
++ Sum(i,j)=A(i,j)+B(i,j);
++ }
++ }
++ return Sum;
++}
++
++
++void operator+=(FGMatrix &A,FGMatrix &B)
++{
++ if ((A.Rows() != B.Rows()) || (A.Cols() != B.Cols())) {
++ cout << endl << "FGMatrix::operator+" << endl << '\t';
++ cout << "Addition not defined for matrices of different sizes";
++ cout << endl;
++ exit(1);
++ }
++ for (int i=1;i<=A.Rows();i++) {
++ for (int j=1;j<=A.Cols();j++) {
++ A(i,j)+=B(i,j);
++ }
++ }
++}
++
++
++FGMatrix operator*(double scalar,FGMatrix &A)
++{
++ FGMatrix Product(A.Rows(),A.Cols());
++ Product.keep = true;
++ for (int i=1;i<=A.Rows();i++) {
++ for (int j=1;j<=A.Cols();j++) {
++ Product(i,j) = scalar*A(i,j);
++ }
++ }
++ return Product;
++}
++
++
++void operator*=(FGMatrix &A,double scalar)
++{
++ for (int i=1;i<=A.Rows();i++) {
++ for (int j=1;j<=A.Cols();j++) {
++ A(i,j)*=scalar;
++ }
++ }
++}
++
++
++FGMatrix operator*(FGMatrix &Left, FGMatrix &Right)
++{
++ if (Left.Cols() != Right.Rows()) {
++ cout << endl << "FGMatrix::operator*" << endl << '\t';
++ cout << "The number of rows in the right matrix must match the number";
++ cout << endl << '\t' << "of columns in the left." << endl;
++ cout << '\t' << "Multiplication not defined." << endl;
++ exit(1);
++ }
++
++ FGMatrix Product(Left.Rows(),Right.Cols());
++ Product.keep = true;
++ for (int i=1;i<=Left.Rows();i++) {
++ for (int j=1;j<=Right.Cols();j++) {
++ Product(i,j) = 0;
++ for (int k=1;k<=Left.Cols();k++) {
++ Product(i,j)+=Left(i,k)*Right(k,j);
++ }
++ }
++ }
++ return Product;
++}
++
++
++void operator*=(FGMatrix &Left,FGMatrix &Right)
++{
++ if (Left.Cols() != Right.Rows()) {
++ cout << endl << "FGMatrix::operator*" << endl << '\t';
++ cout << "The number of rows in the right matrix must match the number";
++ cout << endl << '\t' << "of columns in the left." << endl;
++ cout << '\t' << "Multiplication not defined." << endl;
++ exit(1);
++ }
++
++ double **prod;
++
++ prod=alloc(Left.Rows(),Right.Cols());
++ for (int i=1;i<=Left.Rows();i++) {
++ for (int j=1;j<=Right.Cols();j++) {
++ prod[i][j] = 0;
++ for (int k=1;k<=Left.Cols();k++) {
++ prod[i][j]+=Left(i,k)*Right(k,j);
++ }
++ }
++ }
++ dealloc(Left.data,Left.Rows(),Left.Cols());
++ Left.data=prod;
++ Left.cols=Right.cols;
++}
++
++
++FGMatrix operator/(FGMatrix& A, double scalar)
++{
++ FGMatrix Quot(A.Rows(),A.Cols());
++ A.keep = true;
++ for (int i=1;i<=A.Rows();i++) {
++ for (int j=1;j<=A.Cols();j++) {
++ Quot(i,j)=A(i,j)/scalar;
++ }
++ }
++ return Quot;
++}
++
++
++void operator/=(FGMatrix &A,double scalar)
++{
++ for (int i=1;i<=A.Rows();i++) {
++ for (int j=1;j<=A.Cols();j++) {
++ A(i,j)/=scalar;
++ }
++ }
++}
++
++
++void FGMatrix::T(void)
++{
++ if (rows==cols)
++ TransposeSquare();
++ else
++ TransposeNonSquare();
++}
++
++
++void FGMatrix::TransposeSquare(void)
++{
++ for (int i=1;i<=rows;i++) {
++ for (int j=i+1;j<=cols;j++) {
++ double tmp=data[i][j];
++ data[i][j]=data[j][i];
++ data[j][i]=tmp;
++ }
++ }
++}
++
++
++void FGMatrix::TransposeNonSquare(void)
++{
++ double **tran;
++
++ tran=alloc(rows,cols);
++ for (int i=1;i<=rows;i++) {
++ for (int j=1;j<=cols;j++) {
++ tran[j][i]=data[i][j];
++ }
++ }
++ dealloc(data,rows,cols);
++
++ data=tran;
++ unsigned m=rows;
++ rows=cols;
++ cols=m;
++}
++
++
++FGColumnVector::FGColumnVector(void):FGMatrix(3,1) { }
++FGColumnVector::FGColumnVector(int m):FGMatrix(m,1) { }
++FGColumnVector::FGColumnVector(FGColumnVector& b):FGMatrix(b) { }
++FGColumnVector::~FGColumnVector() { }
++double& FGColumnVector::operator()(int m)
++{
++ return FGMatrix::operator()(m,1);
++}
++
--- /dev/null
--- /dev/null
++/*******************************************************************************
++
++Header: FGMatrix.h
++Author: Tony Peden [formatted here by Jon Berndt]
++Date started: Unknown
++
++HISTORY
++--------------------------------------------------------------------------------
++??/??/?? TP Created
++
++/*******************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGMATRIX_H
++#define FGMATRIX_H
++
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#include <stdlib.h>
++#include <iostream.h>
++#include <fstream.h>
++
++/*******************************************************************************
++DEFINES
++*******************************************************************************/
++
++
++/*******************************************************************************
++CONSTANTS
++*******************************************************************************/
++
++
++/*******************************************************************************
++TYPEDEFS
++*******************************************************************************/
++
++
++/*******************************************************************************
++GLOBALS
++*******************************************************************************/
++
++class FGMatrix
++{
++private:
++ double **data;
++ unsigned rows,cols;
++ bool keep;
++ char delim;
++ int width,prec,origin;
++ void TransposeSquare(void);
++ void TransposeNonSquare(void);
++
++public:
++ FGMatrix(unsigned rows, unsigned cols);
++ FGMatrix(const FGMatrix& A);
++ ~FGMatrix(void);
++
++ FGMatrix& FGMatrix::operator=(const FGMatrix& A);
++ double& FGMatrix::operator()(unsigned row, unsigned col);
++
++ unsigned FGMatrix::Rows(void) const;
++ unsigned FGMatrix::Cols(void) const;
++
++ void FGMatrix::T(void);
++ void InitMatrix(void);
++ void InitMatrix(double value);
++
++ friend FGMatrix operator-(FGMatrix& A, FGMatrix& B);
++ friend FGMatrix operator+(FGMatrix& A, FGMatrix& B);
++ friend FGMatrix operator*(double scalar,FGMatrix& A);
++ friend FGMatrix operator*(FGMatrix& Left, FGMatrix& Right);
++ friend FGMatrix operator/(FGMatrix& A, double scalar);
++
++ friend void operator-=(FGMatrix &A,FGMatrix &B);
++ friend void operator+=(FGMatrix &A,FGMatrix &B);
++ friend void operator*=(FGMatrix &A,FGMatrix &B);
++ friend void operator*=(FGMatrix &A,double scalar);
++ friend void operator/=(FGMatrix &A,double scalar);
++
++ void SetOParams(char delim,int width,int prec, int origin=0);
++};
++
++class FGColumnVector : public FGMatrix
++{
++public:
++ FGColumnVector(void);
++ FGColumnVector(int m);
++ FGColumnVector(FGColumnVector& b);
++ ~FGColumnVector();
++
++ double& operator()(int m);
++};
++
++/******************************************************************************/
++#endif
--- /dev/null
--- /dev/null
++/*******************************************************************************
++
++ Module: FGModel.cpp
++ Author: Jon Berndt
++ Date started: 11/11/98
++ Purpose: Base class for all models
++ Called by: FGSimExec, et. al.
++
++ ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ 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., 59 Temple
++ Place - Suite 330, Boston, MA 02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++This base class for the FGAero, FGRotational, etc. classes defines methods
++common to all models.
++
++HISTORY
++--------------------------------------------------------------------------------
++11/11/98 JSB Created
++
++********************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#include "FGModel.h"
++#include "FGState.h"
++#include "FGFDMExec.h"
++#include "FGAtmosphere.h"
++#include "FGFCS.h"
++#include "FGAircraft.h"
++#include "FGTranslation.h"
++#include "FGRotation.h"
++#include "FGPosition.h"
++#include "FGAuxiliary.h"
++#include "FGOutput.h"
++
++/*******************************************************************************
++************************************ CODE **************************************
++*******************************************************************************/
++
++FGModel::FGModel(FGFDMExec* fdmex)
++{
++ FDMExec = fdmex;
++ NextModel = 0L;
++
++ State = 0;
++ Atmosphere = 0;
++ FCS = 0;
++ Aircraft = 0;
++ Translation = 0;
++ Rotation = 0;
++ Position = 0;
++ Auxiliary = 0;
++ Output = 0;
++
++ exe_ctr = 1;
++}
++
++
++FGModel::~FGModel()
++{
++}
++
++
++bool FGModel::InitModel(void)
++{
++ State = FDMExec->GetState();
++ Atmosphere = FDMExec->GetAtmosphere();
++ FCS = FDMExec->GetFCS();
++ Aircraft = FDMExec->GetAircraft();
++ Translation = FDMExec->GetTranslation();
++ Rotation = FDMExec->GetRotation();
++ Position = FDMExec->GetPosition();
++ Auxiliary = FDMExec->GetAuxiliary();
++ Output = FDMExec->GetOutput();
++
++ if (!State ||
++ !Atmosphere ||
++ !FCS ||
++ !Aircraft ||
++ !Translation ||
++ !Rotation ||
++ !Position ||
++ !Auxiliary ||
++ !Output) return(false);
++ else return(true);
++}
++
++
++bool FGModel::Run()
++{
++ if (exe_ctr == 1) {
++ if (exe_ctr++ >= rate) exe_ctr = 1;
++ return false;
++ } else {
++ if (exe_ctr++ >= rate) exe_ctr = 1;
++ return true;
++ }
++}
++
++
--- /dev/null
--- /dev/null
++/*******************************************************************************
++
++ Header: FGModel.h
++ Author: Jon Berndt
++ Date started: 11/21/98
++
++ ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ 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., 59 Temple
++ Place - Suite 330, Boston, MA 02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++HISTORY
++--------------------------------------------------------------------------------
++11/22/98 JSB Created
++
++********************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGMODEL_H
++#define FGMODEL_H
++
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#include "FGDefs.h"
++
++#ifdef FGFS
++# include <Include/compiler.h>
++# include STL_STRING
++# ifdef FG_HAVE_STD_INCLUDES
++# include <iostream>
++# else
++# include <iostream.h>
++# endif
++ FG_USING_STD(string);
++#else
++# include <string>
++# include <iostream>
++#endif
++
++/*******************************************************************************
++DEFINES
++*******************************************************************************/
++
++/*******************************************************************************
++CLASS DECLARATION
++*******************************************************************************/
++
++class FGFDMExec;
++class FGState;
++class FGAtmosphere;
++class FGFCS;
++class FGAircraft;
++class FGTranslation;
++class FGRotation;
++class FGPosition;
++class FGAuxiliary;
++class FGOutput;
++
++class FGModel
++{
++public:
++ FGModel(FGFDMExec*);
++ ~FGModel(void);
++
++ FGModel* NextModel;
++ string Name;
++ virtual bool Run(void);
++ virtual bool InitModel(void);
++ void SetRate(int tt) {rate = tt;};
++
++protected:
++ int exe_ctr;
++ int rate;
++
++ FGFDMExec* FDMExec;
++ FGState* State;
++ FGAtmosphere* Atmosphere;
++ FGFCS* FCS;
++ FGAircraft* Aircraft;
++ FGTranslation* Translation;
++ FGRotation* Rotation;
++ FGPosition* Position;
++ FGAuxiliary* Auxiliary;
++ FGOutput* Output;
++
++private:
++};
++
++/******************************************************************************/
++#endif
--- /dev/null
--- /dev/null
++/*******************************************************************************
++
++ Module: FGOutput.cpp
++ Author: Jon Berndt
++ Date started: 12/02/98
++ Purpose: Manage output of sim parameters to file or stdout
++ Called by: FGSimExec
++
++ ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ 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., 59 Temple
++ Place - Suite 330, Boston, MA 02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++This is the place where you create output routines to dump data for perusal
++later. Some machines may not support the ncurses console output. Borland is one
++of those environments which does not, so the ncurses stuff is commented out.
++
++HISTORY
++--------------------------------------------------------------------------------
++12/02/98 JSB Created
++
++********************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#ifdef FGFS
++# include <Include/compiler.h>
++# ifdef FG_HAVE_STD_INCLUDES
++# include <iostream>
++# else
++# include <iostream.h>
++# endif
++#else
++# include <iostream>
++#endif
++
++#ifdef HAVE_CURSES
++ #include <ncurses.h>
++#endif
++
++#include "FGOutput.h"
++#include "FGState.h"
++#include "FGFDMExec.h"
++#include "FGAtmosphere.h"
++#include "FGFCS.h"
++#include "FGAircraft.h"
++#include "FGTranslation.h"
++#include "FGRotation.h"
++#include "FGPosition.h"
++#include "FGAuxiliary.h"
++
++/*******************************************************************************
++************************************ CODE **************************************
++*******************************************************************************/
++
++FGOutput::FGOutput(FGFDMExec* fdmex) : FGModel(fdmex)
++{
++ Name = "FGOutput";
++ FirstPass = true;
++#ifdef HAVE_CURSES
++ initscr();
++ cbreak();
++ noecho();
++#endif
++}
++
++
++FGOutput::~FGOutput(void)
++{
++}
++
++
++bool FGOutput::Run(void)
++{
++ if (!FGModel::Run()) {
++ DelimitedOutput();
++// ConsoleOutput();
++ } else {
++ }
++ return false;
++}
++
++
++void FGOutput::ConsoleOutput(void)
++{
++#ifdef HAVE_CURSES
++ string buffer;
++
++ clear();
++ move(1,1); insstr("Quaternions");
++ move(2,5); insstr("Q0");
++ move(2,16); insstr("Q1");
++ move(2,27); insstr("Q2");
++ move(2,38); insstr("Q3");
++
++ move(3,1); buffer = Rotation->GetQ0(); insstr(buffer.c_str());
++ move(3,12); buffer = Rotation->GetQ1(); insstr(buffer.c_str());
++ move(3,23); buffer = Rotation->GetQ2(); insstr(buffer.c_str());
++ move(3,34); buffer = Rotation->GetQ3(); insstr(buffer.c_str());
++
++ move(0,0); insstr("Time: ");
++ move(0,6); insstr(gcvt(State->Getsim_time(),6,buffer));
++
++ move(2,46); insstr("Phi");
++ move(2,55); insstr("Tht");
++ move(2,64); insstr("Psi");
++
++ move(3,45); buffer = Rotation->Getphi(); insstr(buffer.c_str());
++ move(3,54); buffer = Rotation->Gettht(); insstr(buffer.c_str());
++ move(3,63); buffer = Rotation->Getpsi(); insstr(buffer.c_str());
++
++ move(5,47); insstr("U");
++ move(5,56); insstr("V");
++ move(5,65); insstr("W");
++
++ move(6,45); buffer = Translation->GetU(); insstr(buffer.c_str());
++ move(6,54); buffer = Translation->GetV(); insstr(buffer.c_str());
++ move(6,63); buffer = Translation->GetW(); insstr(buffer.c_str());
++
++ move(8,47); insstr("Fx");
++ move(8,56); insstr("Fy");
++ move(8,65); insstr("Fz");
++
++ move(9,45); buffer = Aircraft->GetFx(); insstr(buffer.c_str());
++ move(9,54); buffer = Aircraft->GetFy(); insstr(buffer.c_str());
++ move(9,63); buffer = Aircraft->GetFz(); insstr(buffer.c_str());
++
++ move(11,47); insstr("Fn");
++ move(11,56); insstr("Fe");
++ move(11,65); insstr("Fd");
++
++ move(12,45); buffer = Position->GetFn(); insstr(buffer.c_str());
++ move(12,54); buffer = Position->GetFe(); insstr(buffer.c_str());
++ move(12,63); buffer = Position->GetFd(); insstr(buffer.c_str());
++
++ move(14,47); insstr("Latitude");
++ move(14,57); insstr("Longitude");
++ move(14,67); insstr("Altitude");
++
++ move(15,47); buffer = State->Getlatitude(); insstr(buffer.c_str());
++ move(15,57); buffer = State->Getlongitude(); insstr(buffer.c_str());
++ move(15,67); buffer = State->Geth(); insstr(buffer.c_str());
++
++ refresh();
++
++ move(LINES-1,1);
++ refresh();
++#endif
++}
++
++
++void FGOutput::DelimitedOutput(void)
++{
++ if (FirstPass) {
++ cout << "Time,";
++ cout << "Altitude,";
++ cout << "Phi,";
++ cout << "Tht,";
++ cout << "Psi,";
++ cout << "Rho,";
++ cout << "Vtotal,";
++ cout << "U,";
++ cout << "V,";
++ cout << "W,";
++ cout << "Vn,";
++ cout << "Ve,";
++ cout << "Vd,";
++ cout << "Udot,";
++ cout << "Vdot,";
++ cout << "Wdot,";
++ cout << "Fx,";
++ cout << "Fy,";
++ cout << "Fz,";
++ cout << "Latitude,";
++ cout << "Longitude,";
++ cout << "QBar,";
++ cout << "Alpha";
++ cout << endl;
++ FirstPass = false;
++ } else {
++ cout << State->Getsim_time() << ",";
++ cout << State->Geth() << ",";
++ cout << Rotation->Getphi() << ",";
++ cout << Rotation->Gettht() << ",";
++ cout << Rotation->Getpsi() << ",";
++ cout << Atmosphere->Getrho() << ",";
++ cout << State->GetVt() << ",";
++ cout << Translation->GetU() << ",";
++ cout << Translation->GetV() << ",";
++ cout << Translation->GetW() << ",";
++ cout << Position->GetVn() << ",";
++ cout << Position->GetVe() << ",";
++ cout << Position->GetVd() << ",";
++ cout << Translation->GetUdot() << ",";
++ cout << Translation->GetVdot() << ",";
++ cout << Translation->GetWdot() << ",";
++ cout << Aircraft->GetFx() << ",";
++ cout << Aircraft->GetFy() << ",";
++ cout << Aircraft->GetFz() << ",";
++ cout << State->Getlatitude() << ",";
++ cout << State->Getlongitude() << ",";
++ cout << State->Getqbar() << ",";
++ cout << Translation->Getalpha() << "";
++ cout << endl;
++ }
++}
--- /dev/null
--- /dev/null
++/*******************************************************************************
++
++ Header: FGOutput.h
++ Author: Jon Berndt
++ Date started: 12/2/98
++
++ ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ 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., 59 Temple
++ Place - Suite 330, Boston, MA 02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++HISTORY
++--------------------------------------------------------------------------------
++12/02/98 JSB Created
++
++********************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGOUTPUT_H
++#define FGOUTPUT_H
++
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#include "FGModel.h"
++
++/*******************************************************************************
++CLASS DECLARATION
++*******************************************************************************/
++
++class FGOutput : public FGModel
++{
++public:
++ FGOutput(FGFDMExec*);
++ ~FGOutput(void);
++
++ bool Run(void);
++
++ void ConsoleOutput(void);
++ void DelimitedOutput(void);
++
++protected:
++
++private:
++ bool FirstPass;
++};
++
++/******************************************************************************/
++#endif
++
--- /dev/null
--- /dev/null
++/*******************************************************************************
++
++ Module: FGPosition.cpp
++ Author: Jon S. Berndt
++ Date started: 01/05/99
++ Purpose: Integrate the EOM to determine instantaneous position
++ Called by: FGFDMExec
++
++ ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ 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., 59 Temple
++ Place - Suite 330, Boston, MA 02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++This class encapsulates the integration of rates and accelerations to get the
++current position of the aircraft.
++
++HISTORY
++--------------------------------------------------------------------------------
++01/05/99 JSB Created
++
++********************************************************************************
++COMMENTS, REFERENCES, and NOTES
++********************************************************************************
++[1] Cooke, Zyda, Pratt, and McGhee, "NPSNET: Flight Simulation Dynamic Modeling
++ Using Quaternions", Presence, Vol. 1, No. 4, pp. 404-420 Naval Postgraduate
++ School, January 1994
++[2] D. M. Henderson, "Euler Angles, Quaternions, and Transformation Matrices",
++ JSC 12960, July 1977
++[3] Richard E. McFarland, "A Standard Kinematic Model for Flight Simulation at
++ NASA-Ames", NASA CR-2497, January 1975
++[4] Barnes W. McCormick, "Aerodynamics, Aeronautics, and Flight Mechanics",
++ Wiley & Sons, 1979 ISBN 0-471-03032-5
++[5] Bernard Etkin, "Dynamics of Flight, Stability and Control", Wiley & Sons,
++ 1982 ISBN 0-471-08936-2
++
++********************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#ifdef FGFS
++# include <Include/compiler.h>
++# ifdef FG_HAVE_STD_INCLUDES
++# include <cmath>
++# else
++# include <math.h>
++# endif
++#else
++# include <cmath>
++#endif
++
++#include "FGPosition.h"
++#include "FGAtmosphere.h"
++#include "FGState.h"
++#include "FGFDMExec.h"
++#include "FGFCS.h"
++#include "FGAircraft.h"
++#include "FGTranslation.h"
++#include "FGRotation.h"
++#include "FGAuxiliary.h"
++#include "FGOutput.h"
++
++/*******************************************************************************
++************************************ CODE **************************************
++*******************************************************************************/
++
++
++FGPosition::FGPosition(FGFDMExec* fdmex) : FGModel(fdmex)
++{
++ Name = "FGPosition";
++ AccelN = AccelE = AccelD = 0.0;
++ LongitudeDot = LatitudeDot = RadiusDot = 0.0;
++}
++
++
++FGPosition::~FGPosition(void)
++{
++}
++
++
++bool FGPosition:: Run(void)
++{
++ float tanLat, cosLat;
++
++ if (!FGModel::Run()) {
++ GetState();
++ T[1][1] = Q0*Q0 + Q1*Q1 - Q2*Q2 - Q3*Q3; // Page A-11
++ T[1][2] = 2*(Q1*Q2 + Q0*Q3); // From
++ T[1][3] = 2*(Q1*Q3 - Q0*Q2); // Reference [2]
++ T[2][1] = 2*(Q1*Q2 - Q0*Q3);
++ T[2][2] = Q0*Q0 - Q1*Q1 + Q2*Q2 - Q3*Q3;
++ T[2][3] = 2*(Q2*Q3 + Q0*Q1);
++ T[3][1] = 2*(Q1*Q3 + Q0*Q2);
++ T[3][2] = 2*(Q2*Q3 - Q0*Q1);
++ T[3][3] = Q0*Q0 - Q1*Q1 - Q2*Q2 + Q3*Q3;
++
++ Fn = T[1][1]*Fx + T[2][1]*Fy + T[3][1]*Fz; // Eqn. 3.5
++ Fe = T[1][2]*Fx + T[2][2]*Fy + T[3][2]*Fz; // From
++ Fd = T[1][3]*Fx + T[2][3]*Fy + T[3][3]*Fz; // Reference [3]
++
++ tanLat = tan(Latitude); // I made this up
++ cosLat = cos(Latitude);
++
++ lastAccelN = AccelN;
++ lastAccelE = AccelE;
++ lastAccelD = AccelD;
++
++ Vn = T[1][1]*U + T[2][1]*V + T[3][1]*W;
++ Ve = T[1][2]*U + T[2][2]*V + T[3][2]*W;
++ Vd = T[1][3]*U + T[2][3]*V + T[3][3]*W;
++
++ AccelN = invMass * Fn + invRadius * (Vn*Vd - Ve*Ve*tanLat); // Eqn. 3.6
++ AccelE = invMass * Fe + invRadius * (Ve*Vd + Vn*Ve*tanLat); // From
++ AccelD = invMass * Fd - invRadius * (Vn*Vn + Ve*Ve); // Reference [3]
++
++ Vn += 0.5*dt*rate*(3.0*AccelN - lastAccelN); // Eqn. 3.7
++ Ve += 0.5*dt*rate*(3.0*AccelE - lastAccelE); // From
++ Vd += 0.5*dt*rate*(3.0*AccelD - lastAccelD); // Reference [3]
++
++ Vee = Ve - OMEGAEARTH * (Radius) * cosLat; // From Eq. 3.8
++ // Reference [3]
++ lastLatitudeDot = LatitudeDot;
++ lastLongitudeDot = LongitudeDot;
++ lastRadiusDot = RadiusDot;
++
++ if (cosLat != 0) LongitudeDot = Ve / (Radius * cosLat);
++ LatitudeDot = Vn * invRadius;
++ RadiusDot = -Vd;
++
++ Longitude += 0.5*dt*rate*(LongitudeDot + lastLongitudeDot);
++ Latitude += 0.5*dt*rate*(LatitudeDot + lastLatitudeDot);
++ Radius += 0.5*dt*rate*(RadiusDot + lastRadiusDot);
++
++ PutState();
++ return false;
++ } else {
++ return true;
++ }
++}
++
++
++void FGPosition::GetState(void)
++{
++ dt = State->Getdt();
++
++ Q0 = Rotation->GetQ0();
++ Q1 = Rotation->GetQ1();
++ Q2 = Rotation->GetQ2();
++ Q3 = Rotation->GetQ3();
++
++ Fx = Aircraft->GetFx();
++ Fy = Aircraft->GetFy();
++ Fz = Aircraft->GetFz();
++
++ U = Translation->GetU();
++ V = Translation->GetV();
++ W = Translation->GetW();
++
++ Latitude = State->Getlatitude();
++ Longitude = State->Getlongitude();
++
++ invMass = 1.0 / Aircraft->GetMass();
++ invRadius = 1.0 / (State->Geth() + EARTHRAD);
++ Radius = State->Geth() + EARTHRAD;
++}
++
++
++void FGPosition::PutState(void)
++{
++ State->Setlatitude(Latitude);
++ State->Setlongitude(Longitude);
++ State->Seth(Radius - EARTHRAD);
++}
++
--- /dev/null
--- /dev/null
++/*******************************************************************************
++
++ Header: FGPosition.h
++ Author: Jon S. Berndt
++ Date started: 1/5/99
++
++ ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ 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., 59 Temple
++ Place - Suite 330, Boston, MA 02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++HISTORY
++--------------------------------------------------------------------------------
++01/05/99 JSB Created
++
++********************************************************************************
++COMMENTS, REFERENCES, and NOTES
++********************************************************************************
++
++********************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGPOSITION_H
++#define FGPOSITION_H
++
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++#include "FGModel.h"
++
++/*******************************************************************************
++CLASS DECLARATION
++*******************************************************************************/
++
++class FGPosition : public FGModel
++{
++public:
++ FGPosition(FGFDMExec*);
++ ~FGPosition(void);
++
++ inline float GetFn(void) {return Fn;}
++ inline float GetFe(void) {return Fe;}
++ inline float GetFd(void) {return Fd;}
++
++ inline float GetVn(void) {return Vn;}
++ inline float GetVe(void) {return Ve;}
++ inline float GetVd(void) {return Vd;}
++
++ inline float GetT(int r, int c) {return T[r][c];}
++ inline void SetT(float t1, float t2, float t3, float t4, float t5, float t6,
++ float t7, float t8, float t9)
++ {T[1][1]=t1; T[1][2]=t2 ;T[1][3]=t3;
++ T[2][1]=t4; T[2][2]=t5 ;T[2][3]=t6;
++ T[3][1]=t7; T[3][2]=t8 ;T[3][3]=t9;}
++
++ bool Run(void);
++
++protected:
++
++private:
++ float T[4][4];
++ float Q0, Q1, Q2, Q3;
++ float Fn, Fe, Fd;
++ float Fx, Fy, Fz;
++ float U, V, W;
++ float Vn, Ve, Vd, Vee;
++ float invMass, invRadius;
++ float Radius;
++ float AccelN, AccelE, AccelD;
++ float lastAccelN, lastAccelE, lastAccelD;
++ float LatitudeDot, LongitudeDot, RadiusDot;
++ float lastLatitudeDot, lastLongitudeDot, lastRadiusDot;
++ float Longitude, Latitude;
++ float dt;
++
++ void GetState(void);
++ void PutState(void);
++};
++
++/******************************************************************************/
++#endif
--- /dev/null
--- /dev/null
++/*******************************************************************************
++
++ Module: FGRotation.cpp
++ Author: Jon Berndt
++ Date started: 12/02/98
++ Purpose: Integrates the rotational EOM
++ Called by: FGFDMExec
++
++ ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ 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., 59 Temple
++ Place - Suite 330, Boston, MA 02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++This class integrates the rotational EOM.
++
++HISTORY
++--------------------------------------------------------------------------------
++12/02/98 JSB Created
++
++********************************************************************************
++COMMENTS, REFERENCES, and NOTES
++********************************************************************************
++[1] Cooke, Zyda, Pratt, and McGhee, "NPSNET: Flight Simulation Dynamic Modeling
++ Using Quaternions", Presence, Vol. 1, No. 4, pp. 404-420 Naval Postgraduate
++ School, January 1994
++[2] D. M. Henderson, "Euler Angles, Quaternions, and Transformation Matrices",
++ JSC 12960, July 1977
++[3] Richard E. McFarland, "A Standard Kinematic Model for Flight Simulation at
++ NASA-Ames", NASA CR-2497, January 1975
++[4] Barnes W. McCormick, "Aerodynamics, Aeronautics, and Flight Mechanics",
++ Wiley & Sons, 1979 ISBN 0-471-03032-5
++[5] Bernard Etkin, "Dynamics of Flight, Stability and Control", Wiley & Sons,
++ 1982 ISBN 0-471-08936-2
++
++ The order of rotations used in this class corresponds to a 3-2-1 sequence,
++ or Y-P-R, or Z-Y-X, if you prefer.
++
++********************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#include "FGRotation.h"
++#include "FGAtmosphere.h"
++#include "FGState.h"
++#include "FGFDMExec.h"
++#include "FGFCS.h"
++#include "FGAircraft.h"
++#include "FGTranslation.h"
++#include "FGPosition.h"
++#include "FGAuxiliary.h"
++#include "FGOutput.h"
++
++/*******************************************************************************
++************************************ CODE **************************************
++*******************************************************************************/
++
++
++FGRotation::FGRotation(FGFDMExec* fdmex) : FGModel(fdmex)
++{
++ Name = "FGRotation";
++ Q0dot = Q1dot = Q2dot = Q3dot = 0.0;
++ Pdot = Qdot = Rdot = 0.0;
++}
++
++
++FGRotation::~FGRotation(void)
++{
++}
++
++
++bool FGRotation::Run(void)
++{
++ float L2, N1, iQtot, sum;
++
++ if (!FGModel::Run()) {
++ GetState();
++
++ lastPdot = Pdot;
++ lastQdot = Qdot;
++ lastRdot = Rdot;
++
++ L2 = L + Ixz*P*Q - (Izz-Iyy)*R*Q;
++ N1 = N - (Iyy-Ixx)*P*Q - Ixz*R*Q;
++
++ Pdot = (L2*Izz - N1*Ixz) / (Ixx*Izz - Ixz*Ixz);
++ Qdot = (M - (Ixx-Izz)*P*R - Ixz*(P*P - R*R))/Iyy;
++ Rdot = (N1*Ixx + L2*Ixz) / (Ixx*Izz - Ixz*Ixz);
++
++ P += dt*rate*(lastPdot + Pdot)/2.0;
++ Q += dt*rate*(lastQdot + Qdot)/2.0;
++ R += dt*rate*(lastRdot + Rdot)/2.0;
++
++ lastQ0dot = Q0dot;
++ lastQ1dot = Q1dot;
++ lastQ2dot = Q2dot;
++ lastQ3dot = Q3dot;
++
++ Q0dot = -0.5*(Q1*P + Q2*Q + Q3*R);
++ Q1dot = 0.5*(Q0*P + Q2*R - Q3*Q);
++ Q2dot = 0.5*(Q0*Q + Q3*P - Q1*R);
++ Q3dot = 0.5*(Q0*R + Q1*Q - Q2*P);
++
++ Q0 += 0.5*dt*rate*(lastQ0dot + Q0dot);
++ Q1 += 0.5*dt*rate*(lastQ1dot + Q1dot);
++ Q2 += 0.5*dt*rate*(lastQ2dot + Q2dot);
++ Q3 += 0.5*dt*rate*(lastQ3dot + Q3dot);
++
++ sum = Q0*Q0 + Q1*Q1 + Q2*Q2 + Q3*Q3;
++
++ iQtot = 1.0 / sqrt(sum);
++
++ Q0 *= iQtot;
++ Q1 *= iQtot;
++ Q2 *= iQtot;
++ Q3 *= iQtot;
++
++ if (T[3][3] == 0)
++ phi = 0.0;
++ else
++ phi = atan2(T[2][3], T[3][3]);
++
++ tht = asin(-T[1][3]);
++
++ if (T[1][1] == 0.0)
++ psi = 0.0;
++ else
++ psi = atan2(T[1][2], T[1][1]);
++
++ if (psi < 0.0) psi += 2*M_PI;
++
++ PutState();
++ } else {
++ }
++ return false;
++}
++
++
++void FGRotation::GetState(void)
++{
++ dt = State->Getdt();
++
++ L = Aircraft->GetL();
++ M = Aircraft->GetM();
++ N = Aircraft->GetN();
++
++ Ixx = Aircraft->GetIxx();
++ Iyy = Aircraft->GetIyy();
++ Izz = Aircraft->GetIzz();
++ Ixz = Aircraft->GetIxz();
++
++ for (int r=1;r<=3;r++)
++ for (int c=1;c<=3;c++)
++ T[r][c] = Position->GetT(r,c);
++}
++
++
++void FGRotation::PutState(void)
++{
++}
++
--- /dev/null
--- /dev/null
++/*******************************************************************************
++
++ Header: FGRotation.h
++ Author: Jon Berndt
++ Date started: 12/02/98
++
++ ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ 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., 59 Temple
++ Place - Suite 330, Boston, MA 02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++HISTORY
++--------------------------------------------------------------------------------
++12/02/98 JSB Created
++
++********************************************************************************
++COMMENTS, REFERENCES, and NOTES
++********************************************************************************
++[1] Cooke, Zyda, Pratt, and McGhee, "NPSNET: Flight Simulation Dynamic Modeling
++ Using Quaternions", Presence, Vol. 1, No. 4, pp. 404-420 Naval Postgraduate
++ School, January 1994
++[2] D. M. Henderson, "Euler Angles, Quaternions, and Transformation Matrices",
++ JSC 12960, July 1977
++[3] Richard E. McFarland, "A Standard Kinematic Model for Flight Simulation at
++ NASA-Ames", NASA CR-2497, January 1975
++[4] Barnes W. McCormick, "Aerodynamics, Aeronautics, and Flight Mechanics",
++ Wiley & Sons, 1979 ISBN 0-471-03032-5
++[5] Bernard Etkin, "Dynamics of Flight, Stability and Control", Wiley & Sons,
++ 1982 ISBN 0-471-08936-2
++
++ The order of rotations used in this class corresponds to a 3-2-1 sequence,
++ or Y-P-R, or Z-Y-X, if you prefer.
++
++********************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGROTATION_H
++#define FGROTATION_H
++
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#ifdef FGFS
++# include <Include/compiler.h>
++# ifdef FG_HAVE_STD_INCLUDES
++# include <cmath>
++# else
++# include <math.h>
++# endif
++#else
++# include <cmath>
++#endif
++
++#include "FGModel.h"
++
++/*******************************************************************************
++CLASS DECLARATION
++*******************************************************************************/
++
++class FGRotation : public FGModel
++{
++public:
++ FGRotation(FGFDMExec*);
++ ~FGRotation(void);
++
++ bool Run(void);
++
++ inline float GetP(void) {return P;}
++ inline float GetQ(void) {return Q;}
++ inline float GetR(void) {return R;}
++
++ inline float GetPdot(void) {return Pdot;}
++ inline float GetQdot(void) {return Qdot;}
++ inline float GetRdot(void) {return Rdot;}
++
++ inline float Getphi(void) {return phi;}
++ inline float Gettht(void) {return tht;}
++ inline float Getpsi(void) {return psi;}
++
++ inline float GetQ0(void) {return Q0;}
++ inline float GetQ1(void) {return Q1;}
++ inline float GetQ2(void) {return Q2;}
++ inline float GetQ3(void) {return Q3;}
++
++ inline void SetP(float tt) {P = tt;}
++ inline void SetQ(float tt) {Q = tt;}
++ inline void SetR(float tt) {R = tt;}
++
++ inline void SetPQR(float t1, float t2, float t3) {P=t1;
++ Q=t2;
++ R=t3;}
++
++ inline void Setphi(float tt) {phi = tt;}
++ inline void Settht(float tt) {tht = tt;}
++ inline void Setpsi(float tt) {psi = tt;}
++
++ inline void SetEuler(float t1, float t2, float t3) {phi=t1;
++ tht=t2;
++ psi=t3;}
++
++ inline void SetQ0123(float t1, float t2, float t3, float t4) {Q0=t1;
++ Q1=t2;
++ Q2=t3;
++ Q3=t4;}
++
++protected:
++
++private:
++ float P, Q, R;
++ float L, M, N;
++ float Ixx, Iyy, Izz, Ixz;
++ float Q0, Q1, Q2, Q3;
++ float phi, tht, psi;
++ float Pdot, Qdot, Rdot;
++ float Q0dot, Q1dot, Q2dot, Q3dot;
++ float lastPdot, lastQdot, lastRdot;
++ float lastQ0dot, lastQ1dot, lastQ2dot, lastQ3dot;
++ float dt;
++ float T[4][4];
++
++ void GetState(void);
++ void PutState(void);
++};
++
++/******************************************************************************/
++#endif
--- /dev/null
--- /dev/null
++/*******************************************************************************
++
++ Module: FGState.cpp
++ Author: Jon Berndt
++ Date started: 11/17/98
++ Called by: FGFDMExec and accessed by all models.
++
++ ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ 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., 59 Temple
++ Place - Suite 330, Boston, MA 02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++See header file.
++
++HISTORY
++--------------------------------------------------------------------------------
++11/17/98 JSB Created
++
++********************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#ifdef FGFS
++# include <Include/compiler.h>
++# ifdef FG_HAVE_STD_INCLUDES
++# include <cmath>
++# else
++# include <math.h>
++# endif
++#else
++# include <cmath>
++#endif
++
++#include "FGState.h"
++#include "FGFDMExec.h"
++#include "FGAtmosphere.h"
++#include "FGFCS.h"
++#include "FGAircraft.h"
++#include "FGTranslation.h"
++#include "FGRotation.h"
++#include "FGPosition.h"
++#include "FGAuxiliary.h"
++#include "FGOutput.h"
++
++/*******************************************************************************
++************************************ CODE **************************************
++*******************************************************************************/
++
++
++FGState::FGState(FGFDMExec* fdex)
++{
++ FDMExec = fdex;
++
++ Vt = 0.0;
++ latitude = longitude = 0.0;
++ adot = bdot = 0.0;
++ h = 0.0;
++ a = 1000.0;
++ qbar = 0.0;
++ sim_time = dt = 0.1;
++}
++
++
++FGState::~FGState(void)
++{
++}
++
++
++bool FGState::Reset(string path, string fname)
++{
++ string resetDef;
++ float U, V, W;
++ float phi, tht, psi;
++ float alpha, beta, gamma;
++ float Q0, Q1, Q2, Q3;
++ float T[4][4];
++
++ resetDef = path + "/" + FDMExec->GetAircraft()->GetAircraftName() + "/" + fname;
++
++ ifstream resetfile(resetDef.c_str());
++
++ if (resetfile) {
++ resetfile >> U;
++ resetfile >> V;
++ resetfile >> W;
++ resetfile >> latitude;
++ resetfile >> longitude;
++ resetfile >> phi;
++ resetfile >> tht;
++ resetfile >> psi;
++ resetfile >> h;
++ resetfile.close();
++
++// Change all angular measurements from degrees (as in config file) to radians
++
++ gamma = 0.0;
++ if (W != 0.0)
++ alpha = U*U > 0.0 ? atan2(W, U) : 0.0;
++ else
++ alpha = 0.0;
++ if (V != 0.0)
++ beta = U*U+W*W > 0.0 ? atan2(V, (fabs(U)/U)*sqrt(U*U + W*W)) : 0.0;
++ else
++ beta = 0.0;
++
++ latitude *= M_PI / 180.0;
++ longitude *= M_PI / 180.0;
++ phi *= M_PI / 180.0;
++ tht *= M_PI / 180.0;
++ psi *= M_PI / 180.0;
++
++ FDMExec->GetTranslation()->SetUVW(U, V, W);
++ FDMExec->GetRotation()->SetEuler(phi, tht, psi);
++ FDMExec->GetTranslation()->SetABG(alpha, beta, gamma);
++
++ Vt = sqrt(U*U + V*V + W*W);
++ qbar = sqrt(U*U + V*V + W*W);
++
++ Q0 = sin(psi*0.5)*sin(tht*0.5)*sin(phi*0.5) + cos(psi*0.5)*cos(tht*0.5)*cos(phi*0.5);
++ Q1 = -sin(psi*0.5)*sin(tht*0.5)*cos(phi*0.5) + cos(psi*0.5)*cos(tht*0.5)*sin(phi*0.5);
++ Q2 = sin(psi*0.5)*cos(tht*0.5)*sin(phi*0.5) + cos(psi*0.5)*sin(tht*0.5)*cos(phi*0.5);
++ Q3 = sin(psi*0.5)*cos(tht*0.5)*cos(phi*0.5) - cos(psi*0.5)*sin(tht*0.5)*sin(phi*0.5);
++
++ FDMExec->GetRotation()->SetQ0123(Q0, Q1, Q2, Q3);
++
++ T[1][1] = Q0*Q0 + Q1*Q1 - Q2*Q2 - Q3*Q3;
++ T[1][2] = 2*(Q1*Q2 + Q0*Q3);
++ T[1][3] = 2*(Q1*Q3 - Q0*Q2);
++ T[2][1] = 2*(Q1*Q2 - Q0*Q3);
++ T[2][2] = Q0*Q0 - Q1*Q1 + Q2*Q2 - Q3*Q3;
++ T[2][3] = 2*(Q2*Q3 + Q0*Q1);
++ T[3][1] = 2*(Q1*Q3 + Q0*Q2);
++ T[3][2] = 2*(Q2*Q3 - Q0*Q1);
++ T[3][3] = Q0*Q0 - Q1*Q1 - Q2*Q2 + Q3*Q3;
++
++ FDMExec->GetPosition()->SetT(T[1][1], T[1][2], T[1][3],
++ T[2][1], T[2][2], T[2][3],
++ T[3][1], T[3][2], T[3][3]);
++
++ return true;
++ } else {
++ cerr << "Unable to load reset file " << fname << endl;
++ return false;
++ }
++}
++
++
++bool FGState::StoreData(string fname)
++{
++ ofstream datafile(fname.c_str());
++
++ if (datafile) {
++ datafile << FDMExec->GetTranslation()->GetU();
++ datafile << FDMExec->GetTranslation()->GetV();
++ datafile << FDMExec->GetTranslation()->GetW();
++ datafile << latitude;
++ datafile << longitude;
++ datafile << FDMExec->GetRotation()->Getphi();
++ datafile << FDMExec->GetRotation()->Gettht();
++ datafile << FDMExec->GetRotation()->Getpsi();
++ datafile << h;
++ datafile.close();
++ return true;
++ } else {
++ cerr << "Could not open dump file " << fname << endl;
++ return false;
++ }
++}
++
++
++bool FGState::DumpData(string fname)
++{
++ ofstream datafile(fname.c_str());
++
++ if (datafile) {
++ datafile << "U: " << FDMExec->GetTranslation()->GetU() << endl;
++ datafile << "V: " << FDMExec->GetTranslation()->GetV() << endl;
++ datafile << "W: " << FDMExec->GetTranslation()->GetW() << endl;
++ datafile << "P: " << FDMExec->GetRotation()->GetP() << endl;
++ datafile << "Q: " << FDMExec->GetRotation()->GetQ() << endl;
++ datafile << "R: " << FDMExec->GetRotation()->GetR() << endl;
++ datafile << "L: " << FDMExec->GetAircraft()->GetL() << endl;
++ datafile << "M: " << FDMExec->GetAircraft()->GetM() << endl;
++ datafile << "N: " << FDMExec->GetAircraft()->GetN() << endl;
++ datafile << "latitude: " << latitude << endl;
++ datafile << "longitude: " << longitude << endl;
++ datafile << "alpha: " << FDMExec->GetTranslation()->Getalpha() << endl;
++ datafile << "beta: " << FDMExec->GetTranslation()->Getbeta() << endl;
++ datafile << "gamma: " << FDMExec->GetTranslation()->Getgamma() << endl;
++ datafile << "phi: " << FDMExec->GetRotation()->Getphi() << endl;
++ datafile << "tht: " << FDMExec->GetRotation()->Gettht() << endl;
++ datafile << "psi: " << FDMExec->GetRotation()->Getpsi() << endl;
++ datafile << "Pdot: " << FDMExec->GetRotation()->GetPdot() << endl;
++ datafile << "Qdot: " << FDMExec->GetRotation()->GetQdot() << endl;
++ datafile << "Rdot: " << FDMExec->GetRotation()->GetRdot() << endl;
++ datafile << "h: " << h << endl;
++ datafile << "a: " << a << endl;
++ datafile << "rho: " << FDMExec->GetAtmosphere()->Getrho() << endl;
++ datafile << "qbar: " << qbar << endl;
++ datafile << "sim_time: " << sim_time << endl;
++ datafile << "dt: " << dt << endl;
++ datafile << "m: " << FDMExec->GetAircraft()->GetMass() << endl;
++ datafile.close();
++ return true;
++ } else {
++ return false;
++ }
++}
++
++
++bool FGState::DisplayData(void)
++{
++ cout << "U: " << FDMExec->GetTranslation()->GetU() << endl;
++ cout << "V: " << FDMExec->GetTranslation()->GetV() << endl;
++ cout << "W: " << FDMExec->GetTranslation()->GetW() << endl;
++ cout << "P: " << FDMExec->GetRotation()->GetP() << endl;
++ cout << "Q: " << FDMExec->GetRotation()->GetQ() << endl;
++ cout << "R: " << FDMExec->GetRotation()->GetR() << endl;
++ cout << "L: " << FDMExec->GetAircraft()->GetL() << endl;
++ cout << "M: " << FDMExec->GetAircraft()->GetM() << endl;
++ cout << "N: " << FDMExec->GetAircraft()->GetN() << endl;
++ cout << "Vt: " << Vt << endl;
++ cout << "latitude: " << latitude << endl;
++ cout << "longitude: " << longitude << endl;
++ cout << "alpha: " << FDMExec->GetTranslation()->Getalpha() << endl;
++ cout << "beta: " << FDMExec->GetTranslation()->Getbeta() << endl;
++ cout << "gamma: " << FDMExec->GetTranslation()->Getgamma() << endl;
++ cout << "phi: " << FDMExec->GetRotation()->Getphi() << endl;
++ cout << "tht: " << FDMExec->GetRotation()->Gettht() << endl;
++ cout << "psi: " << FDMExec->GetRotation()->Getpsi() << endl;
++ cout << "Pdot: " << FDMExec->GetRotation()->GetPdot() << endl;
++ cout << "Qdot: " << FDMExec->GetRotation()->GetQdot() << endl;
++ cout << "Rdot: " << FDMExec->GetRotation()->GetRdot() << endl;
++ cout << "h: " << h << endl;
++ cout << "a: " << a << endl;
++ cout << "rho: " << FDMExec->GetAtmosphere()->Getrho() << endl;
++ cout << "qbar: " << qbar << endl;
++ cout << "sim_time: " << sim_time << endl;
++ cout << "dt: " << dt << endl;
++ cout << "m: " << FDMExec->GetAircraft()->GetMass() << endl;
++
++ return true;
++}
--- /dev/null
--- /dev/null
++/*******************************************************************************
++
++ Header: FGState.h
++ Author: Jon S. Berndt
++ Date started: 11/17/98
++
++ ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ 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., 59 Temple
++ Place - Suite 330, Boston, MA 02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++
++Based on Flightgear code, which is based on LaRCSim. This class wraps all
++global state variables (such as velocity, position, orientation, etc.).
++
++HISTORY
++--------------------------------------------------------------------------------
++11/17/98 JSB Created
++
++********************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGSTATE_H
++#define FGSTATE_H
++
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#ifdef FGFS
++# include <Include/compiler.h>
++# include STL_STRING
++# ifdef FG_HAVE_STD_INCLUDES
++# include <fstream>
++# else
++# include <fstream.h>
++# endif
++ FG_USING_STD(string);
++#else
++# include <string>
++# include <fstream>
++#endif
++
++#include "FGDefs.h"
++
++/*******************************************************************************
++DEFINES
++*******************************************************************************/
++
++/*******************************************************************************
++CLASS DECLARATION
++*******************************************************************************/
++
++class FGFDMExec;
++class FGState
++{
++public:
++ FGState(FGFDMExec*);
++ ~FGState(void);
++
++ bool Reset(string, string);
++ bool StoreData(string);
++ bool DumpData(string);
++ bool DisplayData(void);
++
++ inline float GetVt(void) {return Vt;}
++
++ inline float Getlatitude(void) {return latitude;}
++ inline float Getlongitude(void) {return longitude;}
++ inline float GetGeodeticLat(void) {return GeodeticLat;}
++
++ inline float Getadot(void) {return adot;}
++ inline float Getbdot(void) {return bdot;}
++
++ inline float Geth(void) {return h;}
++ inline float Geta(void) {return a;}
++ inline float GetMach(void) {return Mach;}
++
++ inline float Getsim_time(void) {return sim_time;}
++ inline float Getdt(void) {return dt;}
++
++ inline float Getqbar(void) {return qbar;}
++
++ inline void SetVt(float tt) {Vt = tt;}
++
++ inline void Setlatitude(float tt) {latitude = tt;}
++ inline void Setlongitude(float tt) {longitude = tt;}
++ inline void SetGeodeticLat(float tt) {GeodeticLat = tt;}
++
++ inline void Setadot(float tt) {adot = tt;}
++ inline void Setbdot(float tt) {bdot = tt;}
++
++ inline void Setqbar(float tt) {qbar = tt;}
++
++ inline void Seth(float tt) {h = tt;}
++ inline void Seta(float tt) {a = tt;}
++ inline void SetMach(float tt) {Mach = tt;}
++
++ inline float Setsim_time(float tt) {sim_time = tt; return sim_time;}
++ inline void Setdt(float tt) {dt = tt;}
++
++ inline float IncrTime(void) {sim_time+=dt;return sim_time;}
++
++private:
++
++ float Vt; // Total velocity
++ float latitude, longitude; // position
++ float GeodeticLat; // Geodetic Latitude
++ float adot, bdot; // alpha dot and beta dot
++ float h, a; // altitude above sea level, speed of sound
++ float qbar; // dynamic pressure
++ float sim_time, dt;
++ float Mach; // Mach number
++
++ FGFDMExec* FDMExec;
++
++protected:
++
++};
++
++/******************************************************************************/
++#endif
--- /dev/null
--- /dev/null
++/*******************************************************************************
++
++ Module: FGTank.cpp
++ Author: Jon Berndt
++ Date started: 01/21/99
++ Called by: FGAircraft
++
++ ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ 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., 59 Temple
++ Place - Suite 330, Boston, MA 02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++See header file.
++
++HISTORY
++--------------------------------------------------------------------------------
++01/21/99 JSB Created
++
++********************************************************************************
++INCLUDES
++*******************************************************************************/
++#include "FGTank.h"
++
++/*******************************************************************************
++************************************ CODE **************************************
++*******************************************************************************/
++
++
++FGTank::FGTank(ifstream& acfile)
++{
++ string type;
++
++ acfile >> type; // Type = 0: fuel, 1: oxidizer
++ if (type == "FUEL") Type = ttFUEL;
++ else if (type == "OXIDIZER") Type = ttOXIDIZER;
++ else Type = ttUNKNOWN;
++ acfile >> X; // inches
++ acfile >> Y; // "
++ acfile >> Z; // "
++ acfile >> Radius; // "
++ acfile >> Capacity; // pounds (amount it can hold)
++ acfile >> Contents; // pounds (amount it is holding)
++ Selected = true;
++ PctFull = 100.0*Contents/Capacity; // percent full; 0 to 100.0
++}
++
++
++FGTank::~FGTank(void)
++{
++}
++
++
++float FGTank::Reduce(float used)
++{
++ float shortage;
++
++ if (used < Contents) {
++ Contents -= used;
++ PctFull = 100.0*Contents/Capacity;
++ return Contents;
++ } else {
++ shortage = Contents - used;
++ Contents = 0.0;
++ PctFull = 0.0;
++ Selected = false;
++ return shortage;
++ }
++}
++
--- /dev/null
--- /dev/null
++/*******************************************************************************
++
++ Header: FGTank.h
++ Author: Jon S. Berndt
++ Date started: 01/21/99
++
++ ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ 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., 59 Temple
++ Place - Suite 330, Boston, MA 02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++
++Based on Flightgear code, which is based on LaRCSim. This class simulates
++a generic Tank.
++
++HISTORY
++--------------------------------------------------------------------------------
++01/21/99 JSB Created
++
++********************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGTank_H
++#define FGTank_H
++
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++#ifdef FGFS
++# include <Include/compiler.h>
++# include STL_STRING
++# ifdef FG_HAVE_STD_INCLUDES
++# include <fstream>
++# else
++# include <fstream.h>
++# endif
++ FG_USING_STD(string);
++#else
++# include <string>
++# include <fstream>
++#endif
++
++/*******************************************************************************
++DEFINES
++*******************************************************************************/
++
++/*******************************************************************************
++CLASS DECLARATION
++*******************************************************************************/
++
++class FGTank
++{
++public:
++ FGTank(ifstream&);
++ ~FGTank(void);
++
++ float Reduce(float);
++ int GetType(void) {return Type;}
++ bool GetSelected(void) {return Selected;}
++ float GetPctFull(void) {return PctFull;}
++ float GetContents(void) {return Contents;}
++
++ enum TankType {ttUNKNOWN, ttFUEL, ttOXIDIZER};
++
++private:
++ TankType Type;
++ float X, Y, Z;
++ float Capacity;
++ float Radius;
++ float PctFull;
++ float Contents;
++ bool Selected;
++
++protected:
++};
++
++/******************************************************************************/
++#endif
--- /dev/null
--- /dev/null
++/*******************************************************************************
++
++ Module: FGTranslation.cpp
++ Author: Jon Berndt
++ Date started: 12/02/98
++ Purpose: Integrates the translational EOM
++ Called by: FDMExec
++
++ ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ 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., 59 Temple
++ Place - Suite 330, Boston, MA 02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++This class integrates the translational EOM.
++
++HISTORY
++--------------------------------------------------------------------------------
++12/02/98 JSB Created
++
++********************************************************************************
++COMMENTS, REFERENCES, and NOTES
++********************************************************************************
++[1] Cooke, Zyda, Pratt, and McGhee, "NPSNET: Flight Simulation Dynamic Modeling
++ Using Quaternions", Presence, Vol. 1, No. 4, pp. 404-420 Naval Postgraduate
++ School, January 1994
++[2] D. M. Henderson, "Euler Angles, Quaternions, and Transformation Matrices",
++ JSC 12960, July 1977
++[3] Richard E. McFarland, "A Standard Kinematic Model for Flight Simulation at
++ NASA-Ames", NASA CR-2497, January 1975
++[4] Barnes W. McCormick, "Aerodynamics, Aeronautics, and Flight Mechanics",
++ Wiley & Sons, 1979 ISBN 0-471-03032-5
++[5] Bernard Etkin, "Dynamics of Flight, Stability and Control", Wiley & Sons,
++ 1982 ISBN 0-471-08936-2
++
++ The order of rotations used in this class corresponds to a 3-2-1 sequence,
++ or Y-P-R, or Z-Y-X, if you prefer.
++
++********************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#include "FGTranslation.h"
++#include "FGRotation.h"
++#include "FGAtmosphere.h"
++#include "FGState.h"
++#include "FGFDMExec.h"
++#include "FGFCS.h"
++#include "FGAircraft.h"
++#include "FGPosition.h"
++#include "FGAuxiliary.h"
++#include "FGOutput.h"
++
++/*******************************************************************************
++************************************ CODE **************************************
++*******************************************************************************/
++
++
++FGTranslation::FGTranslation(FGFDMExec* fdmex) : FGModel(fdmex)
++{
++ Name = "FGTranslation";
++ Udot = Vdot = Wdot = 0.0;
++}
++
++
++FGTranslation::~FGTranslation(void)
++{
++}
++
++
++bool FGTranslation::Run(void)
++{
++ if (!FGModel::Run()) {
++
++ GetState();
++
++ lastUdot = Udot;
++ lastVdot = Vdot;
++ lastWdot = Wdot;
++
++ Udot = V*R - W*Q + Fx/Mass;
++ Vdot = W*P - U*R + Fy/Mass;
++ Wdot = U*Q - V*P + Fz/Mass;
++
++ U += 0.5*dt*rate*(lastUdot + Udot);
++ V += 0.5*dt*rate*(lastVdot + Vdot);
++ W += 0.5*dt*rate*(lastWdot + Wdot);
++
++ Vt = U*U+V*V+W*W > 0.0 ? sqrt(U*U + V*V + W*W) : 0.0;
++
++ if (W != 0.0)
++ alpha = U*U > 0.0 ? atan2(W, U) : 0.0;
++ if (V != 0.0)
++ beta = U*U+W*W > 0.0 ? atan2(V, (fabs(U)/U)*sqrt(U*U + W*W)) : 0.0;
++
++ qbar = 0.5*rho*Vt*Vt;
++
++ PutState();
++ } else {
++ }
++ return false;
++}
++
++
++void FGTranslation::GetState(void)
++{
++ dt = State->Getdt();
++
++ P = Rotation->GetP();
++ Q = Rotation->GetQ();
++ R = Rotation->GetR();
++
++ Fx = Aircraft->GetFx();
++ Fy = Aircraft->GetFy();
++ Fz = Aircraft->GetFz();
++
++ Mass = Aircraft->GetMass();
++ rho = Atmosphere->Getrho();
++
++ phi = Rotation->Getphi();
++ tht = Rotation->Gettht();
++ psi = Rotation->Getpsi();
++}
++
++
++void FGTranslation::PutState(void)
++{
++ State->SetVt(Vt);
++ State->Setqbar(qbar);
++}
++
--- /dev/null
--- /dev/null
++/*******************************************************************************
++
++ Header: FGTranslation.h
++ Author: Jon Berndt
++ Date started: 12/02/98
++
++ ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ 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., 59 Temple
++ Place - Suite 330, Boston, MA 02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++HISTORY
++--------------------------------------------------------------------------------
++12/02/98 JSB Created
++
++********************************************************************************
++COMMENTS, REFERENCES, and NOTES
++********************************************************************************
++[1] Cooke, Zyda, Pratt, and McGhee, "NPSNET: Flight Simulation Dynamic Modeling
++ Using Quaternions", Presence, Vol. 1, No. 4, pp. 404-420 Naval Postgraduate
++ School, January 1994
++[2] D. M. Henderson, "Euler Angles, Quaternions, and Transformation Matrices",
++ JSC 12960, July 1977
++[3] Richard E. McFarland, "A Standard Kinematic Model for Flight Simulation at
++ NASA-Ames", NASA CR-2497, January 1975
++[4] Barnes W. McCormick, "Aerodynamics, Aeronautics, and Flight Mechanics",
++ Wiley & Sons, 1979 ISBN 0-471-03032-5
++[5] Bernard Etkin, "Dynamics of Flight, Stability and Control", Wiley & Sons,
++ 1982 ISBN 0-471-08936-2
++
++ The order of rotations used in this class corresponds to a 3-2-1 sequence,
++ or Y-P-R, or Z-Y-X, if you prefer.
++
++********************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGTRANSLATION_H
++#define FGTRANSLATION_H
++
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#ifdef FGFS
++# include <Include/compiler.h>
++# ifdef FG_HAVE_STD_INCLUDES
++# include <cmath>
++# else
++# include <math.h>
++# endif
++#else
++# include <cmath>
++#endif
++
++#include "FGModel.h"
++
++/*******************************************************************************
++CLASS DECLARATION
++*******************************************************************************/
++
++class FGTranslation : public FGModel
++{
++public:
++ FGTranslation(FGFDMExec*);
++ ~FGTranslation(void);
++
++ inline float GetU(void) {return U;}
++ inline float GetV(void) {return V;}
++ inline float GetW(void) {return W;}
++
++ inline float GetUdot(void) {return Udot;}
++ inline float GetVdot(void) {return Vdot;}
++ inline float GetWdot(void) {return Wdot;}
++
++ inline float Getalpha(void) {return alpha;}
++ inline float Getbeta (void) {return beta; }
++ inline float Getgamma(void) {return gamma;}
++
++ inline void SetU(float tt) {U = tt;}
++ inline void SetV(float tt) {V = tt;}
++ inline void SetW(float tt) {W = tt;}
++
++ inline void SetUVW(float t1, float t2, float t3) {U=t1; V=t2; W=t3;}
++
++ inline void Setalpha(float tt) {alpha = tt;}
++ inline void Setbeta (float tt) {beta = tt;}
++ inline void Setgamma(float tt) {gamma = tt;}
++
++ inline void SetABG(float t1, float t2, float t3) {alpha=t1; beta=t2; gamma=t3;}
++
++ bool Run(void);
++
++protected:
++
++private:
++ float U, V, W; // Body frame velocities owned by FGTranslation
++ float P, Q, R;
++ float Vt, qbar;
++ float Udot, Vdot, Wdot;
++ float lastUdot, lastVdot, lastWdot;
++ float phi, tht, psi;
++ float Fx, Fy, Fz;
++ float Mass, dt;
++ float alpha, beta, gamma;
++ float rho;
++
++ void GetState(void);
++ void PutState(void);
++};
++
++/******************************************************************************/
++#endif
--- /dev/null
--- /dev/null
++/*******************************************************************************
++
++ Module: FGUtility.cpp
++ Author: Jon Berndt
++ Date started: 01/09/99
++ Purpose: Contains utility classes for the FG FDM
++ Called by: FGPosition, et. al.
++
++ ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ 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., 59 Temple
++ Place - Suite 330, Boston, MA 02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++FUNCTIONAL DESCRIPTION
++--------------------------------------------------------------------------------
++This class is a container for all utility classes used by the flight dynamics
++model.
++
++HISTORY
++--------------------------------------------------------------------------------
++01/09/99 JSB Created
++
++********************************************************************************
++DEFINES
++*******************************************************************************/
++
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++
++#ifdef FGFS
++# include <Include/compiler.h>
++# ifdef FG_HAVE_STD_INCLUDES
++# include <cmath>
++# else
++# include <math.h>
++# endif
++#else
++# include <cmath>
++#endif
++
++#include "FGUtility.h"
++#include "FGState.h"
++#include "FGFDMExec.h"
++
++/*******************************************************************************
++************************************ CODE **************************************
++*******************************************************************************/
++
++FGUtility::FGUtility()
++{
++ // Move constant stuff to here (if any) so it won't take CPU time
++ // in the methods below.
++ SeaLevelR = EARTHRAD * ECCENT;
++}
++
++
++FGUtility::~FGUtility()
++{
++}
++
++
++float FGUtility::ToGeodetic()
++{
++ float GeodeticLat, Latitude, Radius, Altitude;
++ float tanLat, xAlpha, muAlpha, sinmuAlpha, denom, rhoAlpha, dMu;
++ float lPoint, lambdaSL, sinlambdaSL, dLambda, rAlpha;
++
++ Latitude = State->Getlatitude();
++ Radius = State->Geth() + EARTHRAD;
++
++ if (( M_PI_2 - Latitude < ONESECOND) ||
++ ( M_PI_2 + Latitude < ONESECOND)) { // Near a pole
++ GeodeticLat = Latitude;
++ Altitude = Radius - SeaLevelR;
++ } else {
++ tanLat = tan(Latitude);
++ xAlpha = ECCENT*EARTHRAD /
++ sqrt(tanLat*tanLat + ECCENTSQRD);
++ muAlpha = atan2(sqrt(EARTHRADSQRD - xAlpha*xAlpha), ECCENT*xAlpha);
++
++ if (Latitude < 0.0) muAlpha = -muAlpha;
++
++ sinmuAlpha = sin(muAlpha);
++ dLambda = muAlpha - Latitude;
++ rAlpha = xAlpha / cos(Latitude);
++ lPoint = Radius - rAlpha;
++ Altitude = lPoint*cos(dLambda);
++ denom = sqrt(1-EPS*EPS*sinmuAlpha*sinmuAlpha);
++ rhoAlpha = EARTHRAD*(1.0 - EPS) / (denom*denom*denom);
++ dMu = atan2(lPoint*sin(dLambda),rhoAlpha + Altitude);
++ State->SetGeodeticLat(muAlpha - dMu);
++ lambdaSL = atan(ECCENTSQRD*tan(GeodeticLat));
++ sinlambdaSL = sin(lambdaSL);
++ SeaLevelR = sqrt(EARTHRADSQRD / (1 + INVECCENTSQRDM1* sinlambdaSL*sinlambdaSL));
++ }
++ return 0.0;
++}
++
++
++float FGUtility:: FromGeodetic()
++{
++ float lambdaSL, sinlambdaSL, coslambdaSL, sinMu, cosMu, py, px;
++ float Altitude, SeaLevelR;
++
++ lambdaSL = atan(ECCENTSQRD*tan(State->GetGeodeticLat()));
++ sinlambdaSL = sin(lambdaSL);
++ coslambdaSL = cos(lambdaSL);
++ sinMu = sin(State->GetGeodeticLat());
++ cosMu = cos(State->GetGeodeticLat());
++ SeaLevelR = sqrt(EARTHRADSQRD /
++ (1 + INVECCENTSQRDM1*sinlambdaSL*sinlambdaSL));
++ px = SeaLevelR*coslambdaSL + Altitude*cosMu;
++ py = SeaLevelR*sinlambdaSL + Altitude*sinMu;
++ State->Setlatitude(atan2(py,px));
++ return 0.0;
++}
++
--- /dev/null
--- /dev/null
++/*******************************************************************************
++
++ Header: FGUtility.h
++ Author: Jon Berndt
++ Date started: 01/09/99
++
++ ------------- Copyright (C) 1999 Jon S. Berndt (jsb@hal-pc.org) -------------
++
++ 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., 59 Temple
++ Place - Suite 330, Boston, MA 02111-1307, USA.
++
++ Further information about the GNU General Public License can also be found on
++ the world wide web at http://www.gnu.org.
++
++HISTORY
++--------------------------------------------------------------------------------
++01/09/99 JSB Created
++
++********************************************************************************
++SENTRY
++*******************************************************************************/
++
++#ifndef FGUTILITY_H
++#define FGUTILITY_H
++
++/*******************************************************************************
++INCLUDES
++*******************************************************************************/
++
++/*******************************************************************************
++DEFINES
++*******************************************************************************/
++
++/*******************************************************************************
++CLASS DECLARATION
++*******************************************************************************/
++
++class FGFDMExec;
++class FGState;
++
++class FGUtility
++{
++public:
++ FGUtility(void);
++ ~FGUtility(void);
++
++ float ToGeodetic(void);
++ float FromGeodetic(void);
++
++protected:
++
++private:
++ float SeaLevelR;
++ FGState* State;
++ FGFDMExec* FDMExec;
++};
++
++/******************************************************************************/
++#endif
--- /dev/null
--- /dev/null
++noinst_LIBRARIES = libJSBsim.a
++
++libJSBsim_a_SOURCES = FGAircraft.cpp FGAircraft.h \
++ FGAtmosphere.cpp FGAtmosphere.h \
++ FGAuxiliary.cpp FGAuxiliary.h \
++ FGCoefficient.cpp FGCoefficient.h \
++ FGDefs.h \
++ FGFCS.cpp FGFCS.h \
++ FGFDMExec.cpp FGFDMExec.h \
++ FGModel.cpp FGModel.h \
++ FGOutput.cpp FGOutput.h \
++ FGPosition.cpp FGPosition.h \
++ FGRotation.cpp FGRotation.h \
++ FGState.cpp FGState.h \
++ FGTranslation.cpp FGTranslation.h \
++ FGUtility.cpp FGUtility.h \
++ FGEngine.cpp FGEngine.h \
++ FGTank.cpp FGTank.h
++
++INCLUDES += -I$(top_builddir)
++
++DEFS += -DFGFS
--- /dev/null
--- /dev/null
++if ENABLE_LINUX_JOYSTICK
++DEFS += -DENABLE_LINUX_JOYSTICK
++else
++DEFS += -DENABLE_GLUT_JOYSTICK
++endif
++
++EXTRA_DIST = js.cxx
++
++noinst_LIBRARIES = libJoystick.a
++
++libJoystick_a_SOURCES = joystick.cxx joystick.hxx js.hxx
++
++INCLUDES += -I$(top_builddir) \
++ -I$(top_builddir)/Lib \
++ -I$(top_builddir)/Lib/plib/include \
++ -I$(top_builddir)/Simulator
--- /dev/null
--- /dev/null
++// joystick.cxx -- joystick support
++//
++// Written by Curtis Olson, started October 1998.
++//
++// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++
++#include <Aircraft/aircraft.hxx>
++#include <Debug/logstream.hxx>
++
++#if defined( ENABLE_LINUX_JOYSTICK )
++# include <js.h>
++#elif defined( ENABLE_GLUT_JOYSTICK )
++# include <GL/glut.h>
++# include <XGL/xgl.h>
++#endif
++
++
++#include "joystick.hxx"
++
++
++#if defined( ENABLE_LINUX_JOYSTICK )
++
++// joystick classes
++static jsJoystick *js0;
++static jsJoystick *js1;
++
++// these will hold the values of the axes
++static float *js_ax0, *js_ax1;
++
++#elif defined( ENABLE_GLUT_JOYSTICK )
++
++// Do we want these user settable ??
++static float joy_scale = 1./1000;
++
++// play with following to get your desired sensitivity
++static int x_dead_zone = 50;
++static int y_dead_zone = 2*x_dead_zone;
++
++// Joystick support using glut -- William Riley -- riley@technologist.com
++
++// Joystick fixed values for calibration and scaling
++static float joy_x_max = joy_scale;
++static float joy_y_max = joy_scale;
++
++static int joy_z_min = 1000, /* joy_z_ctr=0, */ joy_z_max = -1000;
++static int joy_z_dead_min = 100, joy_z_dead_max = -100;
++
++#else
++# error port me: no joystick support
++#endif
++
++
++
++#if defined( ENABLE_GLUT_JOYSTICK )
++
++// Function called by glutJoystickFunc(), adjusts read values and
++// passes them to the necessary aircraft control functions
++void joystick(unsigned int buttonMask, int js_x, int js_y, int js_z)
++{
++ float joy_x, joy_y, joy_z;
++ // adjust the values to fgfs's scale and allow a 'dead zone' to
++ // reduce jitter code adapted from joystick.c by Michele
++ // F. America - nomimarketing@mail.telepac.pt
++
++ if( js_x > -x_dead_zone && js_x < x_dead_zone) {
++ joy_x = 0.0;
++ } else {
++ joy_x = js_x * joy_scale;
++ }
++
++ if( js_y > -y_dead_zone && js_y < y_dead_zone) {
++ joy_y = 0.0;
++ } else {
++ joy_y = js_y * joy_scale;
++ }
++
++ if( js_z >= joy_z_dead_min && js_z <= joy_z_dead_max ) {
++ joy_z = 0.0;
++ }
++ joy_z = (float)js_z / (float)(joy_z_max - joy_z_min);
++ joy_z = (((joy_z*2.0)+1.0)/2);
++
++ // Pass the values to the control routines
++ controls.set_elevator( -joy_y );
++ controls.set_aileron( joy_x );
++ controls.set_throttle( FGControls::ALL_ENGINES, joy_z );
++}
++
++#endif // ENABLE_GLUT_JOYSTICK
++
++
++// Initialize the joystick(s)
++int fgJoystickInit( void ) {
++
++ FG_LOG( FG_INPUT, FG_INFO, "Initializing joystick" );
++
++#if defined( ENABLE_LINUX_JOYSTICK )
++
++ js0 = new jsJoystick ( 0 );
++ js1 = new jsJoystick ( 1 );
++
++ if ( js0->notWorking () ) {
++ // not working
++ } else {
++ // allocate storage for axes values
++ js_ax0 = new float [ js0->getNumAxes() ];
++
++ // configure
++ js0->setDeadBand( 0, 0.1 );
++ js0->setDeadBand( 1, 0.1 );
++
++ FG_LOG ( FG_INPUT, FG_INFO,
++ " Joystick 0 detected with " << js0->getNumAxes()
++ << " axes" );
++ }
++
++ if ( js1->notWorking () ) {
++ // not working
++ } else {
++ // allocate storage for axes values
++ js_ax1 = new float [ js1->getNumAxes() ];
++
++ // configure
++ js1->setDeadBand( 0, 0.1 );
++ js1->setDeadBand( 1, 0.1 );
++
++ FG_LOG ( FG_INPUT, FG_INFO,
++ " Joystick 1 detected with " << js1->getNumAxes()
++ << " axes" );
++ }
++
++ if ( js0->notWorking() && js1->notWorking() ) {
++ FG_LOG ( FG_INPUT, FG_INFO, " No joysticks detected" );
++ return 0;
++ }
++
++#elif defined( ENABLE_GLUT_JOYSTICK )
++
++ glutJoystickFunc(joystick, 100);
++
++#else
++# error port me: no joystick support
++#endif
++
++ return 1;
++}
++
++
++#if defined( ENABLE_LINUX_JOYSTICK )
++
++// update the control parameters based on joystick intput
++int fgJoystickRead( void ) {
++ int b;
++
++ if ( ! js0->notWorking() ) {
++ js0->read( &b, js_ax0 ) ;
++ controls.set_aileron( js_ax0[0] );
++ controls.set_elevator( -js_ax0[1] );
++ }
++
++ if ( ! js1->notWorking() ) {
++ js1->read( &b, js_ax1 ) ;
++ controls.set_rudder( js_ax1[0] );
++ controls.set_throttle( FGControls::ALL_ENGINES, -js_ax1[1] * 1.05 );
++ }
++
++ return 1;
++}
++
++#endif // ENABLE_LINUX_JOYSTICK
++
++
++// $Log$
++// Revision 1.8 1999/04/03 04:20:33 curt
++// Integration of Steve's plib conglomeration.
++//
++// Revision 1.7 1999/01/19 17:52:30 curt
++// Some joystick tweaks by Norman Vine.
++//
++// Revision 1.6 1998/12/05 16:13:16 curt
++// Renamed class fgCONTROLS to class FGControls.
++//
++// Revision 1.5 1998/11/06 21:18:04 curt
++// Converted to new logstream debugging facility. This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.4 1998/10/27 02:14:32 curt
++// Changes to support GLUT joystick routines as fall back.
++//
++// Revision 1.3 1998/10/25 14:08:44 curt
++// Turned "struct fgCONTROLS" into a class, with inlined accessor functions.
++//
++// Revision 1.2 1998/10/25 10:56:25 curt
++// Completely rewritten to use Steve Baker's joystick interface class.
++//
++// Revision 1.1 1998/10/24 22:28:16 curt
++// Renamed joystick.[ch] to joystick.[ch]xx
++// Added js.hxx which is Steve's joystick interface class.
++//
++// Revision 1.7 1998/04/25 22:06:29 curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.6 1998/04/18 04:14:05 curt
++// Moved fg_debug.c to it's own library.
++//
++// Revision 1.5 1998/02/12 21:59:44 curt
++// Incorporated code changes contributed by Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.4 1998/02/03 23:20:20 curt
++// Lots of little tweaks to fix various consistency problems discovered by
++// Solaris' CC. Fixed a bug in fg_debug.c with how the fgPrintf() wrapper
++// passed arguments along to the real printf(). Also incorporated HUD changes
++// by Michele America.
++//
++// Revision 1.3 1998/01/27 00:47:54 curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.2 1997/12/30 20:47:40 curt
++// Integrated new event manager with subsystem initializations.
++//
++// Revision 1.1 1997/08/29 18:06:54 curt
++// Initial revision.
++//
++
--- /dev/null
--- /dev/null
++// joystick.cxx -- joystick support
++//
++// Written by Curtis Olson, started October 1998.
++//
++// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#ifndef _JOYSTICK_HXX
++#define _JOYSTICK_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++
++// Initialize the joystick(s)
++int fgJoystickInit( void );
++
++#if defined( ENABLE_LINUX_JOYSTICK )
++ // update the control parameters based on joystick intput
++ int fgJoystickRead( void );
++#endif // ENABLE_LINUX_JOYSTICK
++
++
++#endif // _JOYSTICK_HXX
++
++
++// $Log$
++// Revision 1.3 1998/10/27 02:14:33 curt
++// Changes to support GLUT joystick routines as fall back.
++//
++// Revision 1.2 1998/10/25 10:56:27 curt
++// Completely rewritten to use Steve Baker's joystick interface class.
++//
++// Revision 1.1 1998/10/24 22:28:18 curt
++// Renamed joystick.[ch] to joystick.[ch]xx
++// Added js.hxx which is Steve's joystick interface class.
++//
++// Revision 1.3 1998/04/22 13:26:21 curt
++// C++ - ifing the code a bit.
++//
++// Revision 1.2 1998/01/22 02:59:36 curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.1 1997/08/29 18:06:55 curt
++// Initial revision.
++//
++
--- /dev/null
--- /dev/null
++if ENABLE_CHEROKEE
++AIRCRAFT_MODEL = cherokee_aero.c cherokee_engine.c cherokee_gear.c cherokee_init.c navion_init.h
++else
++AIRCRAFT_MODEL = navion_aero.c navion_engine.c navion_gear.c navion_init.c navion_init.h
++endif
++
++noinst_LIBRARIES = libLaRCsim.a
++
++libLaRCsim_a_SOURCES = \
++ atmos_62.c atmos_62.h \
++ default_model_routines.c default_model_routines.h \
++ ls_accel.c ls_accel.h \
++ ls_aux.c ls_aux.h \
++ ls_cockpit.h ls_constants.h ls_generic.h \
++ ls_geodesy.c ls_geodesy.h \
++ ls_gravity.c ls_gravity.h \
++ ls_init.c ls_init.h \
++ ls_matrix.c ls_matrix.h \
++ ls_model.c ls_model.h \
++ ls_sim_control.h \
++ ls_step.c ls_step.h \
++ ls_sym.h ls_types.h \
++ $(AIRCRAFT_MODEL) \
++ ls_interface.c ls_interface.h
++
++INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib -I$(top_builddir)/Simulator
--- /dev/null
--- /dev/null
++/***************************************************************************
++
++ TITLE: atmos_62
++
++----------------------------------------------------------------------------
++
++ FUNCTION: 1962 atmosphere table interpolation routine
++
++----------------------------------------------------------------------------
++
++ MODULE STATUS: developmental
++
++----------------------------------------------------------------------------
++
++ GENEALOGY: Created 920827 by Bruce Jackson as part of the C-castle
++ development effort.
++
++----------------------------------------------------------------------------
++
++ DESIGNED BY: B. Jackson
++
++ CODED BY: B. Jackson
++
++ MAINTAINED BY: B. Jackson
++
++----------------------------------------------------------------------------
++
++ MODIFICATION HISTORY:
++
++ DATE PURPOSE BY
++ 931220 Added ambient pressure and temperature as outputs. EBJ
++ 940111 Changed includes from "ls_eom.h" to "ls_types.h" and
++ "ls_constants.h"; changed DATA to SCALAR types. EBJ
++
++----------------------------------------------------------------------------
++
++ REFERENCES:
++
++ [ 1] Hornbeck, Robert W.: "Numerical Methods", Prentice-Hall,
++ 1975. ISBN 0-13-626614-2
++
++----------------------------------------------------------------------------
++
++ CALLED BY:
++
++----------------------------------------------------------------------------
++
++ CALLS TO:
++
++----------------------------------------------------------------------------
++
++ INPUTS:
++
++----------------------------------------------------------------------------
++
++ OUTPUTS:
++
++--------------------------------------------------------------------------*/
++
++#include "ls_types.h"
++#include "ls_constants.h"
++
++#include "atmos_62.h"
++
++#include <math.h>
++
++#define alt_0 d_a_table[index ][0]
++#define alt_1 d_a_table[index+1][0]
++#define den_0 d_a_table[index ][1]
++#define den_1 d_a_table[index+1][1]
++#define sps_0 d_a_table[index ][2]
++#define sps_1 d_a_table[index+1][2]
++#define gden_0 d_a_table[index ][3]
++#define gden_1 d_a_table[index+1][3]
++#define gsps_0 d_a_table[index ][4]
++#define gsps_1 d_a_table[index+1][4]
++
++#define MAX_ALT_INDEX 121
++#define DELT_ALT 2000.
++#define HLEV 36089.
++#define TAMB0 518.7
++#define PAMB0 2113.8
++#define MAX_ALTITUDE 240000.
++
++void ls_atmos( SCALAR altitude, SCALAR * sigma, SCALAR * v_sound,
++ SCALAR * t_amb, SCALAR * p_amb )
++{
++
++ int index;
++ SCALAR daltp, daltn, daltp3, daltn3, density;
++ SCALAR t_amb_r, p_amb_r;
++ SCALAR tmp;
++
++ static SCALAR d_a_table[MAX_ALT_INDEX][5] =
++ {
++ { 0., 2.37701E-03, 1.11642E+03, 0.00000E+00, 0.00000E+00 },
++ { 2000., 2.24098E-03, 1.10872E+03, 1.92857E-12, -1.75815E-08 },
++ { 4000., 2.11099E-03, 1.10097E+03, 1.34570E-12, -1.21740E-08 },
++ { 6000., 1.98684E-03, 1.09315E+03, 1.44862E-12, -1.47225E-08 },
++ { 8000., 1.86836E-03, 1.08529E+03, 1.36481E-12, -1.44359E-08 },
++ { 10000., 1.75537E-03, 1.07736E+03, 1.32716E-12, -1.45340E-08 },
++ { 12000., 1.64768E-03, 1.06938E+03, 1.27657E-12, -1.44280E-08 },
++ { 14000., 1.54511E-03, 1.06133E+03, 1.24656E-12, -1.62540E-08 },
++ { 16000., 1.44751E-03, 1.05323E+03, 1.19220E-12, -1.50560E-08 },
++ { 18000., 1.35469E-03, 1.04506E+03, 1.15463E-12, -1.65220E-08 },
++ { 20000., 1.26649E-03, 1.03683E+03, 1.11926E-12, -1.63562E-08 },
++ { 22000., 1.18276E-03, 1.02853E+03, 1.07333E-12, -1.70533E-08 },
++ { 24000., 1.10333E-03, 1.02016E+03, 1.03743E-12, -1.59305E-08 },
++ { 26000., 1.02805E-03, 1.01173E+03, 1.00195E-12, -2.27248E-08 },
++ { 28000., 9.56760E-04, 1.00322E+03, 9.39764E-13, 3.29851E-10 },
++ { 30000., 8.89320E-04, 9.94641E+02, 1.01399E-12, -8.80946E-08 },
++ { 32000., 8.25570E-04, 9.85988E+02, 5.39268E-13, 2.41048E-07 },
++ { 34000., 7.65380E-04, 9.77258E+02, 2.16894E-12, -9.91599E-07 },
++ { 36000., 7.08600E-04, 9.68448E+02, -4.10001E-12, 3.60535E-06 },
++ { 38000., 6.44190E-04, 9.68053E+02, 2.78612E-12, -8.07290E-07 },
++ { 40000., 5.85146E-04, 9.68053E+02, 1.00455E-12, 2.16313E-07 },
++ { 42000., 5.31517E-04, 9.68053E+02, 1.31819E-12, -5.79609E-08 },
++ { 44000., 4.82801E-04, 9.68053E+02, 1.09217E-12, 1.55309E-08 },
++ { 46000., 4.38554E-04, 9.68053E+02, 1.01661E-12, -4.16262E-09 },
++ { 48000., 3.98359E-04, 9.68053E+02, 9.19375E-13, 1.11961E-09 },
++ { 50000., 3.61850E-04, 9.68053E+02, 8.34886E-13, -3.15801E-10 },
++ { 52000., 3.28686E-04, 9.68053E+02, 7.58579E-13, 1.43600E-10 },
++ { 54000., 2.98561E-04, 9.68053E+02, 6.89297E-13, -2.58597E-10 },
++ { 56000., 2.71197E-04, 9.68053E+02, 6.25735E-13, 8.90788E-10 },
++ { 58000., 2.46341E-04, 9.68053E+02, 5.69765E-13, -3.30456E-09 },
++ { 60000., 2.23765E-04, 9.68053E+02, 5.15206E-13, 1.23274E-08 },
++ { 62000., 2.03256E-04, 9.68053E+02, 4.69912E-13, -4.60052E-08 },
++ { 64000., 1.84627E-04, 9.68053E+02, 4.25146E-13, 1.71693E-07 },
++ { 66000., 1.67616E-04, 9.68314E+02, 2.56502E-13, -2.49268E-07 },
++ { 68000., 1.51855E-04, 9.68676E+02, 4.23844E-13, 9.76878E-07 },
++ { 70000., 1.37615E-04, 9.71034E+02, 3.29621E-13, -6.64245E-07 },
++ { 72000., 1.24744E-04, 9.72390E+02, 3.11170E-13, 1.77102E-07 },
++ { 74000., 1.13107E-04, 9.73745E+02, 2.76697E-13, -4.56627E-08 },
++ { 76000., 1.02584E-04, 9.75099E+02, 2.53043E-13, 4.04902E-09 },
++ { 78000., 9.30660E-05, 9.76450E+02, 2.18633E-13, 2.49667E-08 },
++ { 80000., 8.44530E-05, 9.77799E+02, 2.29927E-13, -1.06916E-07 },
++ { 82000., 7.67140E-05, 9.78950E+02, 1.72660E-13, 1.05696E-07 },
++ { 84000., 6.97010E-05, 9.80290E+02, 1.68432E-13, -3.23682E-08 },
++ { 86000., 6.33490E-05, 9.81620E+02, 1.45113E-13, 8.77690E-09 },
++ { 88000., 5.75880E-05, 9.82950E+02, 1.37617E-13, -2.73938E-09 },
++ { 90000., 5.23700E-05, 9.84280E+02, 1.18918E-13, 2.18061E-09 },
++ { 92000., 4.76350E-05, 9.85610E+02, 1.11210E-13, -5.98306E-09 },
++ { 94000., 4.33410E-05, 9.86930E+02, 9.77408E-14, 6.75162E-09 },
++ { 96000., 3.94430E-05, 9.88260E+02, 9.18264E-14, -6.02343E-09 },
++ { 98000., 3.59080E-05, 9.89580E+02, 7.94534E-14, 2.34210E-09 },
++ { 100000., 3.26960E-05, 9.90900E+02, 7.48600E-14, -3.34498E-09 },
++ { 102000., 2.97810E-05, 9.92210E+02, 6.66067E-14, -3.96219E-09 },
++ { 104000., 2.71320E-05, 9.93530E+02, 5.77131E-14, 3.41937E-08 },
++ { 106000., 2.46980E-05, 9.95410E+02, 2.50410E-14, 7.07187E-07 },
++ { 108000., 2.24140E-05, 9.99070E+02, 6.71229E-14, -1.92943E-07 },
++ { 110000., 2.03570E-05, 1.00272E+03, 4.69675E-14, 4.95832E-08 },
++ { 112000., 1.85010E-05, 1.00636E+03, 4.65069E-14, -2.03903E-08 },
++ { 114000., 1.68270E-05, 1.00998E+03, 4.00047E-14, 1.97789E-09 },
++ { 116000., 1.53150E-05, 1.01359E+03, 3.64744E-14, -2.52130E-09 },
++ { 118000., 1.39480E-05, 1.01719E+03, 3.15976E-14, -6.89271E-09 },
++ { 120000., 1.27100E-05, 1.02077E+03, 3.06351E-14, 9.21465E-11 },
++ { 122000., 1.15920E-05, 1.02434E+03, 2.58618E-14, -8.47587E-09 },
++ { 124000., 1.05790E-05, 1.02789E+03, 2.34176E-14, 3.81135E-09 },
++ { 126000., 9.66010E-06, 1.03144E+03, 2.16178E-14, -6.76951E-09 },
++ { 128000., 8.82710E-06, 1.03497E+03, 1.89611E-14, -6.73330E-09 },
++ { 130000., 8.07070E-06, 1.03848E+03, 1.74377E-14, 3.70270E-09 },
++ { 132000., 7.38380E-06, 1.04199E+03, 1.55382E-14, -8.07752E-09 },
++ { 134000., 6.75940E-06, 1.04548E+03, 1.41595E-14, -1.39263E-09 },
++ { 136000., 6.19160E-06, 1.04896E+03, 1.27239E-14, -1.35196E-09 },
++ { 138000., 5.67490E-06, 1.05243E+03, 1.15951E-14, -8.19953E-09 },
++ { 140000., 5.20450E-06, 1.05588E+03, 1.03459E-14, 4.15010E-09 },
++ { 142000., 4.77570E-06, 1.05933E+03, 9.42149E-15, -8.40086E-09 },
++ { 144000., 4.38470E-06, 1.06276E+03, 8.66820E-15, -5.46671E-10 },
++ { 146000., 4.02820E-06, 1.06618E+03, 7.65573E-15, -4.41246E-09 },
++ { 148000., 3.70260E-06, 1.06959E+03, 7.05890E-15, 3.19650E-09 },
++ { 150000., 3.40520E-06, 1.07299E+03, 6.40867E-15, -2.33736E-08 },
++ { 152000., 3.13330E-06, 1.07637E+03, 5.55641E-15, 6.02977E-08 },
++ { 154000., 2.88480E-06, 1.07975E+03, 6.46568E-15, -2.17817E-07 },
++ { 156000., 2.66270E-06, 1.08202E+03, 8.18087E-15, -8.54029E-07 },
++ { 158000., 2.46830E-06, 1.08202E+03, 2.36086E-15, 2.28931E-07 },
++ { 160000., 2.28810E-06, 1.08202E+03, 3.67571E-15, -6.16972E-08 },
++ { 162000., 2.12120E-06, 1.08202E+03, 2.88632E-15, 1.78573E-08 },
++ { 164000., 1.96640E-06, 1.08202E+03, 2.92903E-15, -9.73206E-09 },
++ { 166000., 1.82300E-06, 1.08202E+03, 2.49757E-15, 2.10709E-08 },
++ { 168000., 1.69000E-06, 1.08202E+03, 2.68069E-15, -7.45517E-08 },
++ { 170000., 1.56680E-06, 1.08202E+03, 1.47966E-15, 2.77136E-07 },
++ { 172000., 1.45250E-06, 1.08202E+03, 4.75068E-15, -1.03399E-06 },
++ { 174000., 1.35240E-06, 1.07963E+03, 8.17622E-16, 2.73830E-07 },
++ { 176000., 1.25880E-06, 1.07723E+03, 1.72883E-15, -7.63301E-08 },
++ { 178000., 1.17130E-06, 1.07482E+03, 1.41704E-15, 1.64901E-08 },
++ { 180000., 1.08960E-06, 1.07240E+03, 1.30299E-15, -4.63038E-09 },
++ { 182000., 1.01320E-06, 1.06998E+03, 1.32100E-15, 2.03140E-09 },
++ { 184000., 9.41950E-07, 1.06756E+03, 1.13799E-15, -3.49522E-09 },
++ { 186000., 8.75370E-07, 1.06513E+03, 1.13202E-15, -3.05052E-09 },
++ { 188000., 8.13260E-07, 1.06269E+03, 1.03892E-15, 6.97283E-10 },
++ { 190000., 7.55320E-07, 1.06025E+03, 9.67290E-16, 2.61383E-10 },
++ { 192000., 7.01260E-07, 1.05781E+03, 9.11920E-16, -1.74281E-09 },
++ { 194000., 6.50850E-07, 1.05536E+03, 8.60032E-16, -8.29013E-09 },
++ { 196000., 6.03870E-07, 1.05290E+03, 7.92951E-16, 1.99033E-08 },
++ { 198000., 5.60110E-07, 1.05044E+03, 7.98164E-16, -7.13232E-08 },
++ { 200000., 5.19320E-07, 1.04798E+03, 4.69394E-16, 2.65389E-07 },
++ { 202000., 4.81340E-07, 1.04550E+03, 1.53926E-15, -1.02023E-06 },
++ { 204000., 4.47960E-07, 1.04063E+03, 2.73571E-16, 2.30547E-07 },
++ { 206000., 4.16690E-07, 1.03565E+03, 5.31456E-16, -6.69551E-08 },
++ { 208000., 3.87320E-07, 1.03065E+03, 4.50605E-16, 7.27308E-09 },
++ { 210000., 3.59790E-07, 1.02562E+03, 4.26126E-16, -7.13720E-09 },
++ { 212000., 3.33970E-07, 1.02057E+03, 4.09893E-16, -8.72426E-09 },
++ { 214000., 3.09780E-07, 1.01549E+03, 3.79301E-16, -2.96576E-09 },
++ { 216000., 2.87120E-07, 1.01039E+03, 3.67902E-16, -9.41272E-09 },
++ { 218000., 2.65920E-07, 1.00526E+03, 3.39092E-16, -4.38337E-09 },
++ { 220000., 2.46090E-07, 1.00011E+03, 3.30732E-16, -3.05378E-09 },
++ { 222000., 2.27570E-07, 9.94940E+02, 3.02981E-16, -1.34015E-08 },
++ { 224000., 2.10270E-07, 9.89730E+02, 2.87343E-16, -3.34027E-09 },
++ { 226000., 1.94120E-07, 9.84500E+02, 2.72646E-16, -3.23743E-09 },
++ { 228000., 1.79060E-07, 9.79250E+02, 2.57074E-16, -1.37100E-08 },
++ { 230000., 1.65030E-07, 9.73960E+02, 2.44060E-16, -1.92258E-09 },
++ { 232000., 1.51970E-07, 9.68650E+02, 2.21687E-16, -8.59969E-09 },
++ { 234000., 1.39810E-07, 9.63310E+02, 2.19191E-16, -8.67865E-09 },
++ { 236000., 1.28510E-07, 9.57940E+02, 1.91549E-16, -1.68569E-09 },
++ { 238000., 1.18020E-07, 9.52550E+02, 2.29613E-16, -1.45786E-08 },
++ { 240000., 1.08270E-07, 9.47120E+02, 0.00000E+00, 0.00000E+00 }
++ };
++
++ /* for purposes of doing the table lookup, force the incoming
++ altitude to be >= 0 */
++
++ // printf("altitude = %.2f\n", altitude);
++
++ if ( altitude < 0.0 ) {
++ altitude = 0.0;
++ }
++
++ // printf("altitude = %.2f\n", altitude);
++
++ index = (int)( altitude / 2000 );
++ if (index > (MAX_ALT_INDEX-2))
++ {
++ index = MAX_ALT_INDEX-2; /* limit maximum altitude */
++ altitude = MAX_ALTITUDE;
++ }
++ if (index < 0) index = 0;
++ daltp = alt_1 - altitude;
++ daltp3 = daltp*daltp*daltp;
++ daltn = altitude - alt_0;
++ daltn3 = daltn*daltn*daltn;
++
++ density = (gden_0/6)*((daltp3/2000) - 2000*daltp)
++ + (gden_1/6)*((daltn3/2000) - 2000*daltn)
++ + den_0*daltp/2000 + den_1*daltn/2000;
++
++ *v_sound = (gsps_0/6)*((daltp3/2000) - 2000*daltp)
++ + (gsps_1/6)*((daltn3/2000) - 2000*daltn)
++ + sps_0*daltp/2000 + sps_1*daltn/2000;
++
++ *sigma = density/SEA_LEVEL_DENSITY;
++
++ if (altitude < HLEV) /* BUG - these curve fits are only good to about 75000 ft */
++ {
++ t_amb_r = 1. - 6.875e-6*altitude;
++ // printf("index = %d t_amb_r = %.2f\n", index, t_amb_r);
++ // p_amb_r = pow( t_amb_r, 5.256 );
++ tmp = 5.256; // avoid a segfault (?)
++ p_amb_r = pow( t_amb_r, tmp );
++ // printf("p_amb_r = %.2f\n", p_amb_r);
++ }
++ else
++ {
++ t_amb_r = 0.751895;
++ p_amb_r = 0.2234*exp( -4.806e-5 * (altitude - HLEV));
++ }
++
++ *p_amb = p_amb_r * PAMB0;
++ *t_amb = t_amb_r * TAMB0;
++
++/* end of atmos_62 */
++}
++/**************************************************************************/
--- /dev/null
--- /dev/null
++/* a quick atmos_62.h */
++
++
++#ifndef _ATMOS_62_H
++#define _ATMOS_62_H
++
++
++void ls_atmos( SCALAR altitude, SCALAR * sigma, SCALAR * v_sound,
++ SCALAR * t_amb, SCALAR * p_amb );
++
++
++#endif /* _ATMOS_62_H */
--- /dev/null
--- /dev/null
++/***************************************************************************
++
++ TITLE: engine.c
++
++----------------------------------------------------------------------------
++
++ FUNCTION: dummy engine routine
++
++----------------------------------------------------------------------------
++
++ MODULE STATUS: incomplete
++
++----------------------------------------------------------------------------
++
++ GENEALOGY: Created 15 OCT 92 as dummy routine for checkout. EBJ
++
++----------------------------------------------------------------------------
++
++ DESIGNED BY: designer
++
++ CODED BY: programmer
++
++ MAINTAINED BY: maintainer
++
++----------------------------------------------------------------------------
++
++ MODIFICATION HISTORY:
++
++ DATE PURPOSE BY
++
++ CURRENT RCS HEADER INFO:
++
++$Header$
++
++$Log$
++Revision 1.3 1998/08/06 12:46:37 curt
++Header change.
++
++Revision 1.2 1998/01/19 18:40:23 curt
++Tons of little changes to clean up the code and to remove fatal errors
++when building with the c++ compiler.
++
++Revision 1.1 1997/05/29 00:09:53 curt
++Initial Flight Gear revision.
++
++ * Revision 1.3 1994/01/11 19:10:45 bjax
++ * Removed include files.
++ *
++ * Revision 1.2 1993/03/14 12:16:10 bjax
++ * simple correction: added ';' to end of default routines. EBJ
++ *
++ * Revision 1.1 93/03/10 06:43:46 bjax
++ * Initial revision
++ *
++ * Revision 1.1 92/12/30 13:21:46 bjax
++ * Initial revision
++ *
++
++----------------------------------------------------------------------------
++
++ REFERENCES:
++
++----------------------------------------------------------------------------
++
++ CALLED BY: ls_model();
++
++----------------------------------------------------------------------------
++
++ CALLS TO: none
++
++----------------------------------------------------------------------------
++
++ INPUTS:
++
++----------------------------------------------------------------------------
++
++ OUTPUTS:
++
++--------------------------------------------------------------------------*/
++
++
++#include "ls_types.h"
++#include "default_model_routines.h"
++
++void inertias( SCALAR dt, int Initialize ) {}
++void subsystems( SCALAR dt, int Initialize ) {}
++/* void engine() {} */
++/* void gear() {} */
++
++
++
++
--- /dev/null
--- /dev/null
++/* a quick default_model_routines.h */
++
++
++#ifndef _DEFAULT_MODEL_ROUTINES_H
++#define _DEFAULT_MODEL_ROUTINES_H
++
++
++#include "ls_types.h"
++
++
++void inertias( SCALAR dt, int Initialize );
++void subsystems( SCALAR dt, int Initialize );
++void aero( SCALAR dt, int Initialize );
++void engine( SCALAR dt, int Initialize );
++void gear( SCALAR dt, int Initialize );
++
++
++#endif /* _DEFAULT_MODEL_ROUTINES_H */
--- /dev/null
--- /dev/null
++/***************************************************************************
++
++ TITLE: ls_Accel
++
++ ----------------------------------------------------------------------------
++
++ FUNCTION: Sums forces and moments and calculates accelerations
++
++ ----------------------------------------------------------------------------
++
++ MODULE STATUS: developmental
++
++ ----------------------------------------------------------------------------
++
++ GENEALOGY: Written 920731 by Bruce Jackson. Based upon equations
++ given in reference [1] and a Matrix-X/System Build block
++ diagram model of equations of motion coded by David Raney
++ at NASA-Langley in June of 1992.
++
++ ----------------------------------------------------------------------------
++
++ DESIGNED BY: Bruce Jackson
++
++ CODED BY: Bruce Jackson
++
++ MAINTAINED BY:
++
++ ----------------------------------------------------------------------------
++
++ MODIFICATION HISTORY:
++
++ DATE PURPOSE
++
++ 931007 Moved calculations of auxiliary accelerations here from ls_aux.c BY
++ and corrected minus sign in front of A_Y_Pilot
++ contribution from Q_body*P_body*D_X_pilot term.
++ 940111 Changed DATA to SCALAR; updated header files
++
++$Header$
++$Log$
++Revision 1.4 1998/08/24 20:09:26 curt
++Code optimization tweaks from Norman Vine.
++
++Revision 1.3 1998/08/06 12:46:38 curt
++Header change.
++
++Revision 1.2 1998/01/19 18:40:24 curt
++Tons of little changes to clean up the code and to remove fatal errors
++when building with the c++ compiler.
++
++Revision 1.1 1997/05/29 00:09:53 curt
++Initial Flight Gear revision.
++
++ * Revision 1.5 1994/01/11 18:42:16 bjax
++ * Oops! Changed data types from DATA to SCALAR for precision control.
++ *
++ * Revision 1.4 1994/01/11 18:36:58 bjax
++ * Removed ls_eom.h include directive; replaced with ls_types, ls_constants,
++ * and ls_generic.h includes.
++ *
++ * Revision 1.3 1993/10/07 18:45:24 bjax
++ * Added local defn of d[xyz]_pilot_from_cg to support previous mod. EBJ
++ *
++ * Revision 1.2 1993/10/07 18:41:31 bjax
++ * Moved calculations of auxiliary accelerations here from ls_aux, and
++ * corrected sign on Q_body*P_body*d_x_pilot term of A_Y_pilot calc. EBJ
++ *
++ * Revision 1.1 1992/12/30 13:17:02 bjax
++ * Initial revision
++ *
++
++ ----------------------------------------------------------------------------
++
++ REFERENCES:
++
++ [ 1] McFarland, Richard E.: "A Standard Kinematic Model
++ for Flight Simulation at NASA-Ames", NASA CR-2497,
++ January 1975
++
++ ----------------------------------------------------------------------------
++
++ CALLED BY:
++
++ ----------------------------------------------------------------------------
++
++ CALLS TO:
++
++ ----------------------------------------------------------------------------
++
++ INPUTS: Aero, engine, gear forces & moments
++
++ ----------------------------------------------------------------------------
++
++ OUTPUTS: State derivatives
++
++ -------------------------------------------------------------------------*/
++#include "ls_types.h"
++#include "ls_generic.h"
++#include "ls_constants.h"
++#include "ls_accel.h"
++#include <math.h>
++
++void ls_accel( void ) {
++
++ SCALAR inv_Mass, inv_Radius;
++ SCALAR ixz2, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10;
++ SCALAR dx_pilot_from_cg, dy_pilot_from_cg, dz_pilot_from_cg;
++ SCALAR tan_Lat_geocentric;
++
++
++ /* Sum forces and moments at reference point */
++
++
++ F_X = F_X_aero + F_X_engine + F_X_gear;
++ F_Y = F_Y_aero + F_Y_engine + F_Y_gear;
++ F_Z = F_Z_aero + F_Z_engine + F_Z_gear;
++
++ M_l_rp = M_l_aero + M_l_engine + M_l_gear;
++ M_m_rp = M_m_aero + M_m_engine + M_m_gear;
++ M_n_rp = M_n_aero + M_n_engine + M_n_gear;
++
++ /* Transfer moments to center of gravity */
++
++ M_l_cg = M_l_rp + F_Y*Dz_cg - F_Z*Dy_cg;
++ M_m_cg = M_m_rp + F_Z*Dx_cg - F_X*Dz_cg;
++ M_n_cg = M_n_rp + F_X*Dy_cg - F_Y*Dx_cg;
++
++ /* Transform from body to local frame */
++
++ F_north = T_local_to_body_11*F_X + T_local_to_body_21*F_Y
++ + T_local_to_body_31*F_Z;
++ F_east = T_local_to_body_12*F_X + T_local_to_body_22*F_Y
++ + T_local_to_body_32*F_Z;
++ F_down = T_local_to_body_13*F_X + T_local_to_body_23*F_Y
++ + T_local_to_body_33*F_Z;
++
++ /* Calculate linear accelerations */
++
++ tan_Lat_geocentric = tan(Lat_geocentric);
++ inv_Mass = 1/Mass;
++ inv_Radius = 1/Radius_to_vehicle;
++ V_dot_north = inv_Mass*F_north +
++ inv_Radius*(V_north*V_down - V_east*V_east*tan_Lat_geocentric);
++ V_dot_east = inv_Mass*F_east +
++ inv_Radius*(V_east*V_down + V_north*V_east*tan_Lat_geocentric);
++ V_dot_down = inv_Mass*(F_down) + Gravity -
++ inv_Radius*(V_north*V_north + V_east*V_east);
++
++ /* Invert the symmetric inertia matrix */
++
++ ixz2 = I_xz*I_xz;
++ c0 = 1/(I_xx*I_zz - ixz2);
++ c1 = c0*((I_yy-I_zz)*I_zz - ixz2);
++ c4 = c0*I_xz;
++ /* c2 = c0*I_xz*(I_xx - I_yy + I_zz); */
++ c2 = c4*(I_xx - I_yy + I_zz);
++ c3 = c0*I_zz;
++ c7 = 1/I_yy;
++ c5 = c7*(I_zz - I_xx);
++ c6 = c7*I_xz;
++ c8 = c0*((I_xx - I_yy)*I_xx + ixz2);
++ /* c9 = c0*I_xz*(I_yy - I_zz - I_xx); */
++ c9 = c4*(I_yy - I_zz - I_xx);
++ c10 = c0*I_xx;
++
++ /* Calculate the rotational body axis accelerations */
++
++ P_dot_body = (c1*R_body + c2*P_body)*Q_body + c3*M_l_cg + c4*M_n_cg;
++ Q_dot_body = c5*R_body*P_body + c6*(R_body*R_body - P_body*P_body) + c7*M_m_cg;
++ R_dot_body = (c8*P_body + c9*R_body)*Q_body + c4*M_l_cg + c10*M_n_cg;
++
++ /* Calculate body axis accelerations (move to ls_accel?) */
++
++ inv_Mass = 1/Mass;
++
++ A_X_cg = F_X * inv_Mass;
++ A_Y_cg = F_Y * inv_Mass;
++ A_Z_cg = F_Z * inv_Mass;
++
++ dx_pilot_from_cg = Dx_pilot - Dx_cg;
++ dy_pilot_from_cg = Dy_pilot - Dy_cg;
++ dz_pilot_from_cg = Dz_pilot - Dz_cg;
++
++ A_X_pilot = A_X_cg + (-R_body*R_body - Q_body*Q_body)*dx_pilot_from_cg
++ + ( P_body*Q_body - R_dot_body )*dy_pilot_from_cg
++ + ( P_body*R_body + Q_dot_body )*dz_pilot_from_cg;
++ A_Y_pilot = A_Y_cg + ( P_body*Q_body + R_dot_body )*dx_pilot_from_cg
++ + (-P_body*P_body - R_body*R_body)*dy_pilot_from_cg
++ + ( Q_body*R_body - P_dot_body )*dz_pilot_from_cg;
++ A_Z_pilot = A_Z_cg + ( P_body*R_body - Q_dot_body )*dx_pilot_from_cg
++ + ( Q_body*R_body + P_dot_body )*dy_pilot_from_cg
++ + (-Q_body*Q_body - P_body*P_body)*dz_pilot_from_cg;
++
++ N_X_cg = INVG*A_X_cg;
++ N_Y_cg = INVG*A_Y_cg;
++ N_Z_cg = INVG*A_Z_cg;
++
++ N_X_pilot = INVG*A_X_pilot;
++ N_Y_pilot = INVG*A_Y_pilot;
++ N_Z_pilot = INVG*A_Z_pilot;
++
++
++ U_dot_body = T_local_to_body_11*V_dot_north + T_local_to_body_12*V_dot_east
++ + T_local_to_body_13*V_dot_down - Q_total*W_body + R_total*V_body;
++ V_dot_body = T_local_to_body_21*V_dot_north + T_local_to_body_22*V_dot_east
++ + T_local_to_body_23*V_dot_down - R_total*U_body + P_total*W_body;
++ W_dot_body = T_local_to_body_31*V_dot_north + T_local_to_body_32*V_dot_east
++ + T_local_to_body_33*V_dot_down - P_total*V_body + Q_total*U_body;
++ /* End of ls_accel */
++
++}
++/**************************************************************************/
++
++
++
++
--- /dev/null
--- /dev/null
++/* a quick ls_accel.h */
++
++
++#ifndef _LS_ACCEL_H
++#define _LS_ACCEL_H
++
++
++void ls_accel( void );
++
++
++#endif /* _LS_ACCEL_H */
--- /dev/null
--- /dev/null
++/***************************************************************************
++
++ TITLE: ls_aux
++
++----------------------------------------------------------------------------
++
++ FUNCTION: Atmospheric and auxilary relationships for LaRCSim EOM
++
++----------------------------------------------------------------------------
++
++ MODULE STATUS: developmental
++
++----------------------------------------------------------------------------
++
++ GENEALOGY: Created 9208026 as part of C-castle simulation project.
++
++----------------------------------------------------------------------------
++
++ DESIGNED BY: B. Jackson
++
++ CODED BY: B. Jackson
++
++ MAINTAINED BY: B. Jackson
++
++----------------------------------------------------------------------------
++
++ MODIFICATION HISTORY:
++
++ DATE PURPOSE
++
++ 931006 Moved calculations of auxiliary accelerations from here
++ to ls_accel.c and corrected minus sign in front of A_Y_Pilot
++ contribution from Q_body*P_body*D_X_pilot term. EBJ
++ 931014 Changed calculation of Alpha from atan to atan2 so sign is correct.
++ EBJ
++ 931220 Added calculations for static and total temperatures & pressures,
++ as well as dynamic and impact pressures and calibrated airspeed.
++ EBJ
++ 940111 Changed #included header files from old "ls_eom.h" to newer
++ "ls_types.h", "ls_constants.h" and "ls_generic.h". EBJ
++
++ 950207 Changed use of "abs" to "fabs" in calculation of signU. EBJ
++
++ 950228 Fixed bug in calculation of beta_dot. EBJ
++
++ CURRENT RCS HEADER INFO:
++
++$Header$
++$Log$
++Revision 1.4 1998/08/24 20:09:26 curt
++Code optimization tweaks from Norman Vine.
++
++Revision 1.3 1998/08/06 12:46:38 curt
++Header change.
++
++Revision 1.2 1998/01/19 18:40:24 curt
++Tons of little changes to clean up the code and to remove fatal errors
++when building with the c++ compiler.
++
++Revision 1.1 1997/05/29 00:09:54 curt
++Initial Flight Gear revision.
++
++ * Revision 1.12 1995/02/28 17:57:16 bjax
++ * Corrected calculation of beta_dot. EBJ
++ *
++ * Revision 1.11 1995/02/07 21:09:47 bjax
++ * Corrected calculation of "signU"; was using divide by
++ * abs(), which returns an integer; now using fabs(), which
++ * returns a double. EBJ
++ *
++ * Revision 1.10 1994/05/10 20:09:42 bjax
++ * Fixed a major problem with dx_pilot_from_cg, etc. not being calculated locally.
++ *
++ * Revision 1.9 1994/01/11 18:44:33 bjax
++ * Changed header files to use ls_types, ls_constants, and ls_generic.
++ *
++ * Revision 1.8 1993/12/21 14:36:33 bjax
++ * Added calcs of pressures, temps and calibrated airspeeds.
++ *
++ * Revision 1.7 1993/10/14 11:25:38 bjax
++ * Changed calculation of Alpha to use 'atan2' instead of 'atan' so alphas
++ * larger than +/- 90 degrees are calculated correctly. EBJ
++ *
++ * Revision 1.6 1993/10/07 18:45:56 bjax
++ * A little cleanup; no significant changes. EBJ
++ *
++ * Revision 1.5 1993/10/07 18:42:22 bjax
++ * Moved calculations of auxiliary accelerations here from ls_aux, and
++ * corrected sign on Q_body*P_body*d_x_pilot term of A_Y_pilot calc. EBJ
++ *
++ * Revision 1.4 1993/07/16 18:28:58 bjax
++ * Changed call from atmos_62 to ls_atmos. EBJ
++ *
++ * Revision 1.3 1993/06/02 15:02:42 bjax
++ * Changed call to geodesy calcs from ls_geodesy to ls_geoc_to_geod.
++ *
++ * Revision 1.1 92/12/30 13:17:39 bjax
++ * Initial revision
++ *
++
++
++----------------------------------------------------------------------------
++
++ REFERENCES: [ 1] Shapiro, Ascher H.: "The Dynamics and Thermodynamics
++ of Compressible Fluid Flow", Volume I, The Ronald
++ Press, 1953.
++
++----------------------------------------------------------------------------
++
++ CALLED BY:
++
++----------------------------------------------------------------------------
++
++ CALLS TO:
++
++----------------------------------------------------------------------------
++
++ INPUTS:
++
++----------------------------------------------------------------------------
++
++ OUTPUTS:
++
++--------------------------------------------------------------------------*/
++#include "ls_types.h"
++#include "ls_constants.h"
++#include "ls_generic.h"
++
++#include "ls_aux.h"
++
++#include "atmos_62.h"
++#include "ls_geodesy.h"
++#include "ls_gravity.h"
++
++#include <math.h>
++
++
++void ls_aux( void ) {
++
++ SCALAR dx_pilot_from_cg, dy_pilot_from_cg, dz_pilot_from_cg;
++ /* SCALAR inv_Mass; */
++ SCALAR v_XZ_plane_2, signU, v_tangential;
++ /* SCALAR inv_radius_ratio; */
++ SCALAR cos_rwy_hdg, sin_rwy_hdg;
++ SCALAR mach2, temp_ratio, pres_ratio;
++ SCALAR tmp;
++
++ /* update geodetic position */
++
++ ls_geoc_to_geod( Lat_geocentric, Radius_to_vehicle,
++ &Latitude, &Altitude, &Sea_level_radius );
++ Longitude = Lon_geocentric - Earth_position_angle;
++
++ /* Calculate body axis velocities */
++
++ /* Form relative velocity vector */
++
++ V_north_rel_ground = V_north;
++ V_east_rel_ground = V_east
++ - OMEGA_EARTH*Sea_level_radius*cos( Lat_geocentric );
++ V_down_rel_ground = V_down;
++
++ V_north_rel_airmass = V_north_rel_ground - V_north_airmass;
++ V_east_rel_airmass = V_east_rel_ground - V_east_airmass;
++ V_down_rel_airmass = V_down_rel_ground - V_down_airmass;
++
++ U_body = T_local_to_body_11*V_north_rel_airmass
++ + T_local_to_body_12*V_east_rel_airmass
++ + T_local_to_body_13*V_down_rel_airmass + U_gust;
++ V_body = T_local_to_body_21*V_north_rel_airmass
++ + T_local_to_body_22*V_east_rel_airmass
++ + T_local_to_body_23*V_down_rel_airmass + V_gust;
++ W_body = T_local_to_body_31*V_north_rel_airmass
++ + T_local_to_body_32*V_east_rel_airmass
++ + T_local_to_body_33*V_down_rel_airmass + W_gust;
++
++ V_rel_wind = sqrt(U_body*U_body + V_body*V_body + W_body*W_body);
++
++
++ /* Calculate alpha and beta rates */
++
++ v_XZ_plane_2 = (U_body*U_body + W_body*W_body);
++
++ if (U_body == 0)
++ signU = 1;
++ else
++ signU = U_body/fabs(U_body);
++
++ if( (v_XZ_plane_2 == 0) || (V_rel_wind == 0) )
++ {
++ Alpha_dot = 0;
++ Beta_dot = 0;
++ }
++ else
++ {
++ Alpha_dot = (U_body*W_dot_body - W_body*U_dot_body)/
++ v_XZ_plane_2;
++ Beta_dot = (signU*v_XZ_plane_2*V_dot_body
++ - V_body*(U_body*U_dot_body + W_body*W_dot_body))
++ /(V_rel_wind*V_rel_wind*sqrt(v_XZ_plane_2));
++ }
++
++ /* Calculate flight path and other flight condition values */
++
++ if (U_body == 0)
++ Alpha = 0;
++ else
++ Alpha = atan2( W_body, U_body );
++
++ Cos_alpha = cos(Alpha);
++ Sin_alpha = sin(Alpha);
++
++ if (V_rel_wind == 0)
++ Beta = 0;
++ else
++ Beta = asin( V_body/ V_rel_wind );
++
++ Cos_beta = cos(Beta);
++ Sin_beta = sin(Beta);
++
++ V_true_kts = V_rel_wind * V_TO_KNOTS;
++
++ V_ground_speed = sqrt(V_north_rel_ground*V_north_rel_ground
++ + V_east_rel_ground*V_east_rel_ground );
++
++ V_rel_ground = sqrt(V_ground_speed*V_ground_speed
++ + V_down_rel_ground*V_down_rel_ground );
++
++ v_tangential = sqrt(V_north*V_north + V_east*V_east);
++
++ V_inertial = sqrt(v_tangential*v_tangential + V_down*V_down);
++
++ if( (V_ground_speed == 0) && (V_down == 0) )
++ Gamma_vert_rad = 0;
++ else
++ Gamma_vert_rad = atan2( -V_down, V_ground_speed );
++
++ if( (V_north_rel_ground == 0) && (V_east_rel_ground == 0) )
++ Gamma_horiz_rad = 0;
++ else
++ Gamma_horiz_rad = atan2( V_east_rel_ground, V_north_rel_ground );
++
++ if (Gamma_horiz_rad < 0)
++ Gamma_horiz_rad = Gamma_horiz_rad + 2*PI;
++
++ /* Calculate local gravity */
++
++ ls_gravity( Radius_to_vehicle, Lat_geocentric, &Gravity );
++
++ /* call function for (smoothed) density ratio, sonic velocity, and
++ ambient pressure */
++
++ ls_atmos(Altitude, &Sigma, &V_sound,
++ &Static_temperature, &Static_pressure);
++
++ Density = Sigma*SEA_LEVEL_DENSITY;
++
++ Mach_number = V_rel_wind / V_sound;
++
++ V_equiv = V_rel_wind*sqrt(Sigma);
++
++ V_equiv_kts = V_equiv*V_TO_KNOTS;
++
++ /* calculate temperature and pressure ratios (from [1]) */
++
++ mach2 = Mach_number*Mach_number;
++ temp_ratio = 1.0 + 0.2*mach2;
++ tmp = 3.5;
++ pres_ratio = pow( temp_ratio, tmp );
++
++ Total_temperature = temp_ratio*Static_temperature;
++ Total_pressure = pres_ratio*Static_pressure;
++
++ /* calculate impact and dynamic pressures */
++
++ Impact_pressure = Total_pressure - Static_pressure;
++
++ Dynamic_pressure = 0.5*Density*V_rel_wind*V_rel_wind;
++
++ /* calculate calibrated airspeed indication */
++
++ V_calibrated = sqrt( 2.0*Dynamic_pressure / SEA_LEVEL_DENSITY );
++ V_calibrated_kts = V_calibrated*V_TO_KNOTS;
++
++ Centrifugal_relief = 1 - v_tangential/(Radius_to_vehicle*Gravity);
++
++/* Determine location in runway coordinates */
++
++ Radius_to_rwy = Sea_level_radius + Runway_altitude;
++ cos_rwy_hdg = cos(Runway_heading*DEG_TO_RAD);
++ sin_rwy_hdg = sin(Runway_heading*DEG_TO_RAD);
++
++ D_cg_north_of_rwy = Radius_to_rwy*(Latitude - Runway_latitude);
++ D_cg_east_of_rwy = Radius_to_rwy*cos(Runway_latitude)
++ *(Longitude - Runway_longitude);
++ D_cg_above_rwy = Radius_to_vehicle - Radius_to_rwy;
++
++ X_cg_rwy = D_cg_north_of_rwy*cos_rwy_hdg
++ + D_cg_east_of_rwy*sin_rwy_hdg;
++ Y_cg_rwy =-D_cg_north_of_rwy*sin_rwy_hdg
++ + D_cg_east_of_rwy*cos_rwy_hdg;
++ H_cg_rwy = D_cg_above_rwy;
++
++ dx_pilot_from_cg = Dx_pilot - Dx_cg;
++ dy_pilot_from_cg = Dy_pilot - Dy_cg;
++ dz_pilot_from_cg = Dz_pilot - Dz_cg;
++
++ D_pilot_north_of_rwy = D_cg_north_of_rwy
++ + T_local_to_body_11*dx_pilot_from_cg
++ + T_local_to_body_21*dy_pilot_from_cg
++ + T_local_to_body_31*dz_pilot_from_cg;
++ D_pilot_east_of_rwy = D_cg_east_of_rwy
++ + T_local_to_body_12*dx_pilot_from_cg
++ + T_local_to_body_22*dy_pilot_from_cg
++ + T_local_to_body_32*dz_pilot_from_cg;
++ D_pilot_above_rwy = D_cg_above_rwy
++ - T_local_to_body_13*dx_pilot_from_cg
++ - T_local_to_body_23*dy_pilot_from_cg
++ - T_local_to_body_33*dz_pilot_from_cg;
++
++ X_pilot_rwy = D_pilot_north_of_rwy*cos_rwy_hdg
++ + D_pilot_east_of_rwy*sin_rwy_hdg;
++ Y_pilot_rwy = -D_pilot_north_of_rwy*sin_rwy_hdg
++ + D_pilot_east_of_rwy*cos_rwy_hdg;
++ H_pilot_rwy = D_pilot_above_rwy;
++
++/* Calculate Euler rates */
++
++ Sin_phi = sin(Phi);
++ Cos_phi = cos(Phi);
++ Sin_theta = sin(Theta);
++ Cos_theta = cos(Theta);
++ Sin_psi = sin(Psi);
++ Cos_psi = cos(Psi);
++
++ if( Cos_theta == 0 )
++ Psi_dot = 0;
++ else
++ Psi_dot = (Q_total*Sin_phi + R_total*Cos_phi)/Cos_theta;
++
++ Theta_dot = Q_total*Cos_phi - R_total*Sin_phi;
++ Phi_dot = P_total + Psi_dot*Sin_theta;
++
++/* end of ls_aux */
++
++}
++/*************************************************************************/
--- /dev/null
--- /dev/null
++/* a quick ls_aux.h */
++
++
++#ifndef _LS_AUX_H
++#define _LS_AUX_H
++
++
++void ls_aux( void );
++
++
++#endif /* _LS_AUX_H */
--- /dev/null
--- /dev/null
++/***************************************************************************
++
++ TITLE: ls_cockpit.h
++
++----------------------------------------------------------------------------
++
++ FUNCTION: Header for cockpit IO
++
++----------------------------------------------------------------------------
++
++ MODULE STATUS: Developmental
++
++----------------------------------------------------------------------------
++
++ GENEALOGY: Created 20 DEC 93 by E. B. Jackson
++
++----------------------------------------------------------------------------
++
++ DESIGNED BY: E. B. Jackson
++
++ CODED BY: E. B. Jackson
++
++ MAINTAINED BY: E. B. Jackson
++
++----------------------------------------------------------------------------
++
++ MODIFICATION HISTORY:
++
++ DATE PURPOSE BY
++
++ 950314 Added "throttle_pct" field to cockpit header for both
++ display and trim purposes. EBJ
++
++ CURRENT RCS HEADER:
++
++$Header$
++$Log$
++Revision 1.5 1998/10/17 01:34:14 curt
++C++ ifying ...
++
++Revision 1.4 1998/08/06 12:46:39 curt
++Header change.
++
++Revision 1.3 1998/01/22 02:59:32 curt
++Changed #ifdef FILE_H to #ifdef _FILE_H
++
++Revision 1.2 1997/05/31 19:16:27 curt
++Elevator trim added.
++
++Revision 1.1 1997/05/29 00:09:54 curt
++Initial Flight Gear revision.
++
++ * Revision 1.3 1995/03/15 12:32:10 bjax
++ * Added throttle_pct field.
++ *
++ * Revision 1.2 1995/02/28 20:37:02 bjax
++ * Changed name of gear_sel_down switch to gear_sel_up to reflect
++ * correct sense of switch. EBJ
++ *
++ * Revision 1.1 1993/12/21 14:39:04 bjax
++ * Initial revision
++ *
++
++--------------------------------------------------------------------------*/
++
++
++#ifndef _LS_COCKPIT_H
++#define _LS_COCKPIT_H
++
++
++typedef struct {
++ float long_stick, lat_stick, rudder_pedal;
++ float long_trim;
++ float throttle[4];
++ short forward_trim, aft_trim, left_trim, right_trim;
++ short left_pb_on_stick, right_pb_on_stick, trig_pos_1, trig_pos_2;
++ short sb_extend, sb_retract, gear_sel_up;
++ float throttle_pct;
++ float brake_pct;
++} COCKPIT;
++
++extern COCKPIT cockpit_;
++
++#define Left_button cockpit_.left_pb_on_stick
++#define Right_button cockpit_.right_pb_on_stick
++#define Rudder_pedal cockpit_.rudder_pedal
++#define Throttle cockpit_.throttle
++#define Throttle_pct cockpit_.throttle_pct
++#define First_trigger cockpit_.trig_pos_1
++#define Second_trigger cockpit_.trig_pos_2
++#define Long_control cockpit_.long_stick
++#define Long_trim cockpit_.long_trim
++#define Lat_control cockpit_.lat_stick
++#define Fwd_trim cockpit_.forward_trim
++#define Aft_trim cockpit_.aft_trim
++#define Left_trim cockpit_.left_trim
++#define Right_trim cockpit_.right_trim
++#define SB_extend cockpit_.sb_extend
++#define SB_retract cockpit_.sb_retract
++#define Gear_sel_up cockpit_.gear_sel_up
++#define Brake_pct cockpit_.brake_pct
++
++
++#endif /* _LS_COCKPIT_H */
--- /dev/null
--- /dev/null
++/***************************************************************************
++
++ TITLE: ls_constants.h
++
++----------------------------------------------------------------------------
++
++ FUNCTION: LaRCSim constants definition header file
++
++----------------------------------------------------------------------------
++
++ MODULE STATUS: developmental
++
++----------------------------------------------------------------------------
++
++ GENEALOGY: Created 15 DEC 1993 by Bruce Jackson; was part of
++ old ls_eom.h header file
++
++----------------------------------------------------------------------------
++
++ DESIGNED BY: B. Jackson
++
++ CODED BY: B. Jackson
++
++ MAINTAINED BY: guess who
++
++----------------------------------------------------------------------------
++
++ MODIFICATION HISTORY:
++
++ DATE PURPOSE BY
++
++----------------------------------------------------------------------------
++
++ REFERENCES:
++
++ [ 1] McFarland, Richard E.: "A Standard Kinematic Model
++ for Flight Simulation at NASA-Ames", NASA CR-2497,
++ January 1975
++
++ [ 2] ANSI/AIAA R-004-1992 "Recommended Practice: Atmos-
++ pheric and Space Flight Vehicle Coordinate Systems",
++ February 1992
++
++ [ 3] Beyer, William H., editor: "CRC Standard Mathematical
++ Tables, 28th edition", CRC Press, Boca Raton, FL, 1987,
++ ISBN 0-8493-0628-0
++
++ [ 4] Dowdy, M. C.; Jackson, E. B.; and Nichols, J. H.:
++ "Controls Analysis and Simulation Test Loop Environ-
++ ment (CASTLE) Programmer's Guide, Version 1.3",
++ NATC TM 89-11, 30 March 1989.
++
++ [ 5] Halliday, David; and Resnick, Robert: "Fundamentals
++ of Physics, Revised Printing", Wiley and Sons, 1974.
++ ISBN 0-471-34431-1
++
++ [ 6] Anon: "U. S. Standard Atmosphere, 1962"
++
++ [ 7] Anon: "Aeronautical Vest Pocket Handbook, 17th edition",
++ Pratt & Whitney Aircraft Group, Dec. 1977
++
++ [ 8] Stevens, Brian L.; and Lewis, Frank L.: "Aircraft
++ Control and Simulation", Wiley and Sons, 1992.
++ ISBN 0-471-61397-5
++
++--------------------------------------------------------------------------*/
++
++#ifndef _LS_CONSTANTS
++#define _LS_CONSTANTS
++
++
++#ifndef CONSTANTS
++
++#define CONSTANTS -1
++
++/* Define application-wide macros */
++
++#define PATHNAME "LARCSIMPATH"
++#ifndef NIL_POINTER
++#define NIL_POINTER 0L
++#endif
++
++/* Define constants (note: many factors will need to change for other
++ systems of measure) */
++
++/* Value of Pi from ref [3] */
++#ifdef PI
++# undef PI /* avoid a harmless compiler warning */
++#endif
++#define PI 3.14159265358979323846264338327950288419716939967511
++
++/* Value of earth radius from [8], ft */
++#define EQUATORIAL_RADIUS 20925650.
++#define RESQ 437882827922500.
++
++/* Value of earth flattening parameter from ref [8]
++
++ Note: FP = f
++ E = 1-f
++ EPS = sqrt(1-(1-f)^2) */
++
++#define FP .003352813178
++#define E .996647186
++#define EPS .081819221
++#define INVG .031080997
++
++/* linear velocity of earth at equator from w*R; w=2pi/24 hrs, in ft/sec */
++#define OMEGA_EARTH .00007272205217
++
++/* miscellaneous units conversions (ref [7]) */
++#define V_TO_KNOTS 0.5921
++#define DEG_TO_RAD 0.017453292
++#define RAD_TO_DEG 57.29577951
++#define FT_TO_METERS 0.3048
++#define METERS_TO_FT 3.2808
++#define K_TO_R 1.8
++#define R_TO_K 0.55555556
++#define NSM_TO_PSF 0.02088547
++#define PSF_TO_NSM 47.8801826
++#define KCM_TO_SCF 0.00194106
++#define SCF_TO_KCM 515.183616
++
++
++/* ENGLISH Atmospheric reference properties [6] */
++#define SEA_LEVEL_DENSITY 0.002376888
++
++#endif
++
++
++#endif /* _LS_CONSTANTS_H */
++
++
++/*------------------------- end of ls_constants.h -------------------------*/
--- /dev/null
--- /dev/null
++/***************************************************************************
++
++ TITLE: ls_generic.h
++
++----------------------------------------------------------------------------
++
++ FUNCTION: LaRCSim generic parameters header file
++
++----------------------------------------------------------------------------
++
++ MODULE STATUS: developmental
++
++----------------------------------------------------------------------------
++
++ GENEALOGY: Created 15 DEC 1993 by Bruce Jackson;
++ was part of old ls_eom.h header
++
++----------------------------------------------------------------------------
++
++ DESIGNED BY: B. Jackson
++
++ CODED BY: B. Jackson
++
++ MAINTAINED BY: guess who
++
++----------------------------------------------------------------------------
++
++ MODIFICATION HISTORY:
++
++ DATE PURPOSE BY
++
++
++----------------------------------------------------------------------------
++
++ REFERENCES:
++
++ [ 1] McFarland, Richard E.: "A Standard Kinematic Model
++ for Flight Simulation at NASA-Ames", NASA CR-2497,
++ January 1975
++
++ [ 2] ANSI/AIAA R-004-1992 "Recommended Practice: Atmos-
++ pheric and Space Flight Vehicle Coordinate Systems",
++ February 1992
++
++ [ 3] Beyer, William H., editor: "CRC Standard Mathematical
++ Tables, 28th edition", CRC Press, Boca Raton, FL, 1987,
++ ISBN 0-8493-0628-0
++
++ [ 4] Dowdy, M. C.; Jackson, E. B.; and Nichols, J. H.:
++ "Controls Analysis and Simulation Test Loop Environ-
++ ment (CASTLE) Programmer's Guide, Version 1.3",
++ NATC TM 89-11, 30 March 1989.
++
++ [ 5] Halliday, David; and Resnick, Robert: "Fundamentals
++ of Physics, Revised Printing", Wiley and Sons, 1974.
++ ISBN 0-471-34431-1
++
++ [ 6] Anon: "U. S. Standard Atmosphere, 1962"
++
++ [ 7] Anon: "Aeronautical Vest Pocket Handbook, 17th edition",
++ Pratt & Whitney Aircraft Group, Dec. 1977
++
++ [ 8] Stevens, Brian L.; and Lewis, Frank L.: "Aircraft
++ Control and Simulation", Wiley and Sons, 1992.
++ ISBN 0-471-61397-5
++
++--------------------------------------------------------------------------*/
++
++
++#ifndef _LS_GENERIC_H
++#define _LS_GENERIC_H
++
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++
++#include "ls_types.h"
++
++
++typedef struct {
++
++/*================== Mass properties and geometry values ==================*/
++
++ DATA mass, i_xx, i_yy, i_zz, i_xz; /* Inertias */
++#define Mass generic_.mass
++#define I_xx generic_.i_xx
++#define I_yy generic_.i_yy
++#define I_zz generic_.i_zz
++#define I_xz generic_.i_xz
++
++ VECTOR_3 d_pilot_rp_body_v; /* Pilot location rel to ref pt */
++#define D_pilot_rp_body_v generic_.d_pilot_rp_body_v
++#define Dx_pilot generic_.d_pilot_rp_body_v[0]
++#define Dy_pilot generic_.d_pilot_rp_body_v[1]
++#define Dz_pilot generic_.d_pilot_rp_body_v[2]
++
++ VECTOR_3 d_cg_rp_body_v; /* CG position w.r.t. ref. point */
++#define D_cg_rp_body_v generic_.d_cg_rp_body_v
++#define Dx_cg generic_.d_cg_rp_body_v[0]
++#define Dy_cg generic_.d_cg_rp_body_v[1]
++#define Dz_cg generic_.d_cg_rp_body_v[2]
++
++/*================================ Forces =================================*/
++
++ VECTOR_3 f_body_total_v;
++#define F_body_total_v generic_.f_body_total_v
++#define F_X generic_.f_body_total_v[0]
++#define F_Y generic_.f_body_total_v[1]
++#define F_Z generic_.f_body_total_v[2]
++
++ VECTOR_3 f_local_total_v;
++#define F_local_total_v generic_.f_local_total_v
++#define F_north generic_.f_local_total_v[0]
++#define F_east generic_.f_local_total_v[1]
++#define F_down generic_.f_local_total_v[2]
++
++ VECTOR_3 f_aero_v;
++#define F_aero_v generic_.f_aero_v
++#define F_X_aero generic_.f_aero_v[0]
++#define F_Y_aero generic_.f_aero_v[1]
++#define F_Z_aero generic_.f_aero_v[2]
++
++ VECTOR_3 f_engine_v;
++#define F_engine_v generic_.f_engine_v
++#define F_X_engine generic_.f_engine_v[0]
++#define F_Y_engine generic_.f_engine_v[1]
++#define F_Z_engine generic_.f_engine_v[2]
++
++ VECTOR_3 f_gear_v;
++#define F_gear_v generic_.f_gear_v
++#define F_X_gear generic_.f_gear_v[0]
++#define F_Y_gear generic_.f_gear_v[1]
++#define F_Z_gear generic_.f_gear_v[2]
++
++/*================================ Moments ================================*/
++
++ VECTOR_3 m_total_rp_v;
++#define M_total_rp_v generic_.m_total_rp_v
++#define M_l_rp generic_.m_total_rp_v[0]
++#define M_m_rp generic_.m_total_rp_v[1]
++#define M_n_rp generic_.m_total_rp_v[2]
++
++ VECTOR_3 m_total_cg_v;
++#define M_total_cg_v generic_.m_total_cg_v
++#define M_l_cg generic_.m_total_cg_v[0]
++#define M_m_cg generic_.m_total_cg_v[1]
++#define M_n_cg generic_.m_total_cg_v[2]
++
++ VECTOR_3 m_aero_v;
++#define M_aero_v generic_.m_aero_v
++#define M_l_aero generic_.m_aero_v[0]
++#define M_m_aero generic_.m_aero_v[1]
++#define M_n_aero generic_.m_aero_v[2]
++
++ VECTOR_3 m_engine_v;
++#define M_engine_v generic_.m_engine_v
++#define M_l_engine generic_.m_engine_v[0]
++#define M_m_engine generic_.m_engine_v[1]
++#define M_n_engine generic_.m_engine_v[2]
++
++ VECTOR_3 m_gear_v;
++#define M_gear_v generic_.m_gear_v
++#define M_l_gear generic_.m_gear_v[0]
++#define M_m_gear generic_.m_gear_v[1]
++#define M_n_gear generic_.m_gear_v[2]
++
++/*============================== Accelerations ============================*/
++
++ VECTOR_3 v_dot_local_v;
++#define V_dot_local_v generic_.v_dot_local_v
++#define V_dot_north generic_.v_dot_local_v[0]
++#define V_dot_east generic_.v_dot_local_v[1]
++#define V_dot_down generic_.v_dot_local_v[2]
++
++ VECTOR_3 v_dot_body_v;
++#define V_dot_body_v generic_.v_dot_body_v
++#define U_dot_body generic_.v_dot_body_v[0]
++#define V_dot_body generic_.v_dot_body_v[1]
++#define W_dot_body generic_.v_dot_body_v[2]
++
++ VECTOR_3 a_cg_body_v;
++#define A_cg_body_v generic_.a_cg_body_v
++#define A_X_cg generic_.a_cg_body_v[0]
++#define A_Y_cg generic_.a_cg_body_v[1]
++#define A_Z_cg generic_.a_cg_body_v[2]
++
++ VECTOR_3 a_pilot_body_v;
++#define A_pilot_body_v generic_.a_pilot_body_v
++#define A_X_pilot generic_.a_pilot_body_v[0]
++#define A_Y_pilot generic_.a_pilot_body_v[1]
++#define A_Z_pilot generic_.a_pilot_body_v[2]
++
++ VECTOR_3 n_cg_body_v;
++#define N_cg_body_v generic_.n_cg_body_v
++#define N_X_cg generic_.n_cg_body_v[0]
++#define N_Y_cg generic_.n_cg_body_v[1]
++#define N_Z_cg generic_.n_cg_body_v[2]
++
++ VECTOR_3 n_pilot_body_v;
++#define N_pilot_body_v generic_.n_pilot_body_v
++#define N_X_pilot generic_.n_pilot_body_v[0]
++#define N_Y_pilot generic_.n_pilot_body_v[1]
++#define N_Z_pilot generic_.n_pilot_body_v[2]
++
++ VECTOR_3 omega_dot_body_v;
++#define Omega_dot_body_v generic_.omega_dot_body_v
++#define P_dot_body generic_.omega_dot_body_v[0]
++#define Q_dot_body generic_.omega_dot_body_v[1]
++#define R_dot_body generic_.omega_dot_body_v[2]
++
++
++/*============================== Velocities ===============================*/
++
++ VECTOR_3 v_local_v;
++#define V_local_v generic_.v_local_v
++#define V_north generic_.v_local_v[0]
++#define V_east generic_.v_local_v[1]
++#define V_down generic_.v_local_v[2]
++
++ VECTOR_3 v_local_rel_ground_v; /* V rel w.r.t. earth surface */
++#define V_local_rel_ground_v generic_.v_local_rel_ground_v
++#define V_north_rel_ground generic_.v_local_rel_ground_v[0]
++#define V_east_rel_ground generic_.v_local_rel_ground_v[1]
++#define V_down_rel_ground generic_.v_local_rel_ground_v[2]
++
++ VECTOR_3 v_local_airmass_v; /* velocity of airmass (steady winds) */
++#define V_local_airmass_v generic_.v_local_airmass_v
++#define V_north_airmass generic_.v_local_airmass_v[0]
++#define V_east_airmass generic_.v_local_airmass_v[1]
++#define V_down_airmass generic_.v_local_airmass_v[2]
++
++ VECTOR_3 v_local_rel_airmass_v; /* velocity of veh. relative to airmass */
++#define V_local_rel_airmass_v generic_.v_local_rel_airmass_v
++#define V_north_rel_airmass generic_.v_local_rel_airmass_v[0]
++#define V_east_rel_airmass generic_.v_local_rel_airmass_v[1]
++#define V_down_rel_airmass generic_.v_local_rel_airmass_v[2]
++
++ VECTOR_3 v_local_gust_v; /* linear turbulence components, L frame */
++#define V_local_gust_v generic_.v_local_gust_v
++#define U_gust generic_.v_local_gust_v[0]
++#define V_gust generic_.v_local_gust_v[1]
++#define W_gust generic_.v_local_gust_v[2]
++
++ VECTOR_3 v_wind_body_v; /* Wind-relative velocities in body axis */
++#define V_wind_body_v generic_.v_wind_body_v
++#define U_body generic_.v_wind_body_v[0]
++#define V_body generic_.v_wind_body_v[1]
++#define W_body generic_.v_wind_body_v[2]
++
++ DATA v_rel_wind, v_true_kts, v_rel_ground, v_inertial;
++ DATA v_ground_speed, v_equiv, v_equiv_kts;
++ DATA v_calibrated, v_calibrated_kts;
++#define V_rel_wind generic_.v_rel_wind
++#define V_true_kts generic_.v_true_kts
++#define V_rel_ground generic_.v_rel_ground
++#define V_inertial generic_.v_inertial
++#define V_ground_speed generic_.v_ground_speed
++#define V_equiv generic_.v_equiv
++#define V_equiv_kts generic_.v_equiv_kts
++#define V_calibrated generic_.v_calibrated
++#define V_calibrated_kts generic_.v_calibrated_kts
++
++ VECTOR_3 omega_body_v; /* Angular B rates */
++#define Omega_body_v generic_.omega_body_v
++#define P_body generic_.omega_body_v[0]
++#define Q_body generic_.omega_body_v[1]
++#define R_body generic_.omega_body_v[2]
++
++ VECTOR_3 omega_local_v; /* Angular L rates */
++#define Omega_local_v generic_.omega_local_v
++#define P_local generic_.omega_local_v[0]
++#define Q_local generic_.omega_local_v[1]
++#define R_local generic_.omega_local_v[2]
++
++ VECTOR_3 omega_total_v; /* Diff btw B & L */
++#define Omega_total_v generic_.omega_total_v
++#define P_total generic_.omega_total_v[0]
++#define Q_total generic_.omega_total_v[1]
++#define R_total generic_.omega_total_v[2]
++
++ VECTOR_3 euler_rates_v;
++#define Euler_rates_v generic_.euler_rates_v
++#define Phi_dot generic_.euler_rates_v[0]
++#define Theta_dot generic_.euler_rates_v[1]
++#define Psi_dot generic_.euler_rates_v[2]
++
++ VECTOR_3 geocentric_rates_v; /* Geocentric linear velocities */
++#define Geocentric_rates_v generic_.geocentric_rates_v
++#define Latitude_dot generic_.geocentric_rates_v[0]
++#define Longitude_dot generic_.geocentric_rates_v[1]
++#define Radius_dot generic_.geocentric_rates_v[2]
++
++/*=============================== Positions ===============================*/
++
++ VECTOR_3 geocentric_position_v;
++#define Geocentric_position_v generic_.geocentric_position_v
++#define Lat_geocentric generic_.geocentric_position_v[0]
++#define Lon_geocentric generic_.geocentric_position_v[1]
++#define Radius_to_vehicle generic_.geocentric_position_v[2]
++
++ VECTOR_3 geodetic_position_v;
++#define Geodetic_position_v generic_.geodetic_position_v
++#define Latitude generic_.geodetic_position_v[0]
++#define Longitude generic_.geodetic_position_v[1]
++#define Altitude generic_.geodetic_position_v[2]
++
++ VECTOR_3 euler_angles_v;
++#define Euler_angles_v generic_.euler_angles_v
++#define Phi generic_.euler_angles_v[0]
++#define Theta generic_.euler_angles_v[1]
++#define Psi generic_.euler_angles_v[2]
++
++/*======================= Miscellaneous quantities ========================*/
++
++ DATA t_local_to_body_m[3][3]; /* Transformation matrix L to B */
++#define T_local_to_body_m generic_.t_local_to_body_m
++#define T_local_to_body_11 generic_.t_local_to_body_m[0][0]
++#define T_local_to_body_12 generic_.t_local_to_body_m[0][1]
++#define T_local_to_body_13 generic_.t_local_to_body_m[0][2]
++#define T_local_to_body_21 generic_.t_local_to_body_m[1][0]
++#define T_local_to_body_22 generic_.t_local_to_body_m[1][1]
++#define T_local_to_body_23 generic_.t_local_to_body_m[1][2]
++#define T_local_to_body_31 generic_.t_local_to_body_m[2][0]
++#define T_local_to_body_32 generic_.t_local_to_body_m[2][1]
++#define T_local_to_body_33 generic_.t_local_to_body_m[2][2]
++
++ DATA gravity; /* Local acceleration due to G */
++#define Gravity generic_.gravity
++
++ DATA centrifugal_relief; /* load factor reduction due to speed */
++#define Centrifugal_relief generic_.centrifugal_relief
++
++ DATA alpha, beta, alpha_dot, beta_dot; /* in radians */
++#define Alpha generic_.alpha
++#define Beta generic_.beta
++#define Alpha_dot generic_.alpha_dot
++#define Beta_dot generic_.beta_dot
++
++ DATA cos_alpha, sin_alpha, cos_beta, sin_beta;
++#define Cos_alpha generic_.cos_alpha
++#define Sin_alpha generic_.sin_alpha
++#define Cos_beta generic_.cos_beta
++#define Sin_beta generic_.sin_beta
++
++ DATA cos_phi, sin_phi, cos_theta, sin_theta, cos_psi, sin_psi;
++#define Cos_phi generic_.cos_phi
++#define Sin_phi generic_.sin_phi
++#define Cos_theta generic_.cos_theta
++#define Sin_theta generic_.sin_theta
++#define Cos_psi generic_.cos_psi
++#define Sin_psi generic_.sin_psi
++
++ DATA gamma_vert_rad, gamma_horiz_rad; /* Flight path angles */
++#define Gamma_vert_rad generic_.gamma_vert_rad
++#define Gamma_horiz_rad generic_.gamma_horiz_rad
++
++ DATA sigma, density, v_sound, mach_number;
++#define Sigma generic_.sigma
++#define Density generic_.density
++#define V_sound generic_.v_sound
++#define Mach_number generic_.mach_number
++
++ DATA static_pressure, total_pressure, impact_pressure, dynamic_pressure;
++#define Static_pressure generic_.static_pressure
++#define Total_pressure generic_.total_pressure
++#define Impact_pressure generic_.impact_pressure
++#define Dynamic_pressure generic_.dynamic_pressure
++
++ DATA static_temperature, total_temperature;
++#define Static_temperature generic_.static_temperature
++#define Total_temperature generic_.total_temperature
++
++ DATA sea_level_radius, earth_position_angle;
++#define Sea_level_radius generic_.sea_level_radius
++#define Earth_position_angle generic_.earth_position_angle
++
++ DATA runway_altitude, runway_latitude, runway_longitude, runway_heading;
++#define Runway_altitude generic_.runway_altitude
++#define Runway_latitude generic_.runway_latitude
++#define Runway_longitude generic_.runway_longitude
++#define Runway_heading generic_.runway_heading
++
++ DATA radius_to_rwy;
++#define Radius_to_rwy generic_.radius_to_rwy
++
++ VECTOR_3 d_cg_rwy_local_v; /* CG rel. to rwy in local coords */
++#define D_cg_rwy_local_v generic_.d_cg_rwy_local_v
++#define D_cg_north_of_rwy generic_.d_cg_rwy_local_v[0]
++#define D_cg_east_of_rwy generic_.d_cg_rwy_local_v[1]
++#define D_cg_above_rwy generic_.d_cg_rwy_local_v[2]
++
++ VECTOR_3 d_cg_rwy_rwy_v; /* CG relative to runway, in rwy coordinates */
++#define D_cg_rwy_rwy_v generic_.d_cg_rwy_rwy_v
++#define X_cg_rwy generic_.d_cg_rwy_rwy_v[0]
++#define Y_cg_rwy generic_.d_cg_rwy_rwy_v[1]
++#define H_cg_rwy generic_.d_cg_rwy_rwy_v[2]
++
++ VECTOR_3 d_pilot_rwy_local_v; /* pilot rel. to rwy in local coords */
++#define D_pilot_rwy_local_v generic_.d_pilot_rwy_local_v
++#define D_pilot_north_of_rwy generic_.d_pilot_rwy_local_v[0]
++#define D_pilot_east_of_rwy generic_.d_pilot_rwy_local_v[1]
++#define D_pilot_above_rwy generic_.d_pilot_rwy_local_v[2]
++
++ VECTOR_3 d_pilot_rwy_rwy_v; /* pilot rel. to rwy, in rwy coords. */
++#define D_pilot_rwy_rwy_v generic_.d_pilot_rwy_rwy_v
++#define X_pilot_rwy generic_.d_pilot_rwy_rwy_v[0]
++#define Y_pilot_rwy generic_.d_pilot_rwy_rwy_v[1]
++#define H_pilot_rwy generic_.d_pilot_rwy_rwy_v[2]
++
++
++} GENERIC;
++
++extern GENERIC generic_; /* usually defined in ls_main.c */
++
++
++#ifdef __cplusplus
++}
++#endif
++
++
++#endif /* _LS_GENERIC_H */
++
++
++/*--------------------------- end of ls_generic.h ------------------------*/
--- /dev/null
--- /dev/null
++/***************************************************************************
++
++ TITLE: ls_geodesy
++
++----------------------------------------------------------------------------
++
++ FUNCTION: Converts geocentric coordinates to geodetic positions
++
++----------------------------------------------------------------------------
++
++ MODULE STATUS: developmental
++
++----------------------------------------------------------------------------
++
++ GENEALOGY: Written as part of LaRCSim project by E. B. Jackson
++
++----------------------------------------------------------------------------
++
++ DESIGNED BY: E. B. Jackson
++
++ CODED BY: E. B. Jackson
++
++ MAINTAINED BY: E. B. Jackson
++
++----------------------------------------------------------------------------
++
++ MODIFICATION HISTORY:
++
++ DATE PURPOSE BY
++
++ 930208 Modified to avoid singularity near polar region. EBJ
++ 930602 Moved backwards calcs here from ls_step. EBJ
++ 931214 Changed erroneous Latitude and Altitude variables to
++ *lat_geod and *alt in routine ls_geoc_to_geod. EBJ
++ 940111 Changed header files from old ls_eom.h style to ls_types,
++ and ls_constants. Also replaced old DATA type with new
++ SCALAR type. EBJ
++
++ CURRENT RCS HEADER:
++
++$Header$
++$Log$
++Revision 1.3 1998/07/08 14:41:37 curt
++.
++
++Revision 1.2 1998/01/19 18:40:25 curt
++Tons of little changes to clean up the code and to remove fatal errors
++when building with the c++ compiler.
++
++Revision 1.1 1997/05/29 00:09:56 curt
++Initial Flight Gear revision.
++
++ * Revision 1.5 1994/01/11 18:47:05 bjax
++ * Changed include files to use types and constants, not ls_eom.h
++ * Also changed DATA type to SCALAR type.
++ *
++ * Revision 1.4 1993/12/14 21:06:47 bjax
++ * Removed global variable references Altitude and Latitude. EBJ
++ *
++ * Revision 1.3 1993/06/02 15:03:40 bjax
++ * Made new subroutine for calculating geodetic to geocentric; changed name
++ * of forward conversion routine from ls_geodesy to ls_geoc_to_geod.
++ *
++
++----------------------------------------------------------------------------
++
++ REFERENCES:
++
++ [ 1] Stevens, Brian L.; and Lewis, Frank L.: "Aircraft
++ Control and Simulation", Wiley and Sons, 1992.
++ ISBN 0-471-61397-5
++
++
++----------------------------------------------------------------------------
++
++ CALLED BY: ls_aux
++
++----------------------------------------------------------------------------
++
++ CALLS TO:
++
++----------------------------------------------------------------------------
++
++ INPUTS:
++ lat_geoc Geocentric latitude, radians, + = North
++ radius C.G. radius to earth center, ft
++
++----------------------------------------------------------------------------
++
++ OUTPUTS:
++ lat_geod Geodetic latitude, radians, + = North
++ alt C.G. altitude above mean sea level, ft
++ sea_level_r radius from earth center to sea level at
++ local vertical (surface normal) of C.G.
++
++--------------------------------------------------------------------------*/
++
++#include "ls_types.h"
++#include "ls_constants.h"
++#include "ls_geodesy.h"
++#include <math.h>
++
++/* ONE_SECOND is pi/180/60/60, or about 100 feet at earths' equator */
++#define ONE_SECOND 4.848136811E-6
++#define HALF_PI 0.5*PI
++
++
++void ls_geoc_to_geod( SCALAR lat_geoc, SCALAR radius, SCALAR *lat_geod,
++ SCALAR *alt, SCALAR *sea_level_r )
++{
++ SCALAR t_lat, x_alpha, mu_alpha, delt_mu, r_alpha, l_point, rho_alpha;
++ SCALAR sin_mu_a, denom,delt_lambda, lambda_sl, sin_lambda_sl;
++
++ if( ( (HALF_PI - lat_geoc) < ONE_SECOND ) /* near North pole */
++ || ( (HALF_PI + lat_geoc) < ONE_SECOND ) ) /* near South pole */
++ {
++ *lat_geod = lat_geoc;
++ *sea_level_r = EQUATORIAL_RADIUS*E;
++ *alt = radius - *sea_level_r;
++ }
++ else
++ {
++ t_lat = tan(lat_geoc);
++ x_alpha = E*EQUATORIAL_RADIUS/sqrt(t_lat*t_lat + E*E);
++ mu_alpha = atan2(sqrt(RESQ - x_alpha*x_alpha),E*x_alpha);
++ if (lat_geoc < 0) mu_alpha = - mu_alpha;
++ sin_mu_a = sin(mu_alpha);
++ delt_lambda = mu_alpha - lat_geoc;
++ r_alpha = x_alpha/cos(lat_geoc);
++ l_point = radius - r_alpha;
++ *alt = l_point*cos(delt_lambda);
++ denom = sqrt(1-EPS*EPS*sin_mu_a*sin_mu_a);
++ rho_alpha = EQUATORIAL_RADIUS*(1-EPS)/
++ (denom*denom*denom);
++ delt_mu = atan2(l_point*sin(delt_lambda),rho_alpha + *alt);
++ *lat_geod = mu_alpha - delt_mu;
++ lambda_sl = atan( E*E * tan(*lat_geod) ); /* SL geoc. latitude */
++ sin_lambda_sl = sin( lambda_sl );
++ *sea_level_r = sqrt(RESQ
++ /(1 + ((1/(E*E))-1)*sin_lambda_sl*sin_lambda_sl));
++ }
++}
++
++
++void ls_geod_to_geoc( SCALAR lat_geod, SCALAR alt,
++ SCALAR *sl_radius, SCALAR *lat_geoc )
++{
++ SCALAR lambda_sl, sin_lambda_sl, cos_lambda_sl, sin_mu, cos_mu, px, py;
++
++ lambda_sl = atan( E*E * tan(lat_geod) ); /* sea level geocentric latitude */
++ sin_lambda_sl = sin( lambda_sl );
++ cos_lambda_sl = cos( lambda_sl );
++ sin_mu = sin(lat_geod); /* Geodetic (map makers') latitude */
++ cos_mu = cos(lat_geod);
++ *sl_radius = sqrt(RESQ
++ /(1 + ((1/(E*E))-1)*sin_lambda_sl*sin_lambda_sl));
++ py = *sl_radius*sin_lambda_sl + alt*sin_mu;
++ px = *sl_radius*cos_lambda_sl + alt*cos_mu;
++ *lat_geoc = atan2( py, px );
++}
--- /dev/null
--- /dev/null
++/* a quick ls_geodesy.h */
++
++
++#ifndef _LS_GEODESY_H
++#define _LS_GEODESY_H
++
++
++void ls_geoc_to_geod( SCALAR lat_geoc, SCALAR radius,
++ SCALAR *lat_geod, SCALAR *alt, SCALAR *sea_level_r );
++
++void ls_geod_to_geoc( SCALAR lat_geod, SCALAR alt, SCALAR *sl_radius,
++ SCALAR *lat_geoc );
++
++
++#endif /* _LS_GEODESY_H */
--- /dev/null
--- /dev/null
++/***************************************************************************
++
++ TITLE: ls_gravity
++
++----------------------------------------------------------------------------
++
++ FUNCTION: Gravity model for LaRCsim
++
++----------------------------------------------------------------------------
++
++ MODULE STATUS: developmental
++
++----------------------------------------------------------------------------
++
++ GENEALOGY: Created by Bruce Jackson on September 25, 1992.
++
++----------------------------------------------------------------------------
++
++ DESIGNED BY: Bruce Jackson
++
++ CODED BY: Bruce Jackson
++
++ MAINTAINED BY: Bruce Jackson
++
++----------------------------------------------------------------------------
++
++ MODIFICATION HISTORY:
++
++ DATE PURPOSE BY
++
++ 940111 Changed include files to "ls_types.h" and
++ "ls_constants.h" from "ls_eom.h"; also changed DATA types
++ to SCALAR types. EBJ
++
++
++$Header$
++$Log$
++Revision 1.3 1998/08/06 12:46:39 curt
++Header change.
++
++Revision 1.2 1998/01/19 18:40:26 curt
++Tons of little changes to clean up the code and to remove fatal errors
++when building with the c++ compiler.
++
++Revision 1.1 1997/05/29 00:09:56 curt
++Initial Flight Gear revision.
++
++ * Revision 1.2 1994/01/11 18:50:35 bjax
++ * Corrected include files (was ls_eom.h) and DATA types changed
++ * to SCALARs. EBJ
++ *
++ * Revision 1.1 1992/12/30 13:18:46 bjax
++ * Initial revision
++ *
++
++----------------------------------------------------------------------------
++
++ REFERENCES: Stevens, Brian L.; and Lewis, Frank L.: "Aircraft
++ Control and Simulation", Wiley and Sons, 1992.
++ ISBN 0-471-
++
++----------------------------------------------------------------------------
++
++ CALLED BY:
++
++----------------------------------------------------------------------------
++
++ CALLS TO:
++
++----------------------------------------------------------------------------
++
++ INPUTS:
++
++----------------------------------------------------------------------------
++
++ OUTPUTS:
++
++--------------------------------------------------------------------------*/
++#include "ls_types.h"
++#include "ls_constants.h"
++#include "ls_gravity.h"
++#include <math.h>
++
++#define GM 1.4076431E16
++#define J2 1.08263E-3
++
++void ls_gravity( SCALAR radius, SCALAR lat, SCALAR *gravity )
++{
++
++ SCALAR radius_ratio, rrsq, sinsqlat;
++
++ radius_ratio = radius/EQUATORIAL_RADIUS;
++ rrsq = radius_ratio*radius_ratio;
++ sinsqlat = sin(lat)*sin(lat);
++ *gravity = (GM/(radius*radius))
++ *sqrt(2.25*rrsq*rrsq*J2*J2*(5*sinsqlat*sinsqlat -2*sinsqlat + 1)
++ + 3*rrsq*J2*(1 - 3*sinsqlat) + 1);
++
++}
--- /dev/null
--- /dev/null
++/* a quick ls_gravity.h */
++
++
++#ifndef _LS_GRAVITY_H
++#define _LS_GRAVITY_H
++
++
++void ls_gravity( SCALAR radius, SCALAR lat, SCALAR *gravity );
++
++
++#endif _LS_GRAVITY_H
--- /dev/null
--- /dev/null
++/***************************************************************************
++
++ TITLE: ls_init.c
++
++----------------------------------------------------------------------------
++
++ FUNCTION: Initializes simulation
++
++----------------------------------------------------------------------------
++
++ MODULE STATUS: incomplete
++
++----------------------------------------------------------------------------
++
++ GENEALOGY: Written 921230 by Bruce Jackson
++
++----------------------------------------------------------------------------
++
++ DESIGNED BY: EBJ
++
++ CODED BY: EBJ
++
++ MAINTAINED BY: EBJ
++
++----------------------------------------------------------------------------
++
++ MODIFICATION HISTORY:
++
++ DATE PURPOSE BY
++
++ 950314 Added get_set, put_set, and init routines. EBJ
++
++ CURRENT RCS HEADER:
++
++$Header$
++$Log$
++Revision 1.5 1998/07/12 03:11:03 curt
++Removed some printf()'s.
++Fixed the autopilot integration so it should be able to update it's control
++ positions every time the internal flight model loop is run, and not just
++ once per rendered frame.
++Added a routine to do the necessary stuff to force an arbitrary altitude
++ change.
++Gave the Navion engine just a tad more power.
++
++Revision 1.4 1998/01/19 18:40:26 curt
++Tons of little changes to clean up the code and to remove fatal errors
++when building with the c++ compiler.
++
++Revision 1.3 1998/01/05 22:19:25 curt
++#ifdef'd out some unused code that was problematic for MSVC++ to compile.
++
++Revision 1.2 1997/05/29 22:39:58 curt
++Working on incorporating the LaRCsim flight model.
++
++Revision 1.1 1997/05/29 00:09:57 curt
++Initial Flight Gear revision.
++
++ * Revision 1.4 1995/03/15 12:15:23 bjax
++ * Added ls_init_get_set() and ls_init_put_set() and ls_init_init()
++ * routines. EBJ
++ *
++ * Revision 1.3 1994/01/11 19:09:44 bjax
++ * Fixed header includes.
++ *
++ * Revision 1.2 1992/12/30 14:04:53 bjax
++ * Added call to ls_step(0, 1).
++ *
++ * Revision 1.1 92/12/30 14:02:19 bjax
++ * Initial revision
++ *
++ * Revision 1.1 92/12/30 13:21:21 bjax
++ * Initial revision
++ *
++ * Revision 1.3 93/12/31 10:34:11 bjax
++ * Added $Log marker as well.
++ *
++
++----------------------------------------------------------------------------
++
++ REFERENCES:
++
++----------------------------------------------------------------------------
++
++ CALLED BY:
++
++----------------------------------------------------------------------------
++
++ CALLS TO:
++
++----------------------------------------------------------------------------
++
++ INPUTS:
++
++----------------------------------------------------------------------------
++
++ OUTPUTS:
++
++--------------------------------------------------------------------------*/
++static char rcsid[] = "$Id$";
++
++#include <string.h>
++#include <stdio.h>
++#include "ls_types.h"
++#include "ls_sym.h"
++#include "ls_step.h"
++#include "ls_init.h"
++#include "navion_init.h"
++
++/* temp */
++#include "ls_generic.h"
++
++#define MAX_NUMBER_OF_CONTINUOUS_STATES 100
++#define MAX_NUMBER_OF_DISCRETE_STATES 20
++#define HARDWIRED 13
++#define NIL_POINTER 0L
++
++#define FACILITY_NAME_STRING "init"
++#define CURRENT_VERSION 10
++
++typedef struct
++{
++ symbol_rec Symbol;
++ double value;
++} cont_state_rec;
++
++typedef struct
++{
++ symbol_rec Symbol;
++ long value;
++} disc_state_rec;
++
++
++extern SCALAR Simtime;
++
++/* static int Symbols_loaded = 0; */
++static int Number_of_Continuous_States = 0;
++static int Number_of_Discrete_States = 0;
++static cont_state_rec Continuous_States[ MAX_NUMBER_OF_CONTINUOUS_STATES ];
++static disc_state_rec Discrete_States[ MAX_NUMBER_OF_DISCRETE_STATES ];
++
++
++void ls_init_init( void ) {
++ int i;
++ /* int error; */
++
++ if (Number_of_Continuous_States == 0)
++ {
++ Number_of_Continuous_States = HARDWIRED;
++
++ for (i=0;i<HARDWIRED;i++)
++ strcpy( Continuous_States[i].Symbol.Mod_Name, "*" );
++
++ strcpy( Continuous_States[ 0].Symbol.Par_Name,
++ "generic_.geodetic_position_v[0]");
++ strcpy( Continuous_States[ 1].Symbol.Par_Name,
++ "generic_.geodetic_position_v[1]");
++ strcpy( Continuous_States[ 2].Symbol.Par_Name,
++ "generic_.geodetic_position_v[2]");
++ strcpy( Continuous_States[ 3].Symbol.Par_Name,
++ "generic_.v_local_v[0]");
++ strcpy( Continuous_States[ 4].Symbol.Par_Name,
++ "generic_.v_local_v[1]");
++ strcpy( Continuous_States[ 5].Symbol.Par_Name,
++ "generic_.v_local_v[2]");
++ strcpy( Continuous_States[ 6].Symbol.Par_Name,
++ "generic_.euler_angles_v[0]");
++ strcpy( Continuous_States[ 7].Symbol.Par_Name,
++ "generic_.euler_angles_v[1]");
++ strcpy( Continuous_States[ 8].Symbol.Par_Name,
++ "generic_.euler_angles_v[2]");
++ strcpy( Continuous_States[ 9].Symbol.Par_Name,
++ "generic_.omega_body_v[0]");
++ strcpy( Continuous_States[10].Symbol.Par_Name,
++ "generic_.omega_body_v[1]");
++ strcpy( Continuous_States[11].Symbol.Par_Name,
++ "generic_.omega_body_v[2]");
++ strcpy( Continuous_States[12].Symbol.Par_Name,
++ "generic_.earth_position_angle");
++ }
++
++ /* commented out by CLO
++ for (i=0;i<Number_of_Continuous_States;i++)
++ {
++ (void) ls_get_sym_val( &Continuous_States[i].Symbol, &error );
++ if (error) Continuous_States[i].Symbol.Addr = NIL_POINTER;
++ }
++
++ for (i=0;i<Number_of_Discrete_States;i++)
++ {
++ (void) ls_get_sym_val( &Discrete_States[i].Symbol, &error );
++ if (error) Discrete_States[i].Symbol.Addr = NIL_POINTER;
++ }
++ */
++}
++
++void ls_init( void ) {
++ /* int i; */
++
++ Simtime = 0;
++
++ /* printf("LS in init() pos = %.2f\n", Latitude); */
++
++ ls_init_init();
++
++ /* printf("LS after init_init() pos = %.2f\n", Latitude); */
++
++ /* move the states to proper values */
++
++ /* commented out by CLO
++ for(i=0;i<Number_of_Continuous_States;i++)
++ if (Continuous_States[i].Symbol.Addr)
++ ls_set_sym_val( &Continuous_States[i].Symbol,
++ Continuous_States[i].value );
++
++ for(i=0;i<Number_of_Discrete_States;i++)
++ if (Discrete_States[i].Symbol.Addr)
++ ls_set_sym_val( &Discrete_States[i].Symbol,
++ (double) Discrete_States[i].value );
++ */
++
++ model_init();
++
++ /* printf("LS after model_init() pos = %.2f\n", Latitude); */
++
++ ls_step(0.0, -1);
++
++ /* printf("LS after ls_step() pos = %.2f\n", Latitude); */
++}
++
++
++#ifdef COMPILE_THIS_CODE_THIS_USELESS_CODE
++
++char *ls_init_get_set(char *buffer, char *eob)
++/* This routine parses the settings file for "init" entries. */
++{
++
++ static char *fac_name = FACILITY_NAME_STRING;
++ char *bufptr;
++ char line[256];
++ int n, ver, i, error, abrt;
++
++ enum {cont_states_header, cont_states, disc_states_header, disc_states, done } looking_for;
++
++ abrt = 0;
++ looking_for = cont_states_header;
++
++ n = sscanf(buffer, "%s", line);
++ if (n == 0) return 0L;
++ if (strncasecmp( fac_name, line, strlen(fac_name) )) return 0L;
++
++ bufptr = strtok( buffer+strlen(fac_name)+1, "\n");
++ if (bufptr == 0) return 0L;
++
++ sscanf( bufptr, "%d", &ver );
++ if (ver != CURRENT_VERSION) return 0L;
++
++ ls_init_init();
++
++ while( !abrt && (eob > bufptr))
++ {
++ bufptr = strtok( 0L, "\n");
++ if (bufptr == 0) return 0L;
++ if (strncasecmp( bufptr, "end", 3) == 0) break;
++
++ sscanf( bufptr, "%s", line );
++ if (line[0] != '#') /* ignore comments */
++ {
++ switch (looking_for)
++ {
++ case cont_states_header:
++ {
++ if (strncasecmp( line, "continuous_states", 17) == 0)
++ {
++ n = sscanf( bufptr, "%s%d", line,
++ &Number_of_Continuous_States );
++ if (n != 2) abrt = 1;
++ looking_for = cont_states;
++ i = 0;
++ }
++ break;
++ }
++ case cont_states:
++ {
++ n = sscanf( bufptr, "%s%s%le",
++ Continuous_States[i].Symbol.Mod_Name,
++ Continuous_States[i].Symbol.Par_Name,
++ &Continuous_States[i].value );
++ if (n != 3) abrt = 1;
++ Continuous_States[i].Symbol.Addr = NIL_POINTER;
++ i++;
++ if (i >= Number_of_Continuous_States)
++ looking_for = disc_states_header;
++ break;
++ }
++ case disc_states_header:
++ {
++ if (strncasecmp( line, "discrete_states", 15) == 0)
++ {
++ n = sscanf( bufptr, "%s%d", line,
++ &Number_of_Discrete_States );
++ if (n != 2) abrt = 1;
++ looking_for = disc_states;
++ i = 0;
++ }
++ break;
++ }
++ case disc_states:
++ {
++ n = sscanf( bufptr, "%s%s%ld",
++ Discrete_States[i].Symbol.Mod_Name,
++ Discrete_States[i].Symbol.Par_Name,
++ &Discrete_States[i].value );
++ if (n != 3) abrt = 1;
++ Discrete_States[i].Symbol.Addr = NIL_POINTER;
++ i++;
++ if (i >= Number_of_Discrete_States) looking_for = done;
++ }
++ case done:
++ {
++ break;
++ }
++ }
++
++ }
++ }
++
++ Symbols_loaded = !abrt;
++
++ return bufptr;
++}
++#endif /* COMPILE_THIS_CODE_THIS_USELESS_CODE */
++
++
++void ls_init_put_set( FILE *fp )
++{
++ int i;
++
++ if (fp==0) return;
++ fprintf(fp, "\n");
++ fprintf(fp, "#============================== %s\n", FACILITY_NAME_STRING);
++ fprintf(fp, "\n");
++ fprintf(fp, FACILITY_NAME_STRING);
++ fprintf(fp, "\n");
++ fprintf(fp, "%04d\n", CURRENT_VERSION);
++ fprintf(fp, " continuous_states: %d\n", Number_of_Continuous_States);
++ fprintf(fp, "# module parameter value\n");
++ for (i=0; i<Number_of_Continuous_States; i++)
++ fprintf(fp, " %s\t%s\t%E\n",
++ Continuous_States[i].Symbol.Mod_Name,
++ Continuous_States[i].Symbol.Par_Name,
++ Continuous_States[i].value );
++
++ fprintf(fp, " discrete_states: %d\n", Number_of_Discrete_States);
++ fprintf(fp, "# module parameter value\n");
++ for (i=0;i<Number_of_Discrete_States;i++)
++ fprintf(fp, " %s\t%s\t%ld\n",
++ Discrete_States[i].Symbol.Mod_Name,
++ Discrete_States[i].Symbol.Par_Name,
++ Discrete_States[i].value );
++ fprintf(fp, "end\n");
++ return;
++}
++
++void ls_save_current_as_ic( void ) {
++ /* Save current states as initial conditions */
++
++ /* int i, error; */
++
++ /* commented out by CLO
++ for(i=0;i<Number_of_Continuous_States;i++)
++ if (Continuous_States[i].Symbol.Addr)
++ Continuous_States[i].value =
++ ls_get_sym_val( &Continuous_States[i].Symbol, &error );
++
++ for(i=0;i<Number_of_Discrete_States;i++)
++ if (Discrete_States[i].Symbol.Addr)
++ Discrete_States[i].value = (long)
++ ls_get_sym_val( &Discrete_States[i].Symbol, &error );
++ */
++}
--- /dev/null
--- /dev/null
++/* a quick ls_init.h */
++
++
++#ifndef _LS_INIT_H
++#define _LS_INIT_H
++
++
++void ls_init( void );
++
++
++#endif /* _LS_INIT_H */
--- /dev/null
--- /dev/null
++/**************************************************************************
++ * ls_interface.c -- the FG interface to the LaRCsim routines
++ * This is a heavily modified version of LaRCsim.c
++ * As a result there is much old baggage left in this file.
++ *
++ * Originally Written 921230 by Bruce Jackson
++ * Modified by Curtis Olson, started May 1997.
++ *
++ * 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$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++/* Original headers follow: */
++
++/***************************************************************************
++
++ TITLE: LaRCsim.c
++
++----------------------------------------------------------------------------
++
++ FUNCTION: Top level routine for LaRCSIM. Includes
++ global variable declarations.
++
++----------------------------------------------------------------------------
++
++ MODULE STATUS: Developmental
++
++----------------------------------------------------------------------------
++
++ GENEALOGY: Written 921230 by Bruce Jackson
++
++----------------------------------------------------------------------------
++
++ DESIGNED BY: EBJ
++
++ CODED BY: EBJ
++
++ MAINTAINED BY: EBJ
++
++----------------------------------------------------------------------------
++
++ MODIFICATION HISTORY:
++
++ DATE PURPOSE BY
++
++ 930111 Added "progname" variable to keep name of invoking command.
++ EBJ
++ 931012 Removed altitude < 0. test to support gear development. EBJ
++ 931214 Added various pressures (Impact, Dynamic, Static, etc.) EBJ
++ 931215 Adopted new generic variable structure. EBJ
++ 931218 Added command line options decoding. EBJ
++ 940110 Changed file type of matrix file to ".m" EBJ
++ 940513 Renamed this routine "LaRCsim.c" from "ls_main.c" EBJ
++ 940513 Added time_stamp routine, t_stamp. EBJ
++ 950225 Added options flag, 'i', to set I/O output rate. EBJ
++ 950306 Added calls to ls_get_settings() and ls_put_settings() EBJ
++ 950314 Options flag 'i' now reads IC file; 'o' is output rate EBJ
++ 950406 Many changes: added definition of default value macros;
++ removed local variables term_update_hz, model_dt, endtime,
++ substituted sim_control_ globals for these; removed
++ initialization of sim_control_.tape_channels; moved optarg
++ to generic extern; added mod_end_time & mod_buf_size flags
++ and temporary buffer_time and data_rate locals to
++ ls_checkopts(); added additional command line switches '-s'
++ and '-b'; made psuedo-mandatory file names for data output
++ switches; considerable rewrite of logic for setting data
++ buffer length and interleave parameters; updated '-h' help
++ output message; added protection logic to calculations of
++ these parameters; added check of return value on first call
++ to ls_cockpit() so <esc> abort works from initial pause
++ state; added call to ls_unsync() immediately following
++ first ls_sync() call, if paused (to avoid alarm clock
++ timeout); moved call to ls_record() into non-paused
++ multiloop path (was filling buffer with identical data
++ during pause); put check of paused flag before calling sync
++ routine ls_pause(); and added call to exit() on termination.
++
++
++$Header$
++$Original log: LaRCsim.c,v $
++ * Revision 1.4.1.7 1995/04/07 01:04:37 bjax
++ * Many changes made to support storage of sim options from run to run,
++ * as well as restructuring storage buffer sizing and some loop logic
++ * changes. See the modification log for details.
++ *
++ * Revision 1.4.1.6 1995/03/29 16:12:09 bjax
++ * Added argument to -o switch; changed run loop to pass dt=0
++ * if in paused mode. EBj
++ *
++ * Revision 1.4.1.5 1995/03/15 12:30:20 bjax
++ * Set paused flag to non-zero by default; moved 'i' I/O rate flag
++ * switch to 'o'; made 'i' an initial conditions file switch; added
++ * null string to ls_get_settings() call so that default settings
++ * file will be read. EBJ
++ *
++ * Revision 1.4.1.4 1995/03/08 12:31:34 bjax
++ * Added userid retrieval and proper termination of time & date strings.
++ *
++ * Revision 1.4.1.3 1995/03/08 12:00:21 bjax
++ * Moved setting of default options to ls_setdefopts from
++ * ls_checkopts; rearranged order of ls_get_settings() call
++ * to between ls_setdefopts and ls_checkopts, so command
++ * line options will override settings file options.
++ * EBJ
++ *
++ * Revision 1.4.1.2 1995/03/06 18:48:49 bjax
++ * Added calles to ls_get_settings() and ls_put_settings(); added
++ * passing of dt and init flags in ls_model(). EBJ
++ *
++ * Revision 1.4.1.1 1995/03/03 02:23:08 bjax
++ * Beta version for LaRCsim, version 1.4
++ *
++ * Revision 1.3.2.7 1995/02/27 20:00:21 bjax
++ * Rebuilt LaRCsim
++ *
++ * Revision 1.3.2.6 1995/02/25 16:52:31 bjax
++ * Added 'i' option to set I/O iteration rate. EBJ
++ *
++ * Revision 1.3.2.5 1995/02/06 19:33:15 bjax
++ * Rebuilt LaRCsim
++ *
++ * Revision 1.3.2.4 1995/02/06 19:30:30 bjax
++ * Oops, should really compile these before checking in. Fixed capitailzation of
++ * Initialize in ls_loop parameter.
++ *
++ * Revision 1.3.2.3 1995/02/06 19:25:44 bjax
++ * Moved main simulation loop into subroutine ls_loop. EBJ
++ *
++ * Revision 1.3.2.2 1994/05/20 21:46:45 bjax
++ * A little better logic on checking for option arguments.
++ *
++ * Revision 1.3.2.1 1994/05/20 19:29:51 bjax
++ * Added options arguments to command line.
++ *
++ * Revision 1.3.1.16 1994/05/17 15:08:45 bjax
++ * Corrected so that full name to directyr and file is saved
++ * in new global variable "fullname"; this allows symbol table
++ * to be extracted when in another default directory.
++ *
++ * Revision 1.3.1.15 1994/05/17 14:50:24 bjax
++ * Rebuilt LaRCsim
++ *
++ * Revision 1.3.1.14 1994/05/17 14:50:23 bjax
++ * Rebuilt LaRCsim
++ *
++ * Revision 1.3.1.13 1994/05/17 14:50:21 bjax
++ * Rebuilt LaRCsim
++ *
++ * Revision 1.3.1.12 1994/05/17 14:50:20 bjax
++ * Rebuilt LaRCsim
++ *
++ * Revision 1.3.1.11 1994/05/17 13:56:24 bjax
++ * Rebuilt LaRCsim
++ *
++ * Revision 1.3.1.10 1994/05/17 13:23:03 bjax
++ * Rebuilt LaRCsim
++ *
++ * Revision 1.3.1.9 1994/05/17 13:20:03 bjax
++ * Rebuilt LaRCsim
++ *
++ * Revision 1.3.1.8 1994/05/17 13:19:23 bjax
++ * Rebuilt LaRCsim
++ *
++ * Revision 1.3.1.7 1994/05/17 13:18:29 bjax
++ * Rebuilt LaRCsim
++ *
++ * Revision 1.3.1.6 1994/05/17 13:16:30 bjax
++ * Rebuilt LaRCsim
++ *
++ * Revision 1.3.1.5 1994/05/17 13:03:44 bjax
++ * Rebuilt LaRCsim
++ *
++ * Revision 1.3.1.4 1994/05/17 13:03:38 bjax
++ * Rebuilt LaRCsim
++ *
++ * Revision 1.3.1.3 1994/05/17 12:49:08 bjax
++ * Rebuilt LaRCsim
++ *
++ * Revision 1.3.1.2 1994/05/17 12:48:45 bjax
++ * *** empty log message ***
++ *
++ * Revision 1.3.1.1 1994/05/13 20:39:17 bjax
++ * Top of 1.3 branch.
++ *
++ * Revision 1.2 1994/05/13 19:51:50 bjax
++ * Skip rev
++ *
++
++----------------------------------------------------------------------------
++
++ REFERENCES:
++
++----------------------------------------------------------------------------
++
++ CALLED BY:
++
++----------------------------------------------------------------------------
++
++ CALLS TO:
++
++----------------------------------------------------------------------------
++
++ INPUTS:
++
++----------------------------------------------------------------------------
++
++ OUTPUTS:
++
++--------------------------------------------------------------------------*/
++
++/* #include <sys/types.h> */
++/* #include <sys/stat.h> */
++#include <stdlib.h>
++#include <stdio.h>
++#include <math.h>
++#include <time.h>
++
++#include "ls_types.h"
++#include "ls_constants.h"
++#include "ls_generic.h"
++#include "ls_sim_control.h"
++#include "ls_cockpit.h"
++#include "ls_interface.h"
++#include "ls_step.h"
++#include "ls_accel.h"
++#include "ls_aux.h"
++#include "ls_model.h"
++#include "ls_init.h"
++
++// #include <Flight/flight.h>
++// #include <Aircraft/aircraft.h>
++// #include <Debug/fg_debug.h>
++
++
++/* global variable declarations */
++
++/* TAPE *Tape; */
++GENERIC generic_;
++SIM_CONTROL sim_control_;
++COCKPIT cockpit_;
++
++SCALAR Simtime;
++
++#define DEFAULT_TERM_UPDATE_HZ 20
++#define DEFAULT_MODEL_HZ 120
++#define DEFAULT_END_TIME 3600.
++#define DEFAULT_SAVE_SPACING 8
++#define DEFAULT_WRITE_SPACING 1
++#define MAX_FILE_NAME_LENGTH 80
++
++/* global variables */
++
++char *progname;
++char *fullname;
++
++/* file variables - default simulation settings */
++
++static double model_dt;
++static double speedup;
++static char asc1name[MAX_FILE_NAME_LENGTH] = "run.asc1";
++static char tabname[MAX_FILE_NAME_LENGTH] = "run.dat";
++static char fltname[MAX_FILE_NAME_LENGTH] = "run.flt";
++static char matname[MAX_FILE_NAME_LENGTH] = "run.m";
++
++
++
++void ls_stamp( void ) {
++ char rcsid[] = "$Id$";
++ char revid[] = "$Revision$";
++ char dateid[] = "$Date$";
++ struct tm *nowtime;
++ time_t nowtime_t;
++ long date;
++
++ /* report version of LaRCsim*/
++ printf("\nLaRCsim %s, %s\n\n", revid, dateid);
++
++ nowtime_t = time( 0 );
++ nowtime = localtime( &nowtime_t ); /* set fields to correct time values */
++ date = (nowtime->tm_year)*10000
++ + (nowtime->tm_mon + 1)*100
++ + (nowtime->tm_mday);
++ sprintf(sim_control_.date_string, "%06d\0", date);
++ sprintf(sim_control_.time_stamp, "%02d:%02d:%02d\0",
++ nowtime->tm_hour, nowtime->tm_min, nowtime->tm_sec);
++#ifdef COMPILE_THIS_CODE_THIS_USELESS_CODE
++ cuserid( sim_control_.userid ); /* set up user id */
++#endif /* COMPILE_THIS_CODE_THIS_USELESS_CODE */
++ return;
++}
++
++void ls_setdefopts( void ) {
++ /* set default values for most options */
++
++ sim_control_.debug = 0; /* change to non-zero if in dbx! */
++ sim_control_.vision = 0;
++ sim_control_.write_av = 0; /* write Agile-Vu '.flt' file */
++ sim_control_.write_mat = 0; /* write matrix-x/matlab script */
++ sim_control_.write_tab = 0; /* write tab delim. history file */
++ sim_control_.write_asc1 = 0; /* write GetData file */
++ sim_control_.save_spacing = DEFAULT_SAVE_SPACING;
++ /* interpolation on recording */
++ sim_control_.write_spacing = DEFAULT_WRITE_SPACING;
++ /* interpolation on output */
++ sim_control_.end_time = DEFAULT_END_TIME;
++ sim_control_.model_hz = DEFAULT_MODEL_HZ;
++ sim_control_.term_update_hz = DEFAULT_TERM_UPDATE_HZ;
++ sim_control_.time_slices = (long int)(DEFAULT_END_TIME * DEFAULT_MODEL_HZ /
++ DEFAULT_SAVE_SPACING);
++ sim_control_.paused = 0;
++
++ speedup = 1.0;
++}
++
++
++/* return result codes from ls_checkopts */
++
++#define OPT_OK 0
++#define OPT_ERR 1
++
++#ifdef COMPILE_THIS_CODE_THIS_USELESS_CODE
++
++extern char *optarg;
++extern int optind;
++
++int ls_checkopts(argc, argv) /* check and set options flags */
++ int argc;
++ char *argv[];
++ {
++ int c;
++ int opt_err = 0;
++ int mod_end_time = 0;
++ int mod_buf_size = 0;
++ float buffer_time, data_rate;
++
++ /* set default values */
++
++ buffer_time = sim_control_.time_slices * sim_control_.save_spacing /
++ sim_control_.model_hz;
++ data_rate = sim_control_.model_hz / sim_control_.save_spacing;
++
++ while ((c = getopt(argc, argv, "Aa:b:de:f:hi:kmo:r:s:t:x:")) != EOF)
++ switch (c) {
++ case 'A':
++ if (sim_control_.sim_type == GLmouse)
++ {
++ fprintf(stderr, "Cannot specify both keyboard (k) and ACES (A) cockpits option\n");
++ fprintf(stderr, "Keyboard operation assumed.\n");
++ break;
++ }
++ sim_control_.sim_type = cockpit;
++ break;
++ case 'a':
++ sim_control_.write_av = 1;
++ if (optarg != NULL)
++ if (*optarg != '-')
++ strncpy(fltname, optarg, MAX_FILE_NAME_LENGTH);
++ else
++ optind--;
++ break;
++ case 'b':
++ buffer_time = atof(optarg);
++ if (buffer_time <= 0.) opt_err = -1;
++ mod_buf_size++;
++ break;
++ case 'd':
++ sim_control_.debug = 1;
++ break;
++ case 'e':
++ sim_control_.end_time = atof(optarg);
++ mod_end_time++;
++ break;
++ case 'f':
++ sim_control_.model_hz = atof(optarg);
++ break;
++ case 'h':
++ opt_err = 1;
++ break;
++ case 'i':
++ /* ls_get_settings( optarg ); */
++ break;
++ case 'k':
++ sim_control_.sim_type = GLmouse;
++ break;
++ case 'm':
++ sim_control_.vision = 1;
++ break;
++ case 'o':
++ sim_control_.term_update_hz = atof(optarg);
++ if (sim_control_.term_update_hz <= 0.) opt_err = 1;
++ break;
++ case 'r':
++ sim_control_.write_mat = 1;
++ if (optarg != NULL)
++ if (*optarg != '-')
++ strncpy(matname, optarg, MAX_FILE_NAME_LENGTH);
++ else
++ optind--;
++ break;
++ case 's':
++ data_rate = atof(optarg);
++ if (data_rate <= 0.) opt_err = -1;
++ break;
++ case 't':
++ sim_control_.write_tab = 1;
++ if (optarg != NULL)
++ if (*optarg != '-')
++ strncpy(tabname, optarg, MAX_FILE_NAME_LENGTH);
++ else
++ optind--;
++ break;
++ case 'x':
++ sim_control_.write_asc1 = 1;
++ if (optarg != NULL)
++ if (*optarg != '-')
++ strncpy(asc1name, optarg, MAX_FILE_NAME_LENGTH);
++ else
++ optind--;
++ break;
++ default:
++ opt_err = 1;
++
++ }
++
++ if (opt_err)
++ {
++ fprintf(stderr, "Usage: %s [-options]\n", progname);
++ fprintf(stderr, "\n");
++ fprintf(stderr, " where [-options] is zero or more of the following:\n");
++ fprintf(stderr, "\n");
++ fprintf(stderr, " [A|k] Run mode: [A]CES cockpit [default]\n");
++ fprintf(stderr, " or [k]eyboard\n");
++ fprintf(stderr, "\n");
++ fprintf(stderr, " [i <filename>] [i]nitial conditions filename\n");
++ fprintf(stderr, "\n");
++ fprintf(stderr, " [f <value>] Iteration rate [f]requency, Hz (default is %5.2f Hz)\n",
++ sim_control_.model_hz);
++ fprintf(stderr, "\n");
++ fprintf(stderr, " [o <value>] Display [o]utput frequency, Hz (default is %5.2f Hz)\n",
++ sim_control_.term_update_hz);
++ fprintf(stderr, "\n");
++ fprintf(stderr, " [s <value>] Data storage frequency, Hz (default is %5.2f Hz)\n",
++ data_rate);
++ fprintf(stderr, "\n");
++ fprintf(stderr, " [e <value>] [e]nd time in seconds (default %5.1f seconds)\n",
++ sim_control_.end_time);
++ fprintf(stderr, "\n");
++ fprintf(stderr, " [b <value>] circular time history storage [b]uffer size, in seconds \n");
++ fprintf(stderr, " (default %5.1f seconds) (normally same as end time)\n",
++ sim_control_.time_slices*sim_control_.save_spacing/
++ sim_control_.model_hz);
++ fprintf(stderr, "\n");
++ fprintf(stderr, " [atxr [<filename>]] Output: [a]gile-vu (default name: %s )\n", fltname);
++ fprintf(stderr, " and/or [t]ab delimited ( '' name: %s )\n", tabname);
++ fprintf(stderr, " and/or [x]plot (default name: %s)\n", asc1name);
++ fprintf(stderr, " and/or mat[r]ix script ( '' name: %s )\n", matname);
++ fprintf(stderr, "\n");
++ return OPT_ERR;
++ }
++
++/* calculate additional controls */
++
++ sim_control_.save_spacing = (int) (0.5 + sim_control_.model_hz / data_rate);
++ if (sim_control_.save_spacing < 1) sim_control_.save_spacing = 1;
++
++ sim_control_.time_slices = buffer_time * sim_control_.model_hz /
++ sim_control_.save_spacing;
++ if (sim_control_.time_slices < 2) sim_control_.time_slices = 2;
++
++ return OPT_OK;
++ }
++#endif /* COMPILE_THIS_CODE_THIS_USELESS_CODE */
++
++
++void ls_loop( SCALAR dt, int initialize ) {
++ /* printf (" In ls_loop()\n"); */
++ ls_step( dt, initialize );
++ /* if (sim_control_.sim_type == cockpit ) ls_ACES(); */
++ ls_aux();
++ ls_model( dt, initialize );
++ ls_accel();
++}
++
++
++
++int ls_cockpit( void ) {
++ // fgCONTROLS *c;
++
++ sim_control_.paused = 0;
++
++ // c = current_aircraft.controls;
++
++ // Lat_control = FG_Aileron;
++ // Long_control = FG_Elevator;
++ // Long_trim = FG_Elev_Trim;
++ // Rudder_pedal = FG_Rudder;
++ // Throttle_pct = FG_Throttle[0];
++
++ /* printf("Mach = %.2f ", Mach_number);
++ printf("%.4f,%.4f,%.2f ", Latitude, Longitude, Altitude);
++ printf("%.2f,%.2f,%.2f\n", Phi, Theta, Psi); */
++
++ return( 0 );
++}
++
++
++/* Initialize the LaRCsim flight model, dt is the time increment for
++ each subsequent iteration through the EOM */
++int ls_toplevel_init(double dt) {
++ model_dt = dt;
++
++ ls_setdefopts(); /* set default options */
++
++ ls_stamp(); /* ID stamp; record time and date of run */
++
++ if (speedup == 0.0) {
++ fprintf(stderr, "%s: Cannot run with speedup of 0.\n", progname);
++ return 1;
++ }
++
++ /* printf("LS pre Init pos = %.2f\n", Latitude); */
++
++ ls_init();
++
++ /* printf("LS post Init pos = %.2f\n", Latitude); */
++
++ if (speedup > 0) {
++ /* Initialize (get) cockpit (controls) settings */
++ ls_cockpit();
++ }
++
++ return(1);
++}
++
++
++/* Run an iteration of the EOM (equations of motion) */
++int ls_update(int multiloop) {
++ int i;
++
++ if (speedup > 0) {
++ ls_cockpit();
++ }
++
++ for ( i = 0; i < multiloop; i++ ) {
++ ls_loop( model_dt, 0);
++ }
++
++ return 1;
++}
++
++
++/* Set the altitude (force) */
++int ls_ForceAltitude(double alt_feet) {
++ Altitude = alt_feet;
++ ls_geod_to_geoc( Latitude, Altitude, &Sea_level_radius, &Lat_geocentric);
++ Radius_to_vehicle = Altitude + Sea_level_radius;
++}
++
++
++/* Flight Gear Modification Log
++ *
++ * $Log$
++ * Revision 1.25 1999/01/19 20:57:02 curt
++ * MacOS portability changes contributed by "Robert Puyol" <puyol@abvent.fr>
++ *
++ * Revision 1.24 1998/12/14 13:27:47 curt
++ * Removed some old, outdated, no longer needed code.
++ *
++ * Revision 1.23 1998/10/16 23:27:44 curt
++ * C++-ifying.
++ *
++ * Revision 1.22 1998/09/29 02:02:59 curt
++ * Added a brake + autopilot mods.
++ *
++ * Revision 1.21 1998/08/22 14:49:56 curt
++ * Attempting to iron out seg faults and crashes.
++ * Did some shuffling to fix a initialization order problem between view
++ * position, scenery elevation.
++ *
++ * Revision 1.20 1998/07/12 03:11:03 curt
++ * Removed some printf()'s.
++ * Fixed the autopilot integration so it should be able to update it's control
++ * positions every time the internal flight model loop is run, and not just
++ * once per rendered frame.
++ * Added a routine to do the necessary stuff to force an arbitrary altitude
++ * change.
++ * Gave the Navion engine just a tad more power.
++ *
++ * Revision 1.19 1998/05/11 18:17:28 curt
++ * Output message tweaking.
++ *
++ * Revision 1.18 1998/04/21 16:59:38 curt
++ * Integrated autopilot.
++ * Prepairing for C++ integration.
++ *
++ * Revision 1.17 1998/02/23 19:07:58 curt
++ * Incorporated Durk's Astro/ tweaks. Includes unifying the sun position
++ * calculation code between sun display, and other FG sections that use this
++ * for things like lighting.
++ *
++ * Revision 1.16 1998/02/07 15:29:38 curt
++ * Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++ * <chotchkiss@namg.us.anritsu.com>
++ *
++ * Revision 1.15 1998/01/22 22:03:47 curt
++ * Removed #include <sys/stat.h>
++ *
++ * Revision 1.14 1998/01/19 19:27:04 curt
++ * Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++ * This should simplify things tremendously.
++ *
++ * Revision 1.13 1998/01/19 18:40:26 curt
++ * Tons of little changes to clean up the code and to remove fatal errors
++ * when building with the c++ compiler.
++ *
++ * Revision 1.12 1998/01/06 01:20:16 curt
++ * Tweaks to help building with MSVC++
++ *
++ * Revision 1.11 1998/01/05 22:19:26 curt
++ * #ifdef'd out some unused code that was problematic for MSVC++ to compile.
++ *
++ * Revision 1.10 1997/12/10 22:37:43 curt
++ * Prepended "fg" on the name of all global structures that didn't have it yet.
++ * i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++ *
++ * Revision 1.9 1997/08/27 03:30:08 curt
++ * Changed naming scheme of basic shared structures.
++ *
++ * Revision 1.8 1997/06/21 17:12:50 curt
++ * Capitalized subdirectory names.
++ *
++ * Revision 1.7 1997/05/31 19:16:28 curt
++ * Elevator trim added.
++ *
++ * Revision 1.6 1997/05/31 04:13:53 curt
++ * WE CAN NOW FLY!!!
++ *
++ * Continuing work on the LaRCsim flight model integration.
++ * Added some MSFS-like keyboard input handling.
++ *
++ * Revision 1.5 1997/05/30 23:26:25 curt
++ * Added elevator/aileron controls.
++ *
++ * Revision 1.4 1997/05/30 19:30:15 curt
++ * The LaRCsim flight model is starting to look like it is working.
++ *
++ * Revision 1.3 1997/05/30 03:54:12 curt
++ * Made a bit more progress towards integrating the LaRCsim flight model.
++ *
++ * Revision 1.2 1997/05/29 22:39:59 curt
++ * Working on incorporating the LaRCsim flight model.
++ *
++ * Revision 1.1 1997/05/29 00:09:57 curt
++ * Initial Flight Gear revision.
++ *
++ */
--- /dev/null
--- /dev/null
++/**************************************************************************
++ * ls_interface.h -- interface to the "LaRCsim" flight model
++ *
++ * Written by Curtis Olson, started May 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$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++
++#ifndef _LS_INTERFACE_H
++#define _LS_INTERFACE_H
++
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++
++#include "ls_types.h"
++
++
++/* reset flight params to a specific position */
++int ls_toplevel_init(double dt);
++
++/* update position based on inputs, positions, velocities, etc. */
++int ls_update(int multiloop);
++
++#if 0
++/* Convert from the fgFLIGHT struct to the LaRCsim generic_ struct */
++int fgFlight_2_LaRCsim (fgFLIGHT *f);
++
++/* Convert from the LaRCsim generic_ struct to the fgFLIGHT struct */
++int fgLaRCsim_2_Flight (fgFLIGHT *f);
++
++void ls_loop( SCALAR dt, int initialize );
++#endif
++
++/* Set the altitude (force) */
++int ls_ForceAltitude(double alt_feet);
++
++
++#endif /* _LS_INTERFACE_H */
++
++
++#ifdef __cplusplus
++}
++#endif
++
++
++// $Log$
++// Revision 1.11 1998/10/17 01:34:15 curt
++// C++ ifying ...
++//
++// Revision 1.10 1998/10/16 23:27:45 curt
++// C++-ifying.
++//
++// Revision 1.9 1998/07/12 03:11:04 curt
++// Removed some printf()'s.
++// Fixed the autopilot integration so it should be able to update it's control
++// positions every time the internal flight model loop is run, and not just
++// once per rendered frame.
++// Added a routine to do the necessary stuff to force an arbitrary altitude
++// change.
++// Gave the Navion engine just a tad more power.
++//
++// Revision 1.8 1998/04/21 16:59:39 curt
++// Integrated autopilot.
++// Prepairing for C++ integration.
++//
++// Revision 1.7 1998/02/07 15:29:39 curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.6 1998/02/03 23:20:17 curt
++// Lots of little tweaks to fix various consistency problems discovered by
++// Solaris' CC. Fixed a bug in fg_debug.c with how the fgPrintf() wrapper
++// passed arguments along to the real printf(). Also incorporated HUD changes
++// by Michele America.
++//
++// Revision 1.5 1998/01/19 19:27:05 curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.4 1998/01/19 18:40:27 curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.3 1997/07/23 21:52:20 curt
++// Put comments around the text after an #endif for increased portability.
++//
++// Revision 1.2 1997/05/29 22:39:59 curt
++// Working on incorporating the LaRCsim flight model.
++//
++// Revision 1.1 1997/05/29 00:09:58 curt
++// Initial Flight Gear revision.
++//
--- /dev/null
--- /dev/null
++/***************************************************************************
++
++ TITLE: ls_matrix.c
++
++----------------------------------------------------------------------------
++
++ FUNCTION: general real matrix routines; includes
++ gaussj() for matrix inversion using
++ Gauss-Jordan method with full pivoting.
++
++ The routines in this module have come more or less from ref [1].
++ Note that, probably due to the heritage of ref [1] (which has a
++ FORTRAN version that was probably written first), the use of 1 as
++ the first element of an array (or vector) is used. This is accomplished
++ in memory by allocating, but not using, the 0 elements in each dimension.
++ While this wastes some memory, it allows the routines to be ported more
++ easily from FORTRAN (I suspect) as well as adhering to conventional
++ matrix notation. As a result, however, traditional ANSI C convention
++ (0-base indexing) is not followed; as the authors of ref [1] point out,
++ there is some question of the portability of the resulting routines
++ which sometimes access negative indexes. See ref [1] for more details.
++
++----------------------------------------------------------------------------
++
++ MODULE STATUS: developmental
++
++----------------------------------------------------------------------------
++
++ GENEALOGY: Created 950222 E. B. Jackson
++
++----------------------------------------------------------------------------
++
++ DESIGNED BY: from Numerical Recipes in C, by Press, et. al.
++
++ CODED BY: Bruce Jackson
++
++ MAINTAINED BY:
++
++----------------------------------------------------------------------------
++
++ MODIFICATION HISTORY:
++
++ DATE PURPOSE BY
++
++ CURRENT RCS HEADER:
++
++$Header$
++$Log$
++Revision 1.1 1998/06/27 22:34:57 curt
++Initial revision.
++
++ * Revision 1.1 1995/02/27 19:55:44 bjax
++ * Initial revision
++ *
++
++----------------------------------------------------------------------------
++
++ REFERENCES: [1] Press, William H., et. al, Numerical Recipes in
++ C, 2nd edition, Cambridge University Press, 1992
++
++----------------------------------------------------------------------------
++
++ CALLED BY:
++
++----------------------------------------------------------------------------
++
++ CALLS TO:
++
++----------------------------------------------------------------------------
++
++ INPUTS:
++
++----------------------------------------------------------------------------
++
++ OUTPUTS:
++
++--------------------------------------------------------------------------*/
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#include <stdlib.h>
++#include <stdio.h>
++#include <math.h>
++
++#ifdef HAVE_UNISTD_H
++# include <unistd.h>
++#endif
++
++#include "ls_matrix.h"
++
++
++#define SWAP(a,b) {temp=(a);(a)=(b);(b)=temp;}
++
++static char rcsid[] = "$Id$";
++
++
++int *nr_ivector(long nl, long nh)
++{
++ int *v;
++
++ v=(int *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(int)));
++ return v-nl+NR_END;
++}
++
++
++
++double **nr_matrix(long nrl, long nrh, long ncl, long nch)
++/* allocate a double matrix with subscript range m[nrl..nrh][ncl..nch] */
++{
++ long i, nrow=nrh-nrl+1, ncol=nch-ncl+1;
++ double **m;
++
++ /* allocate pointers to rows */
++ m=(double **) malloc((size_t)((nrow+NR_END)*sizeof(double*)));
++
++ if (!m)
++ {
++ fprintf(stderr, "Memory failure in routine 'nr_matrix'.\n");
++ exit(1);
++ }
++
++ m += NR_END;
++ m -= nrl;
++
++ /* allocate rows and set pointers to them */
++ m[nrl] = (double *) malloc((size_t)((nrow*ncol+NR_END)*sizeof(double)));
++ if (!m[nrl])
++ {
++ fprintf(stderr, "Memory failure in routine 'matrix'\n");
++ exit(1);
++ }
++
++ m[nrl] += NR_END;
++ m[nrl] -= ncl;
++
++ for (i=nrl+1;i<=nrh;i++) m[i]=m[i-1]+ncol;
++
++ /* return pointer to array of pointers to rows */
++ return m;
++}
++
++
++void nr_free_ivector(int *v, long nl /* , long nh */)
++{
++ free( (char *) (v+nl-NR_END));
++}
++
++
++void nr_free_matrix(double **m, long nrl, long nrh, long ncl, long nch)
++/* free a double matrix allocated by nr_matrix() */
++{
++ free((char *) (m[nrl]+ncl-NR_END));
++ free((char *) (m+nrl-NR_END));
++}
++
++
++int nr_gaussj(double **a, int n, double **b, int m)
++
++/* Linear equation solution by Gauss-Jordan elimination. a[1..n][1..n] is */
++/* the input matrix. b[1..n][1..m] is input containing the m right-hand */
++/* side vectors. On output, a is replaced by its matrix invers, and b is */
++/* replaced by the corresponding set of solution vectors. */
++
++/* Note: this routine modified by EBJ to make b optional, if m == 0 */
++
++{
++ int *indxc, *indxr, *ipiv;
++ int i, icol, irow, j, k, l, ll;
++ double big, dum, pivinv, temp;
++
++ int bexists = ((m != 0) || (b == 0));
++
++ indxc = nr_ivector(1,n); /* The integer arrays ipiv, indxr, and */
++ indxr = nr_ivector(1,n); /* indxc are used for pivot bookkeeping */
++ ipiv = nr_ivector(1,n);
++
++ for (j=1;j<=n;j++) ipiv[j] = 0;
++
++ for (i=1;i<=n;i++) /* This is the main loop over columns */
++ {
++ big = 0.0;
++ for (j=1;j<=n;j++) /* This is outer loop of pivot search */
++ if (ipiv[j] != 1)
++ for (k=1;k<=n;k++)
++ {
++ if (ipiv[k] == 0)
++ {
++ if (fabs(a[j][k]) >= big)
++ {
++ big = fabs(a[j][k]);
++ irow = j;
++ icol = k;
++ }
++ }
++ else
++ if (ipiv[k] > 1) return -1;
++ }
++ ++(ipiv[icol]);
++
++/* We now have the pivot element, so we interchange rows, if needed, */
++/* to put the pivot element on the diagonal. The columns are not */
++/* physically interchanged, only relabeled: indxc[i], the column of the */
++/* ith pivot element, is the ith column that is reduced, while indxr[i] */
++/* is the row in which that pivot element was orignally located. If */
++/* indxr[i] != indxc[i] there is an implied column interchange. With */
++/* this form of bookkeeping, the solution b's will end up in the correct */
++/* order, and the inverse matrix will be scrambed by columns. */
++
++ if (irow != icol)
++ {
++/* for (l=1;1<=n;l++) SWAP(a[irow][l],a[icol][l]) */
++ for (l=1;l<=n;l++)
++ {
++ temp=a[irow][l];
++ a[irow][l]=a[icol][l];
++ a[icol][l]=temp;
++ }
++ if (bexists) for (l=1;l<=m;l++) SWAP(b[irow][l],b[icol][l])
++ }
++ indxr[i] = irow; /* We are now ready to divide the pivot row */
++ indxc[i] = icol; /* by the pivot element, a[irow][icol] */
++ if (a[icol][icol] == 0.0) return -1;
++ pivinv = 1.0/a[icol][icol];
++ a[icol][icol] = 1.0;
++ for (l=1;l<=n;l++) a[icol][l] *= pivinv;
++ if (bexists) for (l=1;l<=m;l++) b[icol][l] *= pivinv;
++ for (ll=1;ll<=n;ll++) /* Next, we reduce the rows... */
++ if (ll != icol ) /* .. except for the pivot one */
++ {
++ dum = a[ll][icol];
++ a[ll][icol] = 0.0;
++ for (l=1;l<=n;l++) a[ll][l] -= a[icol][l]*dum;
++ if (bexists) for (l=1;l<=m;l++) b[ll][i] -= b[icol][l]*dum;
++ }
++ }
++
++/* This is the end of the mail loop over columns of the reduction. It
++ only remains to unscrambled the solution in view of the column
++ interchanges. We do this by interchanging pairs of columns in
++ the reverse order that the permutation was built up. */
++
++ for (l=n;l>=1;l--)
++ {
++ if (indxr[l] != indxc[l])
++ for (k=1;k<=n;k++)
++ SWAP(a[k][indxr[l]],a[k][indxc[l]])
++ }
++
++/* and we are done */
++
++ nr_free_ivector(ipiv,1 /*,n*/ );
++ nr_free_ivector(indxr,1 /*,n*/ );
++ nr_free_ivector(indxc,1 /*,n*/ );
++
++ return 0; /* indicate success */
++}
++
++void nr_copymat(double **orig, int n, double **copy)
++/* overwrites matrix 'copy' with copy of matrix 'orig' */
++{
++ long i, j;
++
++ if ((orig==0)||(copy==0)||(n==0)) return;
++
++ for (i=1;i<=n;i++)
++ for (j=1;j<=n;j++)
++ copy[i][j] = orig[i][j];
++}
++
++void nr_multmat(double **m1, int n, double **m2, double **prod)
++{
++ long i, j, k;
++
++ if ((m1==0)||(m2==0)||(prod==0)||(n==0)) return;
++
++ for (i=1;i<=n;i++)
++ for (j=1;j<=n;j++)
++ {
++ prod[i][j] = 0.0;
++ for(k=1;k<=n;k++) prod[i][j] += m1[i][k]*m2[k][j];
++ }
++}
++
++
++
++void nr_printmat(double **a, int n)
++{
++ int i,j;
++
++ printf("\n");
++ for(i=1;i<=n;i++)
++ {
++ for(j=1;j<=n;j++)
++ printf("% 9.4f ", a[i][j]);
++ printf("\n");
++ }
++ printf("\n");
++
++}
++
++
++void testmat( void ) /* main() for test purposes */
++{
++ double **mat1, **mat2, **mat3;
++ double invmaxlong;
++ int loop, i, j, n = 20;
++ long maxlong = RAND_MAX;
++ int maxloop = 2;
++
++ invmaxlong = 1.0/(double)maxlong;
++ mat1 = nr_matrix(1, n, 1, n );
++ mat2 = nr_matrix(1, n, 1, n );
++ mat3 = nr_matrix(1, n, 1, n );
++
++/* for(i=1;i<=n;i++) mat1[i][i]= 5.0; */
++
++ for(loop=0;loop<maxloop;loop++)
++ {
++ if (loop != 0)
++ for(i=1;i<=n;i++)
++ for(j=1;j<=n;j++)
++ mat1[i][j] = 2.0 - 4.0*invmaxlong*(double) rand();
++
++ printf("Original matrix:\n");
++ nr_printmat( mat1, n );
++
++ nr_copymat( mat1, n, mat2 );
++
++ i = nr_gaussj( mat2, n, 0, 0 );
++
++ if (i) printf("Singular matrix.\n");
++
++ printf("Inverted matrix:\n");
++ nr_printmat( mat2, n );
++
++ nr_multmat( mat1, n, mat2, mat3 );
++
++ printf("Original multiplied by inverse:\n");
++ nr_printmat( mat3, n );
++
++ if (loop < maxloop-1) /* sleep(1) */;
++ }
++
++ nr_free_matrix( mat1, 1, n, 1, n );
++ nr_free_matrix( mat2, 1, n, 1, n );
++ nr_free_matrix( mat3, 1, n, 1, n );
++}
--- /dev/null
--- /dev/null
++/***************************************************************************
++
++ TITLE: ls_matrix.h
++
++----------------------------------------------------------------------------
++
++ FUNCTION: Header file for general real matrix routines.
++
++ The routines in this module have come more or less from ref [1].
++ Note that, probably due to the heritage of ref [1] (which has a
++ FORTRAN version that was probably written first), the use of 1 as
++ the first element of an array (or vector) is used. This is accomplished
++ in memory by allocating, but not using, the 0 elements in each dimension.
++ While this wastes some memory, it allows the routines to be ported more
++ easily from FORTRAN (I suspect) as well as adhering to conventional
++ matrix notation. As a result, however, traditional ANSI C convention
++ (0-base indexing) is not followed; as the authors of ref [1] point out,
++ there is some question of the portability of the resulting routines
++ which sometimes access negative indexes. See ref [1] for more details.
++
++----------------------------------------------------------------------------
++
++ MODULE STATUS: developmental
++
++----------------------------------------------------------------------------
++
++ GENEALOGY: Created 950222 E. B. Jackson
++
++----------------------------------------------------------------------------
++
++ DESIGNED BY: from Numerical Recipes in C, by Press, et. al.
++
++ CODED BY: Bruce Jackson
++
++ MAINTAINED BY:
++
++----------------------------------------------------------------------------
++
++ MODIFICATION HISTORY:
++
++ DATE PURPOSE BY
++
++ CURRENT RCS HEADER:
++
++$Header$
++$Log$
++Revision 1.1 1998/06/27 22:34:58 curt
++Initial revision.
++
++ * Revision 1.1 1995/02/27 20:02:18 bjax
++ * Initial revision
++ *
++
++----------------------------------------------------------------------------
++
++ REFERENCES: [1] Press, William H., et. al, Numerical Recipes in
++ C, 2nd edition, Cambridge University Press, 1992
++
++----------------------------------------------------------------------------
++
++ CALLED BY:
++
++----------------------------------------------------------------------------
++
++ CALLS TO:
++
++----------------------------------------------------------------------------
++
++ INPUTS:
++
++----------------------------------------------------------------------------
++
++ OUTPUTS:
++
++--------------------------------------------------------------------------*/
++#include <stdlib.h>
++#include <stdio.h>
++#include <math.h>
++
++#define NR_END 1
++
++/* matrix creation & destruction routines */
++
++int *nr_ivector(long nl, long nh);
++double **nr_matrix(long nrl, long nrh, long ncl, long nch);
++
++void nr_free_ivector(int *v, long nl /* , long nh */);
++void nr_free_matrix(double **m, long nrl, long nrh, long ncl, long nch);
++
++
++/* Gauss-Jordan inversion routine */
++
++int nr_gaussj(double **a, int n, double **b, int m);
++
++/* Linear equation solution by Gauss-Jordan elimination. a[1..n][1..n] is */
++/* the input matrix. b[1..n][1..m] is input containing the m right-hand */
++/* side vectors. On output, a is replaced by its matrix invers, and b is */
++/* replaced by the corresponding set of solution vectors. */
++
++/* Note: this routine modified by EBJ to make b optional, if m == 0 */
++
++/* Matrix copy, multiply, and printout routines (by EBJ) */
++
++void nr_copymat(double **orig, int n, double **copy);
++void nr_multmat(double **m1, int n, double **m2, double **prod);
++void nr_printmat(double **a, int n);
++
++
--- /dev/null
--- /dev/null
++/***************************************************************************
++
++ TITLE: ls_model()
++
++----------------------------------------------------------------------------
++
++ FUNCTION: Model loop executive
++
++----------------------------------------------------------------------------
++
++ MODULE STATUS: developmental
++
++----------------------------------------------------------------------------
++
++ GENEALOGY: Created 15 October 1992 as part of LaRCSIM project
++ by Bruce Jackson.
++
++----------------------------------------------------------------------------
++
++ DESIGNED BY: Bruce Jackson
++
++ CODED BY: Bruce Jackson
++
++ MAINTAINED BY: maintainer
++
++----------------------------------------------------------------------------
++
++ MODIFICATION HISTORY:
++
++ DATE PURPOSE BY
++
++ 950306 Added parameters to call: dt, which is the step size
++ to be taken this loop (caution: may vary from call to call)
++ and Initialize, which if non-zero, implies an initialization
++ is requested. EBJ
++
++ CURRENT RCS HEADER INFO:
++$Header$
++$Log$
++Revision 1.3 1998/08/06 12:46:39 curt
++Header change.
++
++Revision 1.2 1998/01/19 18:40:27 curt
++Tons of little changes to clean up the code and to remove fatal errors
++when building with the c++ compiler.
++
++Revision 1.1 1997/05/29 00:09:58 curt
++Initial Flight Gear revision.
++
++ * Revision 1.3 1995/03/06 18:49:46 bjax
++ * Added dt and initialize flag parameters to subroutine calls. This will
++ * support trim routine (to allow single throttle setting to drive
++ * all four throttle positions, for example, if initialize is TRUE).
++ *
++ * Revision 1.2 1993/03/10 06:38:09 bjax
++ * Added additional calls: inertias() and subsystems()... EBJ
++ *
++ * Revision 1.1 92/12/30 13:19:08 bjax
++ * Initial revision
++ *
++
++----------------------------------------------------------------------------
++
++ REFERENCES:
++
++----------------------------------------------------------------------------
++
++ CALLED BY: ls_step (in initialization), ls_loop (planned)
++
++----------------------------------------------------------------------------
++
++ CALLS TO: aero(), engine(), gear()
++
++----------------------------------------------------------------------------
++
++ INPUTS:
++
++----------------------------------------------------------------------------
++
++ OUTPUTS:
++
++--------------------------------------------------------------------------*/
++#include "ls_types.h"
++#include "ls_model.h"
++#include "default_model_routines.h"
++
++
++void ls_model( SCALAR dt, int Initialize ) {
++ inertias( dt, Initialize );
++ subsystems( dt, Initialize );
++ aero( dt, Initialize );
++ engine( dt, Initialize );
++ gear( dt, Initialize );
++}
--- /dev/null
--- /dev/null
++/* a quick ls_model.h */
++
++
++#ifndef _LS_MODEL_H
++#define _LS_MODEL_H
++
++
++void ls_model( SCALAR dt, int Initialize );
++
++
++#endif /* _LS_MODEL_H */
--- /dev/null
--- /dev/null
++/***************************************************************************
++
++ TITLE: ls_sim_control.h
++
++----------------------------------------------------------------------------
++
++ FUNCTION: LaRCSim simulation control parameters header file
++
++----------------------------------------------------------------------------
++
++ MODULE STATUS: developmental
++
++----------------------------------------------------------------------------
++
++ GENEALOGY: Created 18 DEC 1993 by Bruce Jackson
++
++----------------------------------------------------------------------------
++
++ DESIGNED BY: B. Jackson
++
++ CODED BY: B. Jackson
++
++ MAINTAINED BY: guess who
++
++----------------------------------------------------------------------------
++
++ MODIFICATION HISTORY:
++
++ DATE PURPOSE BY
++
++ 940204 Added "overrun" flag to indicate non-real-time frame.
++ 940210 Added "vision" flag to indicate use of shared memory.
++ 940513 Added "max_tape_channels" and "max_time_slices" EBJ
++ 950308 Increased size of time_stamp and date_string to include
++ terminating null char. EBJ
++ 950314 Addedf "paused" flag to make this global (was local to
++ ls_cockpit routine). EBJ
++ 950406 Removed tape_channels parameter, and added end_time, model_hz,
++ and term_update_hz parameters. EBJ
++
++$Header$
++$Log$
++Revision 1.4 1998/08/06 12:46:39 curt
++Header change.
++
++Revision 1.3 1998/01/22 02:59:33 curt
++Changed #ifdef FILE_H to #ifdef _FILE_H
++
++Revision 1.2 1998/01/06 01:20:17 curt
++Tweaks to help building with MSVC++
++
++Revision 1.1 1997/05/29 00:09:59 curt
++Initial Flight Gear revision.
++
++ * Revision 1.11 1995/04/07 01:39:09 bjax
++ * Removed tape_channels and added end_time, model_hz, and term_update_hz.
++ *
++ * Revision 1.10 1995/03/15 12:33:29 bjax
++ * Added 'paused' flag.
++ *
++ * Revision 1.9 1995/03/08 12:34:21 bjax
++ * Increased size of date_string and time_stamp by 1 to include terminating null;
++ * added userid field and include of stdio.h. EBJ
++ *
++ * Revision 1.8 1994/05/13 20:41:43 bjax
++ * Increased size of time_stamp to 8 chars to allow for colons.
++ * Added fields "tape_channels" and "time_slices" to allow user to change.
++ *
++ * Revision 1.7 1994/05/10 15:18:49 bjax
++ * Modified write_cmp2 flag to write_asc1 flag, since XPLOT 4.00 doesn't
++ * support cmp2. Also added RCS header and log entries in header.
++ *
++
++
++--------------------------------------------------------------------------*/
++
++
++#ifndef _LS_SIM_CONTROL_H
++#define _LS_SIM_CONTROL_H
++
++
++#include <stdio.h>
++
++#ifndef SIM_CONTROL
++
++typedef struct {
++
++ enum { batch, terminal, GLmouse, cockpit } sim_type;
++ char simname[64]; /* name of simulation */
++ int run_number; /* run number of this session */
++ char date_string[7]; /* like "931220" */
++ char time_stamp[9]; /* like "13:00:00" */
++#ifdef COMPILE_THIS_CODE_THIS_USELESS_CODE
++ char userid[L_cuserid]; /* who is running this sim */
++#endif /* COMPILE_THIS_CODE_THIS_USELESS_CODE */
++ long time_slices; /* number of points that can be recorded (circ buff) */
++ int write_av; /* will be writing out an Agile_VU file after run */
++ int write_mat; /* will be writing out a matrix script of session */
++ int write_tab; /* will be writing out a tab-delimited time history */
++ int write_asc1; /* will be writing out a GetData ASCII 1 file */
++ int save_spacing; /* spacing between data points when recording
++ data to memory; 0 = every point, 1 = every
++ other point; 2 = every fourth point, etc. */
++ int write_spacing; /* spacing between data points when writing
++ output files; 0 = every point, 1 = every
++ other point; 2 = every fourth point, etc. */
++ int overrun; /* indicates, if non-zero, a frame overrun
++ occurred in the previous frame. Suitable for
++ setting a display flag or writing an error
++ message. */
++ int vision; /* indicates, if non-zero, marriage to LaRC VISION
++ software (developed A. Dare and J. Burley of the
++ former Cockpit Technologies Branch) */
++ int debug; /* indicates, if non-zero, to operate in debug mode
++ which implies disable double-buffering and synch.
++ attempts to avoid errors */
++ int paused; /* indicates simulation is paused */
++ float end_time; /* end of simulation run value */
++ float model_hz; /* current inner loop frame rate */
++ float term_update_hz; /* current terminal refresh frequency */
++
++} SIM_CONTROL;
++
++extern SIM_CONTROL sim_control_;
++
++#endif
++
++
++#endif /* _LS_SIM_CONTROL_H */
++
++
++/*------------------------ end of ls_sim_control.h ----------------------*/
--- /dev/null
--- /dev/null
++/***************************************************************************
++
++ TITLE: ls_step
++
++----------------------------------------------------------------------------
++
++ FUNCTION: Integration routine for equations of motion
++ (vehicle states)
++
++----------------------------------------------------------------------------
++
++ MODULE STATUS: developmental
++
++----------------------------------------------------------------------------
++
++ GENEALOGY: Written 920802 by Bruce Jackson. Based upon equations
++ given in reference [1] and a Matrix-X/System Build block
++ diagram model of equations of motion coded by David Raney
++ at NASA-Langley in June of 1992.
++
++----------------------------------------------------------------------------
++
++ DESIGNED BY: Bruce Jackson
++
++ CODED BY: Bruce Jackson
++
++ MAINTAINED BY:
++
++----------------------------------------------------------------------------
++
++ MODIFICATION HISTORY:
++
++ DATE PURPOSE BY
++
++ 921223 Modified calculation of Phi and Psi to use the "atan2" routine
++ rather than the "atan" to allow full circular angles.
++ "atan" limits to +/- pi/2. EBJ
++
++ 940111 Changed from oldstyle include file ls_eom.h; also changed
++ from DATA to SCALAR type. EBJ
++
++ 950207 Initialized Alpha_dot and Beta_dot to zero on first pass; calculated
++ thereafter. EBJ
++
++ 950224 Added logic to avoid adding additional increment to V_east
++ in case V_east already accounts for rotating earth.
++ EBJ
++
++ CURRENT RCS HEADER:
++
++$Header$
++$Log$
++Revision 1.4 1998/08/24 20:09:27 curt
++Code optimization tweaks from Norman Vine.
++
++Revision 1.3 1998/07/12 03:11:04 curt
++Removed some printf()'s.
++Fixed the autopilot integration so it should be able to update it's control
++ positions every time the internal flight model loop is run, and not just
++ once per rendered frame.
++Added a routine to do the necessary stuff to force an arbitrary altitude
++ change.
++Gave the Navion engine just a tad more power.
++
++Revision 1.2 1998/01/19 18:40:28 curt
++Tons of little changes to clean up the code and to remove fatal errors
++when building with the c++ compiler.
++
++Revision 1.1 1997/05/29 00:09:59 curt
++Initial Flight Gear revision.
++
++ * Revision 1.5 1995/03/02 20:24:13 bjax
++ * Added logic to avoid adding additional increment to V_east
++ * in case V_east already accounts for rotating earth. EBJ
++ *
++ * Revision 1.4 1995/02/07 20:52:21 bjax
++ * Added initialization of Alpha_dot and Beta_dot to zero on first
++ * pass; they get calculated by ls_aux on next pass... EBJ
++ *
++ * Revision 1.3 1994/01/11 19:01:12 bjax
++ * Changed from DATA to SCALAR type; also fixed header files (was ls_eom.h)
++ *
++ * Revision 1.2 1993/06/02 15:03:09 bjax
++ * Moved initialization of geocentric position to subroutine ls_geod_to_geoc.
++ *
++ * Revision 1.1 92/12/30 13:16:11 bjax
++ * Initial revision
++ *
++
++----------------------------------------------------------------------------
++
++ REFERENCES:
++
++ [ 1] McFarland, Richard E.: "A Standard Kinematic Model
++ for Flight Simulation at NASA-Ames", NASA CR-2497,
++ January 1975
++
++ [ 2] ANSI/AIAA R-004-1992 "Recommended Practice: Atmos-
++ pheric and Space Flight Vehicle Coordinate Systems",
++ February 1992
++
++
++----------------------------------------------------------------------------
++
++ CALLED BY:
++
++----------------------------------------------------------------------------
++
++ CALLS TO: None.
++
++----------------------------------------------------------------------------
++
++ INPUTS: State derivatives
++
++----------------------------------------------------------------------------
++
++ OUTPUTS: States
++
++--------------------------------------------------------------------------*/
++
++#include "ls_types.h"
++#include "ls_constants.h"
++#include "ls_generic.h"
++#include "ls_accel.h"
++#include "ls_aux.h"
++#include "ls_model.h"
++#include "ls_step.h"
++#include "ls_geodesy.h"
++#include "ls_gravity.h"
++/* #include "ls_sim_control.h" */
++#include <math.h>
++
++extern SCALAR Simtime; /* defined in ls_main.c */
++
++void ls_step( SCALAR dt, int Initialize ) {
++ static int inited = 0;
++ SCALAR dth;
++ static SCALAR v_dot_north_past, v_dot_east_past, v_dot_down_past;
++ static SCALAR latitude_dot_past, longitude_dot_past, radius_dot_past;
++ static SCALAR p_dot_body_past, q_dot_body_past, r_dot_body_past;
++ SCALAR p_local_in_body, q_local_in_body, r_local_in_body;
++ SCALAR epsilon, inv_eps, local_gnd_veast;
++ SCALAR e_dot_0, e_dot_1, e_dot_2, e_dot_3;
++ static SCALAR e_0, e_1, e_2, e_3;
++ static SCALAR e_dot_0_past, e_dot_1_past, e_dot_2_past, e_dot_3_past;
++ SCALAR cos_Lat_geocentric, inv_Radius_to_vehicle;
++
++/* I N I T I A L I Z A T I O N */
++
++
++ if ( (inited == 0) || (Initialize != 0) )
++ {
++/* Set past values to zero */
++ v_dot_north_past = v_dot_east_past = v_dot_down_past = 0;
++ latitude_dot_past = longitude_dot_past = radius_dot_past = 0;
++ p_dot_body_past = q_dot_body_past = r_dot_body_past = 0;
++ e_dot_0_past = e_dot_1_past = e_dot_2_past = e_dot_3_past = 0;
++
++/* Initialize geocentric position from geodetic latitude and altitude */
++
++ ls_geod_to_geoc( Latitude, Altitude, &Sea_level_radius, &Lat_geocentric);
++ Earth_position_angle = 0;
++ Lon_geocentric = Longitude;
++ Radius_to_vehicle = Altitude + Sea_level_radius;
++
++/* Correct eastward velocity to account for earths' rotation, if necessary */
++
++ local_gnd_veast = OMEGA_EARTH*Sea_level_radius*cos(Lat_geocentric);
++ if( fabs(V_east - V_east_rel_ground) < 0.8*local_gnd_veast )
++ V_east = V_east + local_gnd_veast;
++
++/* Initialize quaternions and transformation matrix from Euler angles */
++
++ e_0 = cos(Psi*0.5)*cos(Theta*0.5)*cos(Phi*0.5)
++ + sin(Psi*0.5)*sin(Theta*0.5)*sin(Phi*0.5);
++ e_1 = cos(Psi*0.5)*cos(Theta*0.5)*sin(Phi*0.5)
++ - sin(Psi*0.5)*sin(Theta*0.5)*cos(Phi*0.5);
++ e_2 = cos(Psi*0.5)*sin(Theta*0.5)*cos(Phi*0.5)
++ + sin(Psi*0.5)*cos(Theta*0.5)*sin(Phi*0.5);
++ e_3 =-cos(Psi*0.5)*sin(Theta*0.5)*sin(Phi*0.5)
++ + sin(Psi*0.5)*cos(Theta*0.5)*cos(Phi*0.5);
++ T_local_to_body_11 = e_0*e_0 + e_1*e_1 - e_2*e_2 - e_3*e_3;
++ T_local_to_body_12 = 2*(e_1*e_2 + e_0*e_3);
++ T_local_to_body_13 = 2*(e_1*e_3 - e_0*e_2);
++ T_local_to_body_21 = 2*(e_1*e_2 - e_0*e_3);
++ T_local_to_body_22 = e_0*e_0 - e_1*e_1 + e_2*e_2 - e_3*e_3;
++ T_local_to_body_23 = 2*(e_2*e_3 + e_0*e_1);
++ T_local_to_body_31 = 2*(e_1*e_3 + e_0*e_2);
++ T_local_to_body_32 = 2*(e_2*e_3 - e_0*e_1);
++ T_local_to_body_33 = e_0*e_0 - e_1*e_1 - e_2*e_2 + e_3*e_3;
++
++/* Calculate local gravitation acceleration */
++
++ ls_gravity( Radius_to_vehicle, Lat_geocentric, &Gravity );
++
++/* Initialize vehicle model */
++
++ ls_aux();
++ ls_model(0.0, 0);
++
++/* Calculate initial accelerations */
++
++ ls_accel();
++
++/* Initialize auxiliary variables */
++
++ ls_aux();
++ Alpha_dot = 0.;
++ Beta_dot = 0.;
++
++/* set flag; disable integrators */
++
++ inited = -1;
++ dt = 0;
++
++ }
++
++/* Update time */
++
++ dth = 0.5*dt;
++ Simtime = Simtime + dt;
++
++/* L I N E A R V E L O C I T I E S */
++
++/* Integrate linear accelerations to get velocities */
++/* Using predictive Adams-Bashford algorithm */
++
++ V_north = V_north + dth*(3*V_dot_north - v_dot_north_past);
++ V_east = V_east + dth*(3*V_dot_east - v_dot_east_past );
++ V_down = V_down + dth*(3*V_dot_down - v_dot_down_past );
++
++/* record past states */
++
++ v_dot_north_past = V_dot_north;
++ v_dot_east_past = V_dot_east;
++ v_dot_down_past = V_dot_down;
++
++/* Calculate trajectory rate (geocentric coordinates) */
++
++ inv_Radius_to_vehicle = 1.0/Radius_to_vehicle;
++ cos_Lat_geocentric = cos(Lat_geocentric);
++
++ if ( cos_Lat_geocentric != 0) {
++ Longitude_dot = V_east/(Radius_to_vehicle*cos_Lat_geocentric);
++ }
++
++ Latitude_dot = V_north*inv_Radius_to_vehicle;
++ Radius_dot = -V_down;
++
++/* A N G U L A R V E L O C I T I E S A N D P O S I T I O N S */
++
++/* Integrate rotational accelerations to get velocities */
++
++ P_body = P_body + dth*(3*P_dot_body - p_dot_body_past);
++ Q_body = Q_body + dth*(3*Q_dot_body - q_dot_body_past);
++ R_body = R_body + dth*(3*R_dot_body - r_dot_body_past);
++
++/* Save past states */
++
++ p_dot_body_past = P_dot_body;
++ q_dot_body_past = Q_dot_body;
++ r_dot_body_past = R_dot_body;
++
++/* Calculate local axis frame rates due to travel over curved earth */
++
++ P_local = V_east*inv_Radius_to_vehicle;
++ Q_local = -V_north*inv_Radius_to_vehicle;
++ R_local = -V_east*tan(Lat_geocentric)*inv_Radius_to_vehicle;
++
++/* Transform local axis frame rates to body axis rates */
++
++ p_local_in_body = T_local_to_body_11*P_local + T_local_to_body_12*Q_local + T_local_to_body_13*R_local;
++ q_local_in_body = T_local_to_body_21*P_local + T_local_to_body_22*Q_local + T_local_to_body_23*R_local;
++ r_local_in_body = T_local_to_body_31*P_local + T_local_to_body_32*Q_local + T_local_to_body_33*R_local;
++
++/* Calculate total angular rates in body axis */
++
++ P_total = P_body - p_local_in_body;
++ Q_total = Q_body - q_local_in_body;
++ R_total = R_body - r_local_in_body;
++
++/* Transform to quaternion rates (see Appendix E in [2]) */
++
++ e_dot_0 = 0.5*( -P_total*e_1 - Q_total*e_2 - R_total*e_3 );
++ e_dot_1 = 0.5*( P_total*e_0 - Q_total*e_3 + R_total*e_2 );
++ e_dot_2 = 0.5*( P_total*e_3 + Q_total*e_0 - R_total*e_1 );
++ e_dot_3 = 0.5*( -P_total*e_2 + Q_total*e_1 + R_total*e_0 );
++
++/* Integrate using trapezoidal as before */
++
++ e_0 = e_0 + dth*(e_dot_0 + e_dot_0_past);
++ e_1 = e_1 + dth*(e_dot_1 + e_dot_1_past);
++ e_2 = e_2 + dth*(e_dot_2 + e_dot_2_past);
++ e_3 = e_3 + dth*(e_dot_3 + e_dot_3_past);
++
++/* calculate orthagonality correction - scale quaternion to unity length */
++
++ epsilon = sqrt(e_0*e_0 + e_1*e_1 + e_2*e_2 + e_3*e_3);
++ inv_eps = 1/epsilon;
++
++ e_0 = inv_eps*e_0;
++ e_1 = inv_eps*e_1;
++ e_2 = inv_eps*e_2;
++ e_3 = inv_eps*e_3;
++
++/* Save past values */
++
++ e_dot_0_past = e_dot_0;
++ e_dot_1_past = e_dot_1;
++ e_dot_2_past = e_dot_2;
++ e_dot_3_past = e_dot_3;
++
++/* Update local to body transformation matrix */
++
++ T_local_to_body_11 = e_0*e_0 + e_1*e_1 - e_2*e_2 - e_3*e_3;
++ T_local_to_body_12 = 2*(e_1*e_2 + e_0*e_3);
++ T_local_to_body_13 = 2*(e_1*e_3 - e_0*e_2);
++ T_local_to_body_21 = 2*(e_1*e_2 - e_0*e_3);
++ T_local_to_body_22 = e_0*e_0 - e_1*e_1 + e_2*e_2 - e_3*e_3;
++ T_local_to_body_23 = 2*(e_2*e_3 + e_0*e_1);
++ T_local_to_body_31 = 2*(e_1*e_3 + e_0*e_2);
++ T_local_to_body_32 = 2*(e_2*e_3 - e_0*e_1);
++ T_local_to_body_33 = e_0*e_0 - e_1*e_1 - e_2*e_2 + e_3*e_3;
++
++/* Calculate Euler angles */
++
++ Theta = asin( -T_local_to_body_13 );
++
++ if( T_local_to_body_11 == 0 )
++ Psi = 0;
++ else
++ Psi = atan2( T_local_to_body_12, T_local_to_body_11 );
++
++ if( T_local_to_body_33 == 0 )
++ Phi = 0;
++ else
++ Phi = atan2( T_local_to_body_23, T_local_to_body_33 );
++
++/* Resolve Psi to 0 - 359.9999 */
++
++ if (Psi < 0 ) Psi = Psi + 2*PI;
++
++/* L I N E A R P O S I T I O N S */
++
++/* Trapezoidal acceleration for position */
++
++ Lat_geocentric = Lat_geocentric + dth*(Latitude_dot + latitude_dot_past );
++ Lon_geocentric = Lon_geocentric + dth*(Longitude_dot + longitude_dot_past);
++ Radius_to_vehicle = Radius_to_vehicle + dth*(Radius_dot + radius_dot_past );
++ Earth_position_angle = Earth_position_angle + dt*OMEGA_EARTH;
++
++/* Save past values */
++
++ latitude_dot_past = Latitude_dot;
++ longitude_dot_past = Longitude_dot;
++ radius_dot_past = Radius_dot;
++
++/* end of ls_step */
++}
++/*************************************************************************/
++
--- /dev/null
--- /dev/null
++/* a quick ls_step.h */
++
++
++#ifndef _LS_STEP_H
++#define _LS_STEP_H
++
++
++void ls_step( SCALAR dt, int Initialize );
++
++
++#endif /* _LS_STEP_H */
--- /dev/null
--- /dev/null
++/***************************************************************************
++
++ TITLE: ls_sym.h
++
++----------------------------------------------------------------------------
++
++ FUNCTION: Header file for symbol table routines
++
++----------------------------------------------------------------------------
++
++ MODULE STATUS: production
++
++----------------------------------------------------------------------------
++
++ GENEALOGY: Created 930629 by E. B. Jackson
++
++----------------------------------------------------------------------------
++
++ DESIGNED BY: Bruce Jackson
++
++ CODED BY: same
++
++ MAINTAINED BY:
++
++----------------------------------------------------------------------------
++
++ MODIFICATION HISTORY:
++
++ DATE PURPOSE BY
++
++ 950227 Added header and declarations for ls_print_findsym_error(),
++ ls_get_double(), and ls_get_double() routines. EBJ
++
++ 950302 Added structure for symbol description. EBJ
++
++ 950306 Added ls_get_sym_val() and ls_set_sym_val() routines.
++ This is now the production version. EBJ
++
++ CURRENT RCS HEADER:
++
++$Header$
++$Log$
++Revision 1.3 1998/08/06 12:46:40 curt
++Header change.
++
++Revision 1.2 1998/01/22 02:59:34 curt
++Changed #ifdef FILE_H to #ifdef _FILE_H
++
++Revision 1.1 1997/05/29 00:10:00 curt
++Initial Flight Gear revision.
++
++ * Revision 1.9 1995/03/07 12:52:33 bjax
++ * This production version now specified ls_get_sym_val() and ls_put_sym_val().
++ *
++ * Revision 1.6.1.2 1995/03/06 18:45:41 bjax
++ * Added def'n of ls_get_sym_val() and ls_set_sym_val(); changed symbol_rec
++ * Addr field from void * to char *.
++ * EBJ
++ *
++ * Revision 1.6.1.1 1995/03/03 01:17:44 bjax
++ * Experimental version with just ls_get_double and ls_set_double() routines.
++ *
++ * Revision 1.6 1995/02/27 19:50:49 bjax
++ * Added header and declarations for ls_print_findsym_error(),
++ * ls_get_double(), and ls_set_double(). EBJ
++ *
++
++----------------------------------------------------------------------------
++
++ REFERENCES:
++
++----------------------------------------------------------------------------
++
++ CALLED BY:
++
++----------------------------------------------------------------------------
++
++ CALLS TO:
++
++----------------------------------------------------------------------------
++
++ INPUTS:
++
++----------------------------------------------------------------------------
++
++ OUTPUTS:
++
++--------------------------------------------------------------------------*/
++
++#ifndef _LS_SYM_H
++#define _LS_SYM_H
++
++
++/* Return codes */
++
++#define SYM_NOT_LOADED -2
++#define SYM_UNEXPECTED_ERR -1
++#define SYM_OK 0
++#define SYM_OPEN_ERR 1
++#define SYM_NO_SYMS 2
++#define SYM_MOD_NOT_FOUND 3
++#define SYM_VAR_NOT_FOUND 4
++#define SYM_NOT_SCALAR 5
++#define SYM_NOT_STATIC 6
++#define SYM_MEMORY_ERR 7
++#define SYM_UNMATCHED_PAREN 8
++#define SYM_BAD_SYNTAX 9
++#define SYM_INDEX_BOUNDS_ERR 10
++
++typedef enum {Unknown, Char, UChar, SHint, USHint, Sint, Uint, Slng, Ulng, flt, dbl} vartype;
++
++typedef char SYMBOL_NAME[64];
++typedef vartype SYMBOL_TYPE;
++
++
++
++typedef struct
++{
++ SYMBOL_NAME Mod_Name;
++ SYMBOL_NAME Par_Name;
++ SYMBOL_TYPE Par_Type;
++ SYMBOL_NAME Alias;
++ char *Addr;
++} symbol_rec;
++
++
++extern int ls_findsym( const char *modname, const char *varname,
++ char **addr, vartype *vtype );
++
++extern void ls_print_findsym_error(int result,
++ char *mod_name,
++ char *var_name);
++
++extern double ls_get_double(vartype sym_type, void *addr );
++
++extern void ls_set_double(vartype sym_type, void *addr, double value );
++
++extern double ls_get_sym_val( symbol_rec *symrec, int *error );
++
++ /* This routine attempts to return the present value of the symbol
++ described in symbol_rec. If Addr is non-zero, the value of that
++ location, interpreted as type double, will be returned. If Addr
++ is zero, and Mod_Name and Par_Name are both not null strings,
++ the ls_findsym() routine is used to try to obtain the address
++ by looking at debugger symbol tables in the executable image, and
++ the value of the double contained at that address is returned,
++ and the symbol record is updated to contain the address of that
++ symbol. If an error is discovered, 'error' will be non-zero and
++ and error message is printed on stderr. */
++
++extern void ls_set_sym_val( symbol_rec *symrec, double value );
++
++ /* This routine sets the value of a double at the location pointed
++ to by the symbol_rec's Addr field, if Addr is non-zero. If Addr
++ is zero, and Mod_Name and Par_Name are both not null strings,
++ the ls_findsym() routine is used to try to obtain the address
++ by looking at debugger symbol tables in the executable image, and
++ the value of the double contained at that address is returned,
++ and the symbol record is updated to contain the address of that
++ symbol. If an error is discovered, 'error' will be non-zero and
++ and error message is printed on stderr. */
++
++
++#endif /* _LS_SYM_H */
++
++
--- /dev/null
--- /dev/null
++/***************************************************************************
++
++ TITLE: ls_types.h
++
++----------------------------------------------------------------------------
++
++ FUNCTION: LaRCSim type definitions header file
++
++----------------------------------------------------------------------------
++
++ MODULE STATUS: developmental
++
++----------------------------------------------------------------------------
++
++ GENEALOGY: Created 15 DEC 1993 by Bruce Jackson from old
++ ls_eom.h header
++
++----------------------------------------------------------------------------
++
++ DESIGNED BY: B. Jackson
++
++ CODED BY: B. Jackson
++
++ MAINTAINED BY: guess who
++
++----------------------------------------------------------------------------
++
++ MODIFICATION HISTORY:
++
++ DATE PURPOSE BY
++
++--------------------------------------------------------------------------*/
++
++#ifndef _LS_TYPES_H
++#define _LS_TYPES_H
++
++
++/* SCALAR type is used throughout equations of motion code - sets precision */
++
++typedef double SCALAR;
++
++typedef SCALAR VECTOR_3[3];
++
++/* DATA type is old style; this statement for continuity */
++
++#define DATA SCALAR
++
++
++#endif /* _LS_TYPES_H */
++
++
++/* --------------------------- end of ls_types.h -------------------------*/
--- /dev/null
--- /dev/null
++/* test main for playing with the LaRCsim code */
++
++#include "ls_types.h"
++#include "ls_cockpit.h"
++#include "ls_generic.h"
++
++
++COCKPIT cockpit_;
++GENERIC generic_;
++
++int main(int argc, char **argv) {
++ model_init();
++}
--- /dev/null
--- /dev/null
++/***************************************************************************
++
++ TITLE: Navion_aero
++
++----------------------------------------------------------------------------
++
++ FUNCTION: Linear aerodynamics model
++
++----------------------------------------------------------------------------
++
++ MODULE STATUS: developmental
++
++----------------------------------------------------------------------------
++
++ GENEALOGY: Based upon class notes from AA271, Stanford University,
++ Spring 1988. Dr. Robert Cannon, instructor.
++
++----------------------------------------------------------------------------
++
++ DESIGNED BY: Bruce Jackson
++
++ CODED BY: Bruce Jackson
++
++ MAINTAINED BY: Bruce Jackson
++
++----------------------------------------------------------------------------
++
++ MODIFICATION HISTORY:
++
++ DATE PURPOSE BY
++ 921229 Changed Alpha, Beta into radians; added Alpha bias.
++ EBJ
++ 930105 Modified to support linear airframe simulation by
++ adding shared memory initialization routine. EBJ
++ 931013 Added scaling by airspeed, to allow for low-airspeed
++ ground operations. EBJ
++ 940216 Scaled long, lat stick and rudder to more appropriate values
++ of elevator and aileron. EBJ
++
++----------------------------------------------------------------------------
++
++ REFERENCES:
++
++The Navion "aero" routine is a simple representation of the North
++American Navion airplane, a 1950-s vintage single-engine, low-wing
++mono-lane built by NAA (who built the famous P-51 Mustang) supposedly
++as a plane for returning WW-II fighter jocks to carry the family
++around the country in. Unfortunately underpowered, it can still be
++found in small airports across the United States. From behind, it sort
++of looks like a Volkswagen driving a Piper by virtue of its nicely
++rounded cabin roof and small rear window.
++
++The aero routine is only valid around 100 knots; it is referred to as
++a "linear model" of the navion; the data having been extracted by
++someone unknown from a more complete model, or more likely, from
++in-flight measurements and manuever time histories. It probably came
++from someone at Princeton U; they owned a couple modified Navions that
++had a variable-stability system installed, and were highly
++instrumented (and well calibrated, I assume).
++
++In any event, a linearized model, such as this one, contains various
++"stability derivatives", or estimates of how aerodynamic forces and
++moments vary with changes in angle of attack, angular body rates, and
++control surface deflections. For example, L_beta is an estimate of how
++much roll moment varies per degree of sideslip increase. A decoding
++ring is given below:
++
++ X Aerodynamic force, lbs, in X-axis (+ forward)
++ Y Aerodynamic force, lbs, in Y-axis (+ right)
++ Z Aerodynamic force, lbs, in Z-axis (+ down)
++ L Aero. moment about X-axis (+ roll right), ft-lbs
++ M Aero. moment about Y-axis (+ pitch up), ft-lbs
++ N Aero. moment about Z-axis (+ nose right), ft-lbs
++
++ 0 Subscript implying initial, or nominal, value
++ u X-axis component of airspeed (ft/sec) (+ forward)
++ v Y-axis component of airspeed (ft/sec) (+ right)
++ w Z-axis component of airspeed (ft/sec) (+ down)
++ p X-axis ang. rate (rad/sec) (+ roll right), rad/sec
++ q Y-axis ang. rate (rad/sec) (+ pitch up), rad/sec
++ r Z-axis ang. rate (rad/sec) (+ yaw right), rad/sec
++ beta Angle of sideslip, degrees (+ wind in RIGHT ear)
++ da Aileron deflection, degrees (+ left ail. TE down)
++ de Elevator deflection, degrees (+ trailing edge down)
++ dr Rudder deflection, degrees (+ trailing edge LEFT)
++
++----------------------------------------------------------------------------
++
++ CALLED BY:
++
++----------------------------------------------------------------------------
++
++ CALLS TO:
++
++----------------------------------------------------------------------------
++
++ INPUTS:
++
++----------------------------------------------------------------------------
++
++ OUTPUTS:
++
++--------------------------------------------------------------------------*/
++
++#include "ls_types.h"
++#include "ls_generic.h"
++#include "ls_cockpit.h"
++
++/* define trimmed w_body to correspond with alpha_trim = 5 */
++#define TRIMMED_W 15.34
++
++extern COCKPIT cockpit_;
++
++
++void aero( SCALAR dt, int Initialize ) {
++ static int init = 0;
++
++ SCALAR u, w;
++ static SCALAR elevator, aileron, rudder;
++ static SCALAR long_scale = 0.3;
++ static SCALAR lat_scale = 0.1;
++ static SCALAR yaw_scale = -0.1;
++ static SCALAR scale = 1.0;
++
++ /* static SCALAR trim_inc = 0.0002; */
++ /* static SCALAR long_trim; */
++
++ static DATA U_0;
++ static DATA X_0;
++ static DATA M_0;
++ static DATA Z_0;
++ static DATA X_u;
++ static DATA X_w;
++ static DATA X_de;
++ static DATA Y_v;
++ static DATA Z_u;
++ static DATA Z_w;
++ static DATA Z_de;
++ static DATA L_beta;
++ static DATA L_p;
++ static DATA L_r;
++ static DATA L_da;
++ static DATA L_dr;
++ static DATA M_w;
++ static DATA M_q;
++ static DATA M_de;
++ static DATA N_beta;
++ static DATA N_p;
++ static DATA N_r;
++ static DATA N_da;
++ static DATA N_dr;
++
++ if (!init)
++ {
++ init = -1;
++
++ /* Initialize aero coefficients */
++
++ U_0 = 176;
++ X_0 = -573.75;
++ M_0 = 0;
++ Z_0 = -2750;
++ X_u = -0.0451; /* original value */
++ /* X_u = 0.0000; */ /* for MUCH better performance - EBJ */
++ X_w = 0.03607;
++ X_de = 0;
++ Y_v = -0.2543;
++ Z_u = -0.3697; /* original value */
++ /* Z_u = -0.03697; */ /* for better performance - EBJ */
++ Z_w = -2.0244;
++ Z_de = -28.17;
++ L_beta = -15.982;
++ L_p = -8.402;
++ L_r = 2.193;
++ L_da = 28.984;
++ L_dr = 2.548;
++ M_w = -0.05;
++ M_q = -2.0767;
++ M_de = -11.1892;
++ N_beta = 4.495;
++ N_p = -0.3498;
++ N_r = -0.7605;
++ N_da = -0.2218;
++ N_dr = -4.597;
++ }
++
++ u = V_rel_wind - U_0;
++ w = W_body - TRIMMED_W;
++
++ elevator = long_scale * Long_control;
++ aileron = lat_scale * Lat_control;
++ rudder = yaw_scale * Rudder_pedal;
++
++ /* if(Aft_trim) long_trim = long_trim - trim_inc; */
++ /* if(Fwd_trim) long_trim = long_trim + trim_inc; */
++
++ scale = V_rel_wind*V_rel_wind/(U_0*U_0);
++ if (scale > 1.0) scale = 1.0; /* ebj */
++
++
++ F_X_aero = scale*(X_0 + Mass*(X_u*u + X_w*w + X_de*elevator));
++ F_Y_aero = scale*(Mass*Y_v*V_body);
++ F_Z_aero = scale*(Z_0 + Mass*(Z_u*u + Z_w*w + Z_de*elevator));
++
++ M_l_aero = scale*(I_xx*(L_beta*Beta + L_p*P_body + L_r*R_body
++ + L_da*aileron + L_dr*rudder));
++ M_m_aero = scale*(M_0 + I_yy*(M_w*w + M_q*Q_body + M_de*(elevator + Long_trim)));
++ M_n_aero = scale*(I_zz*(N_beta*Beta + N_p*P_body + N_r*R_body
++ + N_da*aileron + N_dr*rudder));
++
++}
++
++
--- /dev/null
--- /dev/null
++/***************************************************************************
++
++ TITLE: engine.c
++
++----------------------------------------------------------------------------
++
++ FUNCTION: dummy engine routine
++
++----------------------------------------------------------------------------
++
++ MODULE STATUS: incomplete
++
++----------------------------------------------------------------------------
++
++ GENEALOGY: Created 15 OCT 92 as dummy routine for checkout. EBJ
++
++----------------------------------------------------------------------------
++
++ DESIGNED BY: designer
++
++ CODED BY: programmer
++
++ MAINTAINED BY: maintainer
++
++----------------------------------------------------------------------------
++
++ MODIFICATION HISTORY:
++
++ DATE PURPOSE BY
++
++ CURRENT RCS HEADER INFO:
++
++$Header$
++
++ * Revision 1.1 92/12/30 13:21:46 bjax
++ * Initial revision
++ *
++
++----------------------------------------------------------------------------
++
++ REFERENCES:
++
++----------------------------------------------------------------------------
++
++ CALLED BY: ls_model();
++
++----------------------------------------------------------------------------
++
++ CALLS TO: none
++
++----------------------------------------------------------------------------
++
++ INPUTS:
++
++----------------------------------------------------------------------------
++
++ OUTPUTS:
++
++--------------------------------------------------------------------------*/
++#include <math.h>
++#include "ls_types.h"
++#include "ls_constants.h"
++#include "ls_generic.h"
++#include "ls_sim_control.h"
++#include "ls_cockpit.h"
++
++extern SIM_CONTROL sim_control_;
++
++void engine( SCALAR dt, int init ) {
++ /* if (init) { */
++ Throttle[3] = Throttle_pct;
++ /* } */
++
++ /* F_X_engine = Throttle[3]*813.4/0.2; */ /* original code */
++ /* F_Z_engine = Throttle[3]*11.36/0.2; */ /* original code */
++ F_X_engine = Throttle[3]*813.4/0.83;
++ F_Z_engine = Throttle[3]*11.36/0.83;
++
++ Throttle_pct = Throttle[3];
++}
++
++
--- /dev/null
--- /dev/null
++/***************************************************************************
++
++ TITLE: gear
++
++----------------------------------------------------------------------------
++
++ FUNCTION: Landing gear model for example simulation
++
++----------------------------------------------------------------------------
++
++ MODULE STATUS: developmental
++
++----------------------------------------------------------------------------
++
++ GENEALOGY: Created 931012 by E. B. Jackson
++
++----------------------------------------------------------------------------
++
++ DESIGNED BY: E. B. Jackson
++
++ CODED BY: E. B. Jackson
++
++ MAINTAINED BY: E. B. Jackson
++
++----------------------------------------------------------------------------
++
++ MODIFICATION HISTORY:
++
++ DATE PURPOSE BY
++
++ 931218 Added navion.h header to allow connection with
++ aileron displacement for nosewheel steering. EBJ
++ 940511 Connected nosewheel to rudder pedal; adjusted gain.
++
++ CURRENT RCS HEADER:
++
++$Header$
++$Log$
++Revision 1.6 1998/10/17 01:34:16 curt
++C++ ifying ...
++
++Revision 1.5 1998/09/29 02:03:00 curt
++Added a brake + autopilot mods.
++
++Revision 1.4 1998/08/06 12:46:40 curt
++Header change.
++
++Revision 1.3 1998/02/03 23:20:18 curt
++Lots of little tweaks to fix various consistency problems discovered by
++Solaris' CC. Fixed a bug in fg_debug.c with how the fgPrintf() wrapper
++passed arguments along to the real printf(). Also incorporated HUD changes
++by Michele America.
++
++Revision 1.2 1998/01/19 18:40:29 curt
++Tons of little changes to clean up the code and to remove fatal errors
++when building with the c++ compiler.
++
++Revision 1.1 1997/05/29 00:10:02 curt
++Initial Flight Gear revision.
++
++
++----------------------------------------------------------------------------
++
++ REFERENCES:
++
++----------------------------------------------------------------------------
++
++ CALLED BY:
++
++----------------------------------------------------------------------------
++
++ CALLS TO:
++
++----------------------------------------------------------------------------
++
++ INPUTS:
++
++----------------------------------------------------------------------------
++
++ OUTPUTS:
++
++--------------------------------------------------------------------------*/
++#include <math.h>
++#include "ls_types.h"
++#include "ls_constants.h"
++#include "ls_generic.h"
++#include "ls_cockpit.h"
++
++
++void sub3( DATA v1[], DATA v2[], DATA result[] )
++{
++ result[0] = v1[0] - v2[0];
++ result[1] = v1[1] - v2[1];
++ result[2] = v1[2] - v2[2];
++}
++
++void add3( DATA v1[], DATA v2[], DATA result[] )
++{
++ result[0] = v1[0] + v2[0];
++ result[1] = v1[1] + v2[1];
++ result[2] = v1[2] + v2[2];
++}
++
++void cross3( DATA v1[], DATA v2[], DATA result[] )
++{
++ result[0] = v1[1]*v2[2] - v1[2]*v2[1];
++ result[1] = v1[2]*v2[0] - v1[0]*v2[2];
++ result[2] = v1[0]*v2[1] - v1[1]*v2[0];
++}
++
++void multtrans3x3by3( DATA m[][3], DATA v[], DATA result[] )
++{
++ result[0] = m[0][0]*v[0] + m[1][0]*v[1] + m[2][0]*v[2];
++ result[1] = m[0][1]*v[0] + m[1][1]*v[1] + m[2][1]*v[2];
++ result[2] = m[0][2]*v[0] + m[1][2]*v[1] + m[2][2]*v[2];
++}
++
++void mult3x3by3( DATA m[][3], DATA v[], DATA result[] )
++{
++ result[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2];
++ result[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2];
++ result[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2];
++}
++
++void clear3( DATA v[] )
++{
++ v[0] = 0.; v[1] = 0.; v[2] = 0.;
++}
++
++void gear( SCALAR dt, int Initialize ) {
++char rcsid[] = "$Id$";
++
++ /*
++ * Aircraft specific initializations and data goes here
++ */
++
++#define NUM_WHEELS 3
++
++ static int num_wheels = NUM_WHEELS; /* number of wheels */
++ static DATA d_wheel_rp_body_v[NUM_WHEELS][3] = /* X, Y, Z locations */
++ {
++ { 10., 0., 4. }, /* in feet */
++ { -1., 3., 4. },
++ { -1., -3., 4. }
++ };
++ static DATA spring_constant[NUM_WHEELS] = /* springiness, lbs/ft */
++ { 1500., 5000., 5000. };
++ static DATA spring_damping[NUM_WHEELS] = /* damping, lbs/ft/sec */
++ { 100., 150., 150. };
++ static DATA percent_brake[NUM_WHEELS] = /* percent applied braking */
++ { 0., 0., 0. }; /* 0 = none, 1 = full */
++ static DATA caster_angle_rad[NUM_WHEELS] = /* steerable tires - in */
++ { 0., 0., 0.}; /* radians, +CW */
++ /*
++ * End of aircraft specific code
++ */
++
++ /*
++ * Constants & coefficients for tyres on tarmac - ref [1]
++ */
++
++ /* skid function looks like:
++ *
++ * mu ^
++ * |
++ * max_mu | +
++ * | /|
++ * sliding_mu | / +------
++ * | /
++ * | /
++ * +--+------------------------>
++ * | | | sideward V
++ * 0 bkout skid
++ * V V
++ */
++
++
++ static DATA sliding_mu = 0.5;
++ static DATA rolling_mu = 0.01;
++ static DATA max_brake_mu = 0.6;
++ static DATA max_mu = 0.8;
++ static DATA bkout_v = 0.1;
++ static DATA skid_v = 1.0;
++ /*
++ * Local data variables
++ */
++
++ DATA d_wheel_cg_body_v[3]; /* wheel offset from cg, X-Y-Z */
++ DATA d_wheel_cg_local_v[3]; /* wheel offset from cg, N-E-D */
++ DATA d_wheel_rwy_local_v[3]; /* wheel offset from rwy, N-E-U */
++ DATA v_wheel_body_v[3]; /* wheel velocity, X-Y-Z */
++ DATA v_wheel_local_v[3]; /* wheel velocity, N-E-D */
++ DATA f_wheel_local_v[3]; /* wheel reaction force, N-E-D */
++ DATA temp3a[3], temp3b[3], tempF[3], tempM[3];
++ DATA reaction_normal_force; /* wheel normal (to rwy) force */
++ DATA cos_wheel_hdg_angle, sin_wheel_hdg_angle; /* temp storage */
++ DATA v_wheel_forward, v_wheel_sideward, abs_v_wheel_sideward;
++ DATA forward_mu, sideward_mu; /* friction coefficients */
++ DATA beta_mu; /* breakout friction slope */
++ DATA forward_wheel_force, sideward_wheel_force;
++
++ int i; /* per wheel loop counter */
++
++ /*
++ * Execution starts here
++ */
++
++ beta_mu = max_mu/(skid_v-bkout_v);
++ clear3( F_gear_v ); /* Initialize sum of forces... */
++ clear3( M_gear_v ); /* ...and moments */
++
++ /*
++ * Put aircraft specific executable code here
++ */
++
++ /* replace with cockpit brake handle connection code */
++ percent_brake[1] = Brake_pct;
++ percent_brake[2] = percent_brake[1];
++
++ caster_angle_rad[0] = 0.03*Rudder_pedal;
++
++ for (i=0;i<num_wheels;i++) /* Loop for each wheel */
++ {
++ /*========================================*/
++ /* Calculate wheel position w.r.t. runway */
++ /*========================================*/
++
++ /* First calculate wheel location w.r.t. cg in body (X-Y-Z) axes... */
++
++ sub3( d_wheel_rp_body_v[i], D_cg_rp_body_v, d_wheel_cg_body_v );
++
++ /* then converting to local (North-East-Down) axes... */
++
++ multtrans3x3by3( T_local_to_body_m, d_wheel_cg_body_v, d_wheel_cg_local_v );
++
++ /* Runway axes correction - third element is Altitude, not (-)Z... */
++
++ d_wheel_cg_local_v[2] = -d_wheel_cg_local_v[2]; /* since altitude = -Z */
++
++ /* Add wheel offset to cg location in local axes */
++
++ add3( d_wheel_cg_local_v, D_cg_rwy_local_v, d_wheel_rwy_local_v );
++
++ /* remove Runway axes correction so right hand rule applies */
++
++ d_wheel_cg_local_v[2] = -d_wheel_cg_local_v[2]; /* now Z positive down */
++
++ /*============================*/
++ /* Calculate wheel velocities */
++ /*============================*/
++
++ /* contribution due to angular rates */
++
++ cross3( Omega_body_v, d_wheel_cg_body_v, temp3a );
++
++ /* transform into local axes */
++
++ multtrans3x3by3( T_local_to_body_m, temp3a, temp3b );
++
++ /* plus contribution due to cg velocities */
++
++ add3( temp3b, V_local_rel_ground_v, v_wheel_local_v );
++
++
++ /*===========================================*/
++ /* Calculate forces & moments for this wheel */
++ /*===========================================*/
++
++ /* Add any anticipation, or frame lead/prediction, here... */
++
++ /* no lead used at present */
++
++ /* Calculate sideward and forward velocities of the wheel
++ in the runway plane */
++
++ cos_wheel_hdg_angle = cos(caster_angle_rad[i] + Psi);
++ sin_wheel_hdg_angle = sin(caster_angle_rad[i] + Psi);
++
++ v_wheel_forward = v_wheel_local_v[0]*cos_wheel_hdg_angle
++ + v_wheel_local_v[1]*sin_wheel_hdg_angle;
++ v_wheel_sideward = v_wheel_local_v[1]*cos_wheel_hdg_angle
++ - v_wheel_local_v[0]*sin_wheel_hdg_angle;
++
++ /* Calculate normal load force (simple spring constant) */
++
++ reaction_normal_force = 0.;
++ if( d_wheel_rwy_local_v[2] < 0. )
++ {
++ reaction_normal_force = spring_constant[i]*d_wheel_rwy_local_v[2]
++ - v_wheel_local_v[2]*spring_damping[i];
++ if (reaction_normal_force > 0.) reaction_normal_force = 0.;
++ /* to prevent damping component from swamping spring component */
++ }
++
++ /* Calculate friction coefficients */
++
++ forward_mu = (max_brake_mu - rolling_mu)*percent_brake[i] + rolling_mu;
++ abs_v_wheel_sideward = sqrt(v_wheel_sideward*v_wheel_sideward);
++ sideward_mu = sliding_mu;
++ if (abs_v_wheel_sideward < skid_v)
++ sideward_mu = (abs_v_wheel_sideward - bkout_v)*beta_mu;
++ if (abs_v_wheel_sideward < bkout_v) sideward_mu = 0.;
++
++ /* Calculate foreward and sideward reaction forces */
++
++ forward_wheel_force = forward_mu*reaction_normal_force;
++ sideward_wheel_force = sideward_mu*reaction_normal_force;
++ if(v_wheel_forward < 0.) forward_wheel_force = -forward_wheel_force;
++ if(v_wheel_sideward < 0.) sideward_wheel_force = -sideward_wheel_force;
++
++ /* Rotate into local (N-E-D) axes */
++
++ f_wheel_local_v[0] = forward_wheel_force*cos_wheel_hdg_angle
++ - sideward_wheel_force*sin_wheel_hdg_angle;
++ f_wheel_local_v[1] = forward_wheel_force*sin_wheel_hdg_angle
++ + sideward_wheel_force*cos_wheel_hdg_angle;
++ f_wheel_local_v[2] = reaction_normal_force;
++
++ /* Convert reaction force from local (N-E-D) axes to body (X-Y-Z) */
++
++ mult3x3by3( T_local_to_body_m, f_wheel_local_v, tempF );
++
++ /* Calculate moments from force and offsets in body axes */
++
++ cross3( d_wheel_cg_body_v, tempF, tempM );
++
++ /* Sum forces and moments across all wheels */
++
++ add3( tempF, F_gear_v, F_gear_v );
++ add3( tempM, M_gear_v, M_gear_v );
++
++ }
++}
--- /dev/null
--- /dev/null
++/***************************************************************************
++
++ TITLE: navion_init.c
++
++----------------------------------------------------------------------------
++
++ FUNCTION: Initializes navion math model
++
++----------------------------------------------------------------------------
++
++ MODULE STATUS: developmental
++
++----------------------------------------------------------------------------
++
++ GENEALOGY: Added to navion package 930111 by Bruce Jackson
++
++----------------------------------------------------------------------------
++
++ DESIGNED BY: EBJ
++
++ CODED BY: EBJ
++
++ MAINTAINED BY: EBJ
++
++----------------------------------------------------------------------------
++
++ MODIFICATION HISTORY:
++
++ DATE PURPOSE BY
++
++ 950314 Removed initialization of state variables, since this is
++ now done (version 1.4b1) in ls_init. EBJ
++ 950406 Removed #include of "shmdefs.h"; shmdefs.h is a duplicate
++ of "navion.h". EBJ
++
++ CURRENT RCS HEADER:
++
++----------------------------------------------------------------------------
++
++ REFERENCES:
++
++----------------------------------------------------------------------------
++
++ CALLED BY:
++
++----------------------------------------------------------------------------
++
++ CALLS TO:
++
++----------------------------------------------------------------------------
++
++ INPUTS:
++
++----------------------------------------------------------------------------
++
++ OUTPUTS:
++
++--------------------------------------------------------------------------*/
++#include "ls_types.h"
++#include "ls_generic.h"
++#include "ls_cockpit.h"
++
++void model_init( void ) {
++
++ Throttle[3] = 0.2; Rudder_pedal = 0; Lat_control = 0; Long_control = 0;
++
++ Dx_pilot = 0; Dy_pilot = 0; Dz_pilot = 0;
++
++}
--- /dev/null
--- /dev/null
++/* a quick navion_init.h */
++
++
++#ifndef _NAVION_INIT_H
++#define _NAVION_INIT_H
++
++
++void model_init( void );
++
++
++#endif _NAVION_INIT_H
--- /dev/null
--- /dev/null
++// GLUTkey.cxx -- handle GLUT keyboard events
++//
++// Written by Curtis Olson, started May 1997.
++//
++// Copyright (C) 1997 Curtis L. Olson - curt@me.umn.edu
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#if defined(FX) && defined(XMESA)
++#include <GL/xmesa.h>
++#endif
++
++#include <stdio.h>
++#include <stdlib.h>
++
++#include <Debug/logstream.hxx>
++#include <Aircraft/aircraft.hxx>
++#include <Astro/solarsystem.hxx>
++#include <Astro/sky.hxx>
++#include <Autopilot/autopilot.hxx>
++#include <Cockpit/hud.hxx>
++#include <GUI/gui.h>
++#include <Include/fg_constants.h>
++#include <Objects/material.hxx>
++#include <pu.h>
++#include <Time/light.hxx>
++#include <Weather/weather.hxx>
++
++#include "GLUTkey.hxx"
++#include "options.hxx"
++#include "views.hxx"
++
++
++// Force an update of the sky and lighting parameters
++static void local_update_sky_and_lighting_params( void ) {
++ // fgSunInit();
++ SolarSystem::theSolarSystem->rebuild();
++ cur_light_params.Update();
++ fgSkyColorsInit();
++}
++
++
++// Handle keyboard events
++void GLUTkey(unsigned char k, int x, int y) {
++ FGInterface *f;
++ fgTIME *t;
++ FGView *v;
++ FGWeather *w;
++ float fov, tmp;
++ static bool winding_ccw = true;
++
++ f = current_aircraft.fdm_state;
++ t = &cur_time_params;
++ v = ¤t_view;
++ w = ¤t_weather;
++
++ FG_LOG( FG_INPUT, FG_DEBUG, "Key hit = " << k );
++ puKeyboard(k, PU_DOWN );
++
++ if ( GLUT_ACTIVE_ALT && glutGetModifiers() ) {
++ FG_LOG( FG_INPUT, FG_DEBUG, " SHIFTED" );
++ switch (k) {
++ case 1: // Ctrl-A key
++ fgAPToggleAltitude();
++ return;
++ case 8: // Ctrl-H key
++ fgAPToggleHeading();
++ return;
++ case 18: // Ctrl-R key
++ // temporary
++ winding_ccw = !winding_ccw;
++ if ( winding_ccw ) {
++ glFrontFace ( GL_CCW );
++ } else {
++ glFrontFace ( GL_CW );
++ }
++ return;
++ case 19: // Ctrl-S key
++ fgAPToggleAutoThrottle();
++ return;
++ case 20: // Ctrl-T key
++ fgAPToggleTerrainFollow();
++ return;
++ case 49: // numeric keypad 1
++ v->set_goal_view_offset( FG_PI * 0.75 );
++ return;
++ case 50: // numeric keypad 2
++ v->set_goal_view_offset( FG_PI );
++ return;
++ case 51: // numeric keypad 3
++ v->set_goal_view_offset( FG_PI * 1.25 );
++ return;
++ case 52: // numeric keypad 4
++ v->set_goal_view_offset( FG_PI * 0.50 );
++ return;
++ case 54: // numeric keypad 6
++ v->set_goal_view_offset( FG_PI * 1.50 );
++ return;
++ case 55: // numeric keypad 7
++ v->set_goal_view_offset( FG_PI * 0.25 );
++ return;
++ case 56: // numeric keypad 8
++ v->set_goal_view_offset( 0.00 );
++ return;
++ case 57: // numeric keypad 9
++ v->set_goal_view_offset( FG_PI * 1.75 );
++ return;
++ case 72: // H key
++ // status = current_options.get_hud_status();
++ // current_options.set_hud_status(!status);
++ HUD_brightkey( true );
++ return;
++ case 73: // i key
++ // Minimal Hud
++ fgHUDInit2(¤t_aircraft);
++ return;
++ case 77: // M key
++ t->warp -= 60;
++ local_update_sky_and_lighting_params();
++ return;
++ case 84: // T key
++ t->warp_delta -= 30;
++ local_update_sky_and_lighting_params();
++ return;
++ case 87: // W key
++#if defined(FX) && !defined(WIN32)
++ global_fullscreen = ( !global_fullscreen );
++# if defined(XMESA_FX_FULLSCREEN) && defined(XMESA_FX_WINDOW)
++ XMesaSetFXmode( global_fullscreen ?
++ XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW );
++# endif
++#endif
++ return;
++ case 88: // X key
++ fov = current_options.get_fov();
++ fov *= 1.05;
++ if ( fov > FG_FOV_MAX ) {
++ fov = FG_FOV_MAX;
++ }
++ current_options.set_fov(fov);
++ v->force_update_fov_math();
++ return;
++ case 90: // Z key
++ tmp = w->get_visibility(); // in meters
++ tmp /= 1.10;
++ w->set_visibility( tmp );
++ return;
++ }
++ } else {
++ FG_LOG( FG_INPUT, FG_DEBUG, "" );
++ switch (k) {
++ case 50: // numeric keypad 2
++ if( fgAPAltitudeEnabled() ) {
++ fgAPAltitudeAdjust( 100 );
++ } else {
++ controls.move_elevator(-0.05);
++ }
++ return;
++ case 56: // numeric keypad 8
++ if( fgAPAltitudeEnabled() ) {
++ fgAPAltitudeAdjust( -100 );
++ } else {
++ controls.move_elevator(0.05);
++ }
++ return;
++ case 49: // numeric keypad 1
++ controls.move_elevator_trim(-0.001);
++ return;
++ case 55: // numeric keypad 7
++ controls.move_elevator_trim(0.001);
++ return;
++ case 52: // numeric keypad 4
++ controls.move_aileron(-0.05);
++ return;
++ case 54: // numeric keypad 6
++ controls.move_aileron(0.05);
++ return;
++ case 48: // numeric keypad Ins
++ if( fgAPHeadingEnabled() ) {
++ fgAPHeadingAdjust( -1 );
++ } else {
++ controls.move_rudder(-0.05);
++ }
++ return;
++ case 13: // numeric keypad Enter
++ if( fgAPHeadingEnabled() ) {
++ fgAPHeadingAdjust( 1 );
++ } else {
++ controls.move_rudder(0.05);
++ }
++ return;
++ case 53: // numeric keypad 5
++ controls.set_aileron(0.0);
++ controls.set_elevator(0.0);
++ controls.set_rudder(0.0);
++ return;
++ case 57: // numeric keypad 9 (Pg Up)
++ if( fgAPAutoThrottleEnabled() ) {
++ fgAPAutoThrottleAdjust( 5 );
++ } else {
++ controls.move_throttle( FGControls::ALL_ENGINES, 0.01 );
++ }
++ return;
++ case 51: // numeric keypad 3 (Pg Dn)
++ if( fgAPAutoThrottleEnabled() ) {
++ fgAPAutoThrottleAdjust( -5 );
++ } else {
++ controls.move_throttle( FGControls::ALL_ENGINES, -0.01 );
++ }
++ return;
++ case 98: // b key
++ int b_ret;
++ double b_set;
++ b_ret = int( controls.get_brake( 0 ) );
++ b_set = double(!b_ret);
++ controls.set_brake( FGControls::ALL_WHEELS, b_set);
++ return;
++ case 104: // h key
++ HUD_brightkey( false );
++ return;
++ case 105: // i key
++ fgHUDInit(¤t_aircraft); // normal HUD
++ return;
++ case 109: // m key
++ t->warp += 60;
++ local_update_sky_and_lighting_params();
++ return;
++ case 112: // p key
++ t->pause = !t->pause;
++ // printf position and attitude information
++ FG_LOG( FG_INPUT, FG_INFO,
++ "Lon = " << f->get_Longitude() * RAD_TO_DEG
++ << " Lat = " << f->get_Latitude() * RAD_TO_DEG
++ << " Altitude = " << f->get_Altitude() * FEET_TO_METER );
++ FG_LOG( FG_INPUT, FG_INFO,
++ "Heading = " << f->get_Psi() * RAD_TO_DEG
++ << " Roll = " << f->get_Phi() * RAD_TO_DEG
++ << " Pitch = " << f->get_Theta() * RAD_TO_DEG );
++ return;
++ case 116: // t key
++ t->warp_delta += 30;
++ local_update_sky_and_lighting_params();
++ return;
++ case 120: // X key
++ fov = current_options.get_fov();
++ fov /= 1.05;
++ if ( fov < FG_FOV_MIN ) {
++ fov = FG_FOV_MIN;
++ }
++ current_options.set_fov(fov);
++ v->force_update_fov_math();
++ return;
++ case 122: // z key
++ tmp = w->get_visibility(); // in meters
++ tmp *= 1.10;
++ w->set_visibility( tmp );
++ return;
++ case 27: // ESC
++ // if( fg_DebugOutput ) {
++ // fclose( fg_DebugOutput );
++ // }
++ FG_LOG( FG_INPUT, FG_ALERT,
++ "Program exiting normally at user request." );
++ exit(-1);
++ }
++ }
++}
++
++
++// Handle "special" keyboard events
++void GLUTspecialkey(int k, int x, int y) {
++ FGView *v;
++
++ v = ¤t_view;
++
++ FG_LOG( FG_INPUT, FG_DEBUG, "Special key hit = " << k );
++ puKeyboard(k + PU_KEY_GLUT_SPECIAL_OFFSET, PU_DOWN);
++
++ if ( GLUT_ACTIVE_SHIFT && glutGetModifiers() ) {
++ FG_LOG( FG_INPUT, FG_DEBUG, " SHIFTED" );
++ switch (k) {
++ case GLUT_KEY_END: // numeric keypad 1
++ v->set_goal_view_offset( FG_PI * 0.75 );
++ return;
++ case GLUT_KEY_DOWN: // numeric keypad 2
++ v->set_goal_view_offset( FG_PI );
++ return;
++ case GLUT_KEY_PAGE_DOWN: // numeric keypad 3
++ v->set_goal_view_offset( FG_PI * 1.25 );
++ return;
++ case GLUT_KEY_LEFT: // numeric keypad 4
++ v->set_goal_view_offset( FG_PI * 0.50 );
++ return;
++ case GLUT_KEY_RIGHT: // numeric keypad 6
++ v->set_goal_view_offset( FG_PI * 1.50 );
++ return;
++ case GLUT_KEY_HOME: // numeric keypad 7
++ v->set_goal_view_offset( FG_PI * 0.25 );
++ return;
++ case GLUT_KEY_UP: // numeric keypad 8
++ v->set_goal_view_offset( 0.00 );
++ return;
++ case GLUT_KEY_PAGE_UP: // numeric keypad 9
++ v->set_goal_view_offset( FG_PI * 1.75 );
++ return;
++ }
++ } else {
++ FG_LOG( FG_INPUT, FG_DEBUG, "" );
++ switch (k) {
++ case GLUT_KEY_F8: // F8 toggles fog ... off fastest nicest...
++ current_options.cycle_fog();
++
++ if ( current_options.get_fog() == fgOPTIONS::FG_FOG_DISABLED ) {
++ FG_LOG( FG_INPUT, FG_INFO, "Fog disabled" );
++ } else if ( current_options.get_fog() ==
++ fgOPTIONS::FG_FOG_FASTEST )
++ {
++ FG_LOG( FG_INPUT, FG_INFO,
++ "Fog enabled, hint set to fastest" );
++ } else if ( current_options.get_fog() ==
++ fgOPTIONS::FG_FOG_NICEST )
++ {
++ FG_LOG( FG_INPUT, FG_INFO,
++ "Fog enabled, hint set to nicest" );
++ }
++
++ return;
++ case GLUT_KEY_F9: // F9 toggles textures on and off...
++ if ( material_mgr.get_textures_loaded() ) {
++ current_options.get_textures() ?
++ current_options.set_textures(false) :
++ current_options.set_textures(true);
++ FG_LOG( FG_INPUT, FG_INFO, "Toggling texture" );
++ } else {
++ FG_LOG( FG_INPUT, FG_INFO,
++ "No textures loaded, cannot toggle" );
++ }
++ return;
++ case GLUT_KEY_F10: // F10 toggles menu on and off...
++ FG_LOG(FG_INPUT, FG_INFO, "Invoking call back function");
++ hideMenuButton ->
++ setValue ((int) !(hideMenuButton -> getValue() ) );
++ hideMenuButton -> invokeCallback();
++ //exit(1);
++ return;
++ case GLUT_KEY_UP:
++ if( fgAPAltitudeEnabled() ) {
++ fgAPAltitudeAdjust( -100 );
++ } else {
++ controls.move_elevator(0.05);
++ }
++ return;
++ case GLUT_KEY_DOWN:
++ if( fgAPAltitudeEnabled() ) {
++ fgAPAltitudeAdjust( 100 );
++ } else {
++ controls.move_elevator(-0.05);
++ }
++ return;
++ case GLUT_KEY_LEFT:
++ controls.move_aileron(-0.05);
++ return;
++ case GLUT_KEY_RIGHT:
++ controls.move_aileron(0.05);
++ return;
++ case GLUT_KEY_HOME: // numeric keypad 1
++ controls.move_elevator_trim(0.001);
++ return;
++ case GLUT_KEY_END: // numeric keypad 7
++ controls.move_elevator_trim(-0.001);
++ return;
++ case GLUT_KEY_INSERT: // numeric keypad Ins
++ if( fgAPHeadingEnabled() ) {
++ fgAPHeadingAdjust( -1 );
++ } else {
++ controls.move_rudder(-0.05);
++ }
++ return;
++ case 13: // numeric keypad Enter
++ if( fgAPHeadingEnabled() ) {
++ fgAPHeadingAdjust( 1 );
++ } else {
++ controls.move_rudder(0.05);
++ }
++ return;
++ case 53: // numeric keypad 5
++ controls.set_aileron(0.0);
++ controls.set_elevator(0.0);
++ controls.set_rudder(0.0);
++ return;
++ case GLUT_KEY_PAGE_UP: // numeric keypad 9 (Pg Up)
++ if( fgAPAutoThrottleEnabled() ) {
++ fgAPAutoThrottleAdjust( 5 );
++ } else {
++ controls.move_throttle( FGControls::ALL_ENGINES, 0.01 );
++ }
++ return;
++ case GLUT_KEY_PAGE_DOWN: // numeric keypad 3 (Pg Dn)
++ if( fgAPAutoThrottleEnabled() ) {
++ fgAPAutoThrottleAdjust( -5 );
++ } else {
++ controls.move_throttle( FGControls::ALL_ENGINES, -0.01 );
++ }
++ return;
++ }
++ }
++}
++
++
++// $Log$
++// Revision 1.44 1999/04/03 04:21:01 curt
++// Integration of Steve's plib conglomeration.
++// Optimizations (tm) by Norman Vine.
++//
++// Revision 1.43 1999/03/11 23:09:46 curt
++// When "Help" is selected from the menu check to see if netscape is running.
++// If so, command it to go to the flight gear user guide url. Otherwise
++// start a new version of netscape with this url.
++//
++// Revision 1.42 1999/02/26 22:09:46 curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.41 1999/02/12 23:22:43 curt
++// Allow auto-throttle adjustment while active.
++//
++// Revision 1.40 1999/02/12 22:17:59 curt
++// Changes to allow adjustment of the autopilot settings while it is activated.
++//
++// Revision 1.39 1999/02/05 21:29:07 curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.38 1998/12/11 20:26:25 curt
++// Fixed view frustum culling accuracy bug so we can look out the sides and
++// back without tri-stripes dropping out.
++//
++// Revision 1.37 1998/12/09 18:50:22 curt
++// Converted "class fgVIEW" to "class FGView" and updated to make data
++// members private and make required accessor functions.
++//
++// Revision 1.36 1998/12/06 13:51:20 curt
++// Turned "struct fgWEATHER" into "class FGWeather".
++//
++// Revision 1.35 1998/12/05 16:13:17 curt
++// Renamed class fgCONTROLS to class FGControls.
++//
++// Revision 1.34 1998/12/05 15:54:17 curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.33 1998/12/03 01:17:12 curt
++// Converted fgFLIGHT to a class.
++//
++// Revision 1.32 1998/11/06 21:18:06 curt
++// Converted to new logstream debugging facility. This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.31 1998/11/02 18:25:37 curt
++// Check for __CYGWIN__ (b20) as well as __CYGWIN32__ (pre b20 compilers)
++// Other misc. tweaks.
++//
++// Revision 1.30 1998/10/25 14:08:46 curt
++// Turned "struct fgCONTROLS" into a class, with inlined accessor functions.
++//
++// Revision 1.29 1998/10/20 14:58:57 curt
++// Ctrl-R now reverses default polygon winding so I can see if a hole in the
++// terrain is a result of improper winding, or if it is just an empty hole.
++//
++// Revision 1.28 1998/10/17 01:34:20 curt
++// C++ ifying ...
++//
++// Revision 1.27 1998/10/02 12:46:46 curt
++// Added an "auto throttle"
++//
++// Revision 1.26 1998/10/01 00:38:04 curt
++// More altitude hold tweaks.
++//
++// Revision 1.25 1998/09/29 02:03:36 curt
++// Autopilot mods.
++//
++// Revision 1.24 1998/09/26 13:16:44 curt
++// C++-ified the comments.
++//
++// Revision 1.23 1998/09/17 18:35:30 curt
++// Added F8 to toggle fog and F9 to toggle texturing.
++//
++// Revision 1.22 1998/09/15 04:27:27 curt
++// Changes for new Astro code.
++//
++// Revision 1.21 1998/08/29 13:09:25 curt
++// Changes to event manager from Bernie Bright.
++//
++// Revision 1.20 1998/08/24 20:11:12 curt
++// Added i/I to toggle full vs. minimal HUD.
++// Added a --hud-tris vs --hud-culled option.
++// Moved options accessor funtions to options.hxx.
++//
++// Revision 1.19 1998/08/05 00:19:33 curt
++// Added a local routine to update lighting params every frame when time is
++// accelerated.
++//
++// Revision 1.18 1998/07/30 23:48:24 curt
++// Output position & orientation when pausing.
++// Eliminated libtool use.
++// Added options to specify initial position and orientation.
++// Changed default fov to 55 degrees.
++// Added command line option to start in paused or unpaused state.
++//
++// Revision 1.17 1998/07/27 18:41:23 curt
++// Added a pause command "p"
++// Fixed some initialization order problems between pui and glut.
++// Added an --enable/disable-sound option.
++//
++// Revision 1.16 1998/07/16 17:33:34 curt
++// "H" / "h" now control hud brightness as well with off being one of the
++// states.
++// Better checking for xmesa/fx 3dfx fullscreen/window support for deciding
++// whether or not to build in the feature.
++// Translucent menu support.
++// HAVE_AUDIO_SUPPORT -> ENABLE_AUDIO_SUPPORT
++// Use fork() / wait() for playing mp3 init music in background under unix.
++// Changed default tile diameter to 5.
++//
++// Revision 1.15 1998/07/13 21:01:34 curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.14 1998/07/06 02:42:02 curt
++// Added support for switching between fullscreen and window mode for
++// Mesa/3dfx/glide.
++//
++// Added a basic splash screen. Restructured the main loop and top level
++// initialization routines to do this.
++//
++// Hacked in some support for playing a startup mp3 sound file while rest
++// of sim initializes. Currently only works in Unix using the mpg123 player.
++// Waits for the mpg123 player to finish before initializing internal
++// sound drivers.
++//
++// Revision 1.13 1998/06/27 16:54:32 curt
++// Replaced "extern displayInstruments" with a entry in fgOPTIONS.
++// Don't change the view port when displaying the panel.
++//
++// Revision 1.12 1998/06/12 14:27:26 curt
++// Pui -> PUI, Gui -> GUI.
++//
++// Revision 1.11 1998/06/12 00:57:38 curt
++// Added support for Pui/Gui.
++// Converted fog to GL_FOG_EXP2.
++// Link to static simulator parts.
++// Update runfg.bat to try to be a little smarter.
++//
++// Revision 1.10 1998/05/27 02:24:05 curt
++// View optimizations by Norman Vine.
++//
++// Revision 1.9 1998/05/16 13:05:21 curt
++// Added limits to fov.
++//
++// Revision 1.8 1998/05/13 18:29:56 curt
++// Added a keyboard binding to dynamically adjust field of view.
++// Added a command line option to specify fov.
++// Adjusted terrain color.
++// Root path info moved to fgOPTIONS.
++// Added ability to parse options out of a config file.
++//
++// Revision 1.7 1998/05/07 23:14:14 curt
++// Added "D" key binding to set autopilot heading.
++// Made frame rate calculation average out over last 10 frames.
++// Borland C++ floating point exception workaround.
++// Added a --tile-radius=n option.
++//
++// Revision 1.6 1998/04/28 01:20:20 curt
++// Type-ified fgTIME and fgVIEW.
++// Added a command line option to disable textures.
++//
++// Revision 1.5 1998/04/25 22:06:29 curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.4 1998/04/25 20:24:00 curt
++// Cleaned up initialization sequence to eliminate interdependencies
++// between sun position, lighting, and view position. This creates a
++// valid single pass initialization path.
++//
++// Revision 1.3 1998/04/24 14:19:29 curt
++// Fog tweaks.
++//
++// Revision 1.2 1998/04/24 00:49:17 curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Trying out some different option parsing code.
++// Some code reorganization.
++//
++// Revision 1.1 1998/04/22 13:25:40 curt
++// C++ - ifing the code.
++// Starting a bit of reorganization of lighting code.
++//
++// Revision 1.33 1998/04/18 04:11:25 curt
++// Moved fg_debug to it's own library, added zlib support.
++//
++// Revision 1.32 1998/04/14 02:21:01 curt
++// Incorporated autopilot heading hold contributed by: Jeff Goeke-Smith
++// <jgoeke@voyager.net>
++//
++// Revision 1.31 1998/04/08 23:34:05 curt
++// Patch from Durk to fix trim reversal with numlock key active.
++//
++// Revision 1.30 1998/04/03 22:09:02 curt
++// Converting to Gnu autoconf system.
++//
++// Revision 1.29 1998/02/07 15:29:40 curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.28 1998/02/03 23:20:23 curt
++// Lots of little tweaks to fix various consistency problems discovered by
++// Solaris' CC. Fixed a bug in fg_debug.c with how the fgPrintf() wrapper
++// passed arguments along to the real printf(). Also incorporated HUD changes
++// by Michele America.
++//
++// Revision 1.27 1998/01/27 00:47:55 curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.26 1998/01/19 19:27:07 curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.25 1998/01/05 18:44:34 curt
++// Add an option to advance/decrease time from keyboard.
++//
++// Revision 1.24 1997/12/30 16:36:46 curt
++// Merged in Durk's changes ...
++//
++// Revision 1.23 1997/12/15 23:54:44 curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.22 1997/12/10 22:37:45 curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.21 1997/08/27 21:32:23 curt
++// Restructured view calculation code. Added stars.
++//
++// Revision 1.20 1997/08/27 03:30:13 curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.19 1997/08/25 20:27:21 curt
++// Merged in initial HUD and Joystick code.
++//
++// Revision 1.18 1997/08/22 21:34:38 curt
++// Doing a bit of reorganizing and house cleaning.
++//
++// Revision 1.17 1997/07/19 22:34:02 curt
++// Moved PI definitions to ../constants.h
++// Moved random() stuff to ../Utils/ and renamed fg_random()
++//
++// Revision 1.16 1997/07/18 23:41:24 curt
++// Tweaks for building with Cygnus Win32 compiler.
++//
++// Revision 1.15 1997/07/16 20:04:47 curt
++// Minor tweaks to aid Win32 port.
++//
++// Revision 1.14 1997/07/12 03:50:20 curt
++// Added an #include <Windows32/Base.h> to help compiling for Win32
++//
++// Revision 1.13 1997/06/25 15:39:46 curt
++// Minor changes to compile with rsxnt/win32.
++//
++// Revision 1.12 1997/06/21 17:12:52 curt
++// Capitalized subdirectory names.
++//
++// Revision 1.11 1997/06/18 04:10:31 curt
++// A couple more runway tweaks ...
++//
++// Revision 1.10 1997/06/18 02:21:23 curt
++// Hacked in a runway
++//
++// Revision 1.9 1997/06/02 03:40:06 curt
++// A tiny bit more view tweaking.
++//
++// Revision 1.8 1997/06/02 03:01:38 curt
++// Working on views (side, front, back, transitions, etc.)
++//
++// Revision 1.7 1997/05/31 19:16:25 curt
++// Elevator trim added.
++//
++// Revision 1.6 1997/05/31 04:13:52 curt
++// WE CAN NOW FLY!!!
++//
++// Continuing work on the LaRCsim flight model integration.
++// Added some MSFS-like keyboard input handling.
++//
++// Revision 1.5 1997/05/30 23:26:19 curt
++// Added elevator/aileron controls.
++//
++// Revision 1.4 1997/05/27 17:44:31 curt
++// Renamed & rearranged variables and routines. Added some initial simple
++// timer/alarm routines so the flight model can be updated on a regular
++// interval.
++//
++// Revision 1.3 1997/05/23 15:40:25 curt
++// Added GNU copyright headers.
++// Fog now works!
++//
++// Revision 1.2 1997/05/23 00:35:12 curt
++// Trying to get fog to work ...
++//
++// Revision 1.1 1997/05/21 15:57:50 curt
++// Renamed due to added GLUT support.
++//
++// Revision 1.2 1997/05/19 18:22:41 curt
++// Parameter tweaking ... starting to stub in fog support.
++//
++// Revision 1.1 1997/05/16 16:05:51 curt
++// Initial revision.
++
--- /dev/null
--- /dev/null
++// GLUTkey.hxx -- handle GLUT keyboard events
++//
++// Written by Curtis Olson, started May 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$
++// (Log is kept at end of this file)
++
++
++#ifndef _GLUTKEY_HXX
++#define _GLUTKEY_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++
++// Handle keyboard events
++void GLUTkey(unsigned char k, int x, int y);
++void GLUTspecialkey(int k, int x, int y);
++
++
++#endif // _GLUTKEY_HXX
++
++
++// $Log$
++// Revision 1.4 1999/03/12 22:51:53 curt
++// Converted to C++ style comments.
++//
++// Revision 1.3 1999/03/11 23:09:47 curt
++// When "Help" is selected from the menu check to see if netscape is running.
++// If so, command it to go to the flight gear user guide url. Otherwise
++// start a new version of netscape with this url.
++//
++// Revision 1.2 1998/04/24 00:49:18 curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Trying out some different option parsing code.
++// Some code reorganization.
++//
++// Revision 1.1 1998/04/22 13:25:41 curt
++// C++ - ifing the code.
++// Starting a bit of reorganization of lighting code.
++//
++// Revision 1.9 1998/04/21 17:02:36 curt
++// Prepairing for C++ integration.
++//
++// Revision 1.8 1998/04/03 22:09:02 curt
++// Converting to Gnu autoconf system.
++//
++// Revision 1.7 1998/02/12 21:59:44 curt
++// Incorporated code changes contributed by Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.6 1998/01/22 02:59:36 curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.5 1997/07/23 21:52:23 curt
++// Put comments around the text after an #endif for increased portability.
++//
++// Revision 1.4 1997/06/02 03:40:06 curt
++// A tiny bit more view tweaking.
++//
++// Revision 1.3 1997/05/31 04:13:52 curt
++// WE CAN NOW FLY!!!
++//
++// Continuing work on the LaRCsim flight model integration.
++// Added some MSFS-like keyboard input handling.
++//
++// Revision 1.2 1997/05/23 15:40:25 curt
++// Added GNU copyright headers.
++// Fog now works!
++//
++// Revision 1.1 1997/05/21 15:57:51 curt
++// Renamed due to added GLUT support.
++//
++// Revision 1.2 1997/05/17 00:17:34 curt
++// Trying to stub in support for standard OpenGL.
++//
++// Revision 1.1 1997/05/16 16:05:53 curt
++// Initial revision.
++//
++
--- /dev/null
--- /dev/null
++// GLUTmain.cxx -- top level sim routines
++//
++// Written by Curtis Olson for OpenGL, started May 1997.
++//
++// Copyright (C) 1997 Curtis L. Olson - curt@me.umn.edu
++//
++// 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$
++// (Log is kept at end of this file)
++
++#define MICHAEL_JOHNSON_EXPERIMENTAL_ENGINE_AUDIO
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++# include <float.h>
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++#include <stdio.h>
++#include <string.h>
++#include <string>
++
++#ifdef HAVE_STDLIB_H
++# include <stdlib.h>
++#endif
++
++#ifdef HAVE_SYS_STAT_H
++# include <sys/stat.h> /* for stat() */
++#endif
++
++#ifdef HAVE_UNISTD_H
++# include <unistd.h> /* for stat() */
++#endif
++
++#include <Include/fg_constants.h> // for VERSION
++#include <Include/general.hxx>
++
++#include <Debug/logstream.hxx>
++#include <Aircraft/aircraft.hxx>
++#include <Astro/sky.hxx>
++#include <Astro/stars.hxx>
++#include <Astro/solarsystem.hxx>
++
++#ifdef ENABLE_AUDIO_SUPPORT
++# include <sl.h>
++# include <sm.h>
++#endif
++
++#include <Autopilot/autopilot.hxx>
++#include <Cockpit/cockpit.hxx>
++#include <GUI/gui.h>
++#include <Joystick/joystick.hxx>
++#include <Math/fg_geodesy.hxx>
++#include <Math/mat3.h>
++#include <Math/polar3d.hxx>
++#include <Math/fg_random.h>
++#include <pu.h>
++#include <Scenery/scenery.hxx>
++#include <Scenery/tilemgr.hxx>
++#include <Time/event.hxx>
++#include <Time/fg_time.hxx>
++#include <Time/fg_timer.hxx>
++#include <Time/sunpos.hxx>
++#include <Weather/weather.hxx>
++
++#include "GLUTkey.hxx"
++#include "fg_init.hxx"
++#include "options.hxx"
++#include "splash.hxx"
++#include "views.hxx"
++#include "fg_serial.hxx"
++
++
++// This is a record containing a bit of global housekeeping information
++FGGeneral general;
++
++// Specify our current idle function state. This is used to run all
++// our initializations out of the glutIdleLoop() so that we can get a
++// splash screen up and running right away.
++static int idle_state = 0;
++
++// Another hack
++int use_signals = 0;
++
++// Global structures for the Audio library
++#ifdef ENABLE_AUDIO_SUPPORT
++slEnvelope pitch_envelope ( 1, SL_SAMPLE_ONE_SHOT ) ;
++slEnvelope volume_envelope ( 1, SL_SAMPLE_ONE_SHOT ) ;
++slScheduler *audio_sched;
++smMixer *audio_mixer;
++slSample *s1;
++slSample *s2;
++#endif
++
++
++// The following defines flight gear options. Because glutlib will also
++// want to parse its own options, those options must not be included here
++// or they will get parsed by the main program option parser. Hence case
++// is significant for any option added that might be in conflict with
++// glutlib's parser.
++//
++// glutlib parses for:
++// -display
++// -direct (invalid in Win32)
++// -geometry
++// -gldebug
++// -iconized
++// -indirect (invalid in Win32)
++// -synce
++//
++// Note that glutlib depends upon strings while this program's
++// option parser wants only initial characters followed by numbers
++// or pathnames.
++//
++
++
++// fgInitVisuals() -- Initialize various GL/view parameters
++static void fgInitVisuals( void ) {
++ fgLIGHT *l;
++
++ l = &cur_light_params;
++
++ // Go full screen if requested ...
++ if ( current_options.get_fullscreen() ) {
++ glutFullScreen();
++ }
++
++ // If enabled, normal vectors specified with glNormal are scaled
++ // to unit length after transformation. See glNormal.
++ // xglEnable( GL_NORMALIZE );
++
++ xglEnable( GL_LIGHTING );
++ xglEnable( GL_LIGHT0 );
++ xglLightfv( GL_LIGHT0, GL_POSITION, l->sun_vec );
++
++ // xglFogi (GL_FOG_MODE, GL_LINEAR);
++ xglFogi (GL_FOG_MODE, GL_EXP2);
++ // Fog density is now set when the weather system is initialized
++ // xglFogf (GL_FOG_DENSITY, w->fog_density);
++ if ( (current_options.get_fog() == 1) ||
++ (current_options.get_shading() == 0) ) {
++ // if fastest fog requested, or if flat shading force fastest
++ xglHint ( GL_FOG_HINT, GL_FASTEST );
++ } else if ( current_options.get_fog() == 2 ) {
++ xglHint ( GL_FOG_HINT, GL_NICEST );
++ }
++ if ( current_options.get_wireframe() ) {
++ // draw wire frame
++ xglPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
++ }
++
++ // This is the default anyways, but it can't hurt
++ xglFrontFace ( GL_CCW );
++
++ // Just testing ...
++ // xglEnable(GL_POINT_SMOOTH);
++ // xglEnable(GL_LINE_SMOOTH);
++ // xglEnable(GL_POLYGON_SMOOTH);
++}
++
++
++#if 0
++// Draw a basic instrument panel
++static void fgUpdateInstrViewParams( void ) {
++
++ exit(0);
++
++ fgVIEW *v = ¤t_view;
++
++ xglViewport(0, 0 , (GLint)(v->winWidth), (GLint)(v->winHeight) / 2);
++
++ xglMatrixMode(GL_PROJECTION);
++ xglPushMatrix();
++
++ xglLoadIdentity();
++ gluOrtho2D(0, 640, 0, 480);
++ xglMatrixMode(GL_MODELVIEW);
++ xglPushMatrix();
++ xglLoadIdentity();
++
++ xglColor3f(1.0, 1.0, 1.0);
++ xglIndexi(7);
++
++ xglDisable(GL_DEPTH_TEST);
++ xglDisable(GL_LIGHTING);
++
++ xglLineWidth(1);
++ xglColor3f (0.5, 0.5, 0.5);
++
++ xglBegin(GL_QUADS);
++ xglVertex2f(0.0, 0.00);
++ xglVertex2f(0.0, 480.0);
++ xglVertex2f(640.0,480.0);
++ xglVertex2f(640.0, 0.0);
++ xglEnd();
++
++ xglRectf(0.0,0.0, 640, 480);
++ xglEnable(GL_DEPTH_TEST);
++ xglEnable(GL_LIGHTING);
++ xglMatrixMode(GL_PROJECTION);
++ xglPopMatrix();
++ xglMatrixMode(GL_MODELVIEW);
++ xglPopMatrix();
++}
++#endif
++
++
++// Update all Visuals (redraws anything graphics related)
++static void fgRenderFrame( void ) {
++ fgLIGHT *l = &cur_light_params;
++ fgTIME *t = &cur_time_params;
++ FGView *v = ¤t_view;
++
++ double angle;
++ // GLfloat black[4] = { 0.0, 0.0, 0.0, 1.0 };
++ GLfloat white[4] = { 1.0, 1.0, 1.0, 1.0 };
++ GLfloat terrain_color[4] = { 0.54, 0.44, 0.29, 1.0 };
++ GLbitfield clear_mask;
++
++ if ( idle_state != 1000 ) {
++ // still initializing, draw the splash screen
++ if ( current_options.get_splash_screen() == 1 ) {
++ fgSplashUpdate(0.0);
++ }
++ } else {
++ // idle_state is now 1000 meaning we've finished all our
++ // initializations and are running the main loop, so this will
++ // now work without seg faulting the system.
++
++ // printf("Ground = %.2f Altitude = %.2f\n", scenery.cur_elev,
++ // FG_Altitude * FEET_TO_METER);
++
++ // this is just a temporary hack, to make me understand Pui
++ // timerText -> setLabel (ctime (&t->cur_time));
++ // end of hack
++
++ // update view volume parameters
++ v->UpdateViewParams();
++
++ // set the sun position
++ xglLightfv( GL_LIGHT0, GL_POSITION, l->sun_vec );
++
++ clear_mask = GL_DEPTH_BUFFER_BIT;
++ if ( current_options.get_wireframe() ) {
++ clear_mask |= GL_COLOR_BUFFER_BIT;
++ }
++ if ( current_options.get_panel_status() ) {
++ // we can't clear the screen when the panel is active
++ } else if ( current_options.get_skyblend() ) {
++ if ( current_options.get_textures() ) {
++ // glClearColor(black[0], black[1], black[2], black[3]);
++ glClearColor(l->adj_fog_color[0], l->adj_fog_color[1],
++ l->adj_fog_color[2], l->adj_fog_color[3]);
++ clear_mask |= GL_COLOR_BUFFER_BIT;
++ }
++ } else {
++ glClearColor(l->sky_color[0], l->sky_color[1],
++ l->sky_color[2], l->sky_color[3]);
++ clear_mask |= GL_COLOR_BUFFER_BIT;
++ }
++ xglClear( clear_mask );
++
++ // Tell GL we are switching to model view parameters
++ xglMatrixMode(GL_MODELVIEW);
++ // xglLoadIdentity();
++
++ // draw sky
++ xglDisable( GL_DEPTH_TEST );
++ xglDisable( GL_LIGHTING );
++ xglDisable( GL_CULL_FACE );
++ xglDisable( GL_FOG );
++ xglShadeModel( GL_SMOOTH );
++ if ( current_options.get_skyblend() ) {
++ fgSkyRender();
++ }
++
++ // setup transformation for drawing astronomical objects
++ xglPushMatrix();
++ // Translate to view position
++ Point3D view_pos = v->get_view_pos();
++ xglTranslatef( view_pos.x(), view_pos.y(), view_pos.z() );
++ // Rotate based on gst (sidereal time)
++ // note: constant should be 15.041085, Curt thought it was 15
++ angle = t->gst * 15.041085;
++ // printf("Rotating astro objects by %.2f degrees\n",angle);
++ xglRotatef( angle, 0.0, 0.0, -1.0 );
++
++ // draw stars and planets
++ fgStarsRender();
++ SolarSystem::theSolarSystem->draw();
++
++ xglPopMatrix();
++
++ // draw scenery
++ if ( current_options.get_shading() ) {
++ xglShadeModel( GL_SMOOTH );
++ } else {
++ xglShadeModel( GL_FLAT );
++ }
++ xglEnable( GL_DEPTH_TEST );
++ if ( current_options.get_fog() > 0 ) {
++ xglEnable( GL_FOG );
++ xglFogfv (GL_FOG_COLOR, l->adj_fog_color);
++ }
++ // set lighting parameters
++ xglLightfv(GL_LIGHT0, GL_AMBIENT, l->scene_ambient );
++ xglLightfv(GL_LIGHT0, GL_DIFFUSE, l->scene_diffuse );
++
++ if ( current_options.get_textures() ) {
++ // texture parameters
++ xglEnable( GL_TEXTURE_2D );
++ xglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ) ;
++ xglHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ) ;
++ // set base color (I don't think this is doing anything here)
++ xglMaterialfv (GL_FRONT, GL_AMBIENT, white);
++ xglMaterialfv (GL_FRONT, GL_DIFFUSE, white);
++ } else {
++ xglDisable( GL_TEXTURE_2D );
++ xglMaterialfv (GL_FRONT, GL_AMBIENT, terrain_color);
++ xglMaterialfv (GL_FRONT, GL_DIFFUSE, terrain_color);
++ // xglMaterialfv (GL_FRONT, GL_AMBIENT, white);
++ // xglMaterialfv (GL_FRONT, GL_DIFFUSE, white);
++ }
++
++ fgTileMgrRender();
++
++ xglDisable( GL_TEXTURE_2D );
++ xglDisable( GL_FOG );
++
++ // display HUD && Panel
++ fgCockpitUpdate();
++
++ // We can do translucent menus, so why not. :-)
++ xglEnable ( GL_BLEND ) ;
++ xglBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
++ puDisplay();
++ xglDisable ( GL_BLEND ) ;
++ xglEnable( GL_FOG );
++ }
++
++ xglutSwapBuffers();
++}
++
++
++// Update internal time dependent calculations (i.e. flight model)
++void fgUpdateTimeDepCalcs(int multi_loop, int remainder) {
++ FGInterface *f = current_aircraft.fdm_state;
++ fgLIGHT *l = &cur_light_params;
++ fgTIME *t = &cur_time_params;
++ FGView *v = ¤t_view;
++ int i;
++
++ // update the flight model
++ if ( multi_loop < 0 ) {
++ multi_loop = DEFAULT_MULTILOOP;
++ }
++
++ if ( !t->pause ) {
++ // run Autopilot system
++ fgAPRun();
++
++ // printf("updating flight model x %d\n", multi_loop);
++ fgFDMUpdate( current_options.get_flight_model(),
++ cur_fdm_state, multi_loop, remainder );
++ } else {
++ fgFDMUpdate( current_options.get_flight_model(),
++ cur_fdm_state, 0, remainder );
++ }
++
++ // update the view angle
++ for ( i = 0; i < multi_loop; i++ ) {
++ if ( fabs(v->get_goal_view_offset() - v->get_view_offset()) < 0.05 ) {
++ v->set_view_offset( v->get_goal_view_offset() );
++ break;
++ } else {
++ // move v->view_offset towards v->goal_view_offset
++ if ( v->get_goal_view_offset() > v->get_view_offset() ) {
++ if ( v->get_goal_view_offset() - v->get_view_offset() < FG_PI ){
++ v->inc_view_offset( 0.01 );
++ } else {
++ v->inc_view_offset( -0.01 );
++ }
++ } else {
++ if ( v->get_view_offset() - v->get_goal_view_offset() < FG_PI ){
++ v->inc_view_offset( -0.01 );
++ } else {
++ v->inc_view_offset( 0.01 );
++ }
++ }
++ if ( v->get_view_offset() > FG_2PI ) {
++ v->inc_view_offset( -FG_2PI );
++ } else if ( v->get_view_offset() < 0 ) {
++ v->inc_view_offset( FG_2PI );
++ }
++ }
++ }
++
++ double tmp = -(l->sun_rotation + FG_PI)
++ - (f->get_Psi() - v->get_view_offset() );
++ while ( tmp < 0.0 ) {
++ tmp += FG_2PI;
++ }
++ while ( tmp > FG_2PI ) {
++ tmp -= FG_2PI;
++ }
++ /* printf("Psi = %.2f, viewoffset = %.2f sunrot = %.2f rottosun = %.2f\n",
++ FG_Psi * RAD_TO_DEG, v->view_offset * RAD_TO_DEG,
++ -(l->sun_rotation+FG_PI) * RAD_TO_DEG, tmp * RAD_TO_DEG); */
++ l->UpdateAdjFog();
++}
++
++
++void fgInitTimeDepCalcs( void ) {
++ // initialize timer
++
++ // #ifdef HAVE_SETITIMER
++ // fgTimerInit( 1.0 / DEFAULT_TIMER_HZ, fgUpdateTimeDepCalcs );
++ // #endif HAVE_SETITIMER
++}
++
++static const double alt_adjust_ft = 3.758099;
++static const double alt_adjust_m = alt_adjust_ft * FEET_TO_METER;
++
++// What should we do when we have nothing else to do? Let's get ready
++// for the next move and update the display?
++static void fgMainLoop( void ) {
++ FGInterface *f;
++ fgTIME *t;
++ static long remainder = 0;
++ long elapsed, multi_loop;
++ // int i;
++ // double accum;
++ static time_t last_time = 0;
++ static int frames = 0;
++
++ f = current_aircraft.fdm_state;
++ t = &cur_time_params;
++
++ FG_LOG( FG_ALL, FG_DEBUG, "Running Main Loop");
++ FG_LOG( FG_ALL, FG_DEBUG, "======= ==== ====");
++
++#if defined( ENABLE_LINUX_JOYSTICK )
++ // Read joystick and update control settings
++ fgJoystickRead();
++#elif defined( ENABLE_GLUT_JOYSTICK )
++ // Glut joystick support works by feeding a joystick handler
++ // function to glut. This is taken care of once in the joystick
++ // init routine and we don't have to worry about it again.
++#endif
++
++ current_weather.Update();
++
++ // Fix elevation. I'm just sticking this here for now, it should
++ // probably move eventually
++
++ /* printf("Before - ground = %.2f runway = %.2f alt = %.2f\n",
++ scenery.cur_elev,
++ f->get_Runway_altitude() * FEET_TO_METER,
++ f->get_Altitude() * FEET_TO_METER); */
++
++ if ( scenery.cur_elev > -9990 ) {
++ if ( f->get_Altitude() * FEET_TO_METER <
++ (scenery.cur_elev + alt_adjust_m - 3.0) ) {
++ // now set aircraft altitude above ground
++ printf("Current Altitude = %.2f < %.2f forcing to %.2f\n",
++ f->get_Altitude() * FEET_TO_METER,
++ scenery.cur_elev + alt_adjust_m - 3.0,
++ scenery.cur_elev + alt_adjust_m );
++ fgFDMForceAltitude( current_options.get_flight_model(),
++ scenery.cur_elev + alt_adjust_m );
++
++ FG_LOG( FG_ALL, FG_DEBUG,
++ "<*> resetting altitude to "
++ << f->get_Altitude() * FEET_TO_METER << " meters" );
++ }
++ fgFDMSetGroundElevation( current_options.get_flight_model(),
++ scenery.cur_elev ); // meters
++ }
++
++ /* printf("Adjustment - ground = %.2f runway = %.2f alt = %.2f\n",
++ scenery.cur_elev,
++ f->get_Runway_altitude() * FEET_TO_METER,
++ f->get_Altitude() * FEET_TO_METER); */
++
++ // update "time"
++ fgTimeUpdate(f, t);
++
++ // Get elapsed time (in usec) for this past frame
++ elapsed = fgGetTimeInterval();
++ FG_LOG( FG_ALL, FG_DEBUG,
++ "Elapsed time interval is = " << elapsed
++ << ", previous remainder is = " << remainder );
++
++ // Calculate frame rate average
++ if ( (t->cur_time != last_time) && (last_time > 0) ) {
++ general.set_frame_rate( frames );
++ FG_LOG( FG_ALL, FG_DEBUG,
++ "--> Frame rate is = " << general.get_frame_rate() );
++ frames = 0;
++ }
++ last_time = t->cur_time;
++ ++frames;
++
++ /* old fps calculation
++ if ( elapsed > 0 ) {
++ accum = 0.0;
++ for ( i = FG_FRAME_RATE_HISTORY - 2; i >= 0; i-- ) {
++ accum += g->frames[i];
++ // printf("frame[%d] = %.2f\n", i, g->frames[i]);
++ g->frames[i+1] = g->frames[i];
++ }
++ g->frames[0] = 1000.0 / (float)elapsed;
++ // printf("frame[0] = %.2f\n", g->frames[0]);
++ accum += g->frames[0];
++ g->frame_rate = accum / (float)FG_FRAME_RATE_HISTORY;
++ // printf("ave = %.2f\n", g->frame_rate);
++ }
++ */
++
++ // Run flight model
++ if ( ! use_signals ) {
++ // Calculate model iterations needed for next frame
++ elapsed += remainder;
++
++ multi_loop = (int)(((double)elapsed * 0.000001) * DEFAULT_MODEL_HZ);
++ remainder = elapsed - ((multi_loop*1000000) / DEFAULT_MODEL_HZ);
++ FG_LOG( FG_ALL, FG_DEBUG,
++ "Model iterations needed = " << multi_loop
++ << ", new remainder = " << remainder );
++
++ // flight model
++ if ( multi_loop > 0 ) {
++ fgUpdateTimeDepCalcs(multi_loop, remainder);
++ } else {
++ FG_LOG( FG_ALL, FG_INFO, "Elapsed time is zero ... we're zinging" );
++ }
++ }
++
++ // Do any serial port work that might need to be done
++ fgSerialProcess();
++
++ // see if we need to load any new scenery tiles
++ fgTileMgrUpdate();
++
++ // Process/manage pending events
++ global_events.Process();
++
++ // Run audio scheduler
++#ifdef ENABLE_AUDIO_SUPPORT
++ if ( current_options.get_sound() && !audio_sched->not_working() ) {
++
++# ifdef MICHAEL_JOHNSON_EXPERIMENTAL_ENGINE_AUDIO
++
++ // note: all these factors are relative to the sample. our
++ // sample format should really contain a conversion factor so
++ // that we can get prop speed right for arbitrary samples.
++ // Note that for normal-size props, there is a point at which
++ // the prop tips approach the speed of sound; that is a pretty
++ // strong limit to how fast the prop can go.
++
++ // multiplication factor is prime pitch control; add some log
++ // component for verisimilitude
++
++ double pitch = log((controls.get_throttle(0) * 14.0) + 1.0);
++ //fprintf(stderr, "pitch1: %f ", pitch);
++ if (controls.get_throttle(0) > 0.0 || f->v_rel_wind > 40.0) {
++ //fprintf(stderr, "rel_wind: %f ", f->v_rel_wind);
++ // only add relative wind and AoA if prop is moving
++ // or we're really flying at idle throttle
++ if (pitch < 5.4) { // this needs tuning
++ // prop tips not breaking sound barrier
++ pitch += log(f->v_rel_wind + 0.8)/2;
++ } else {
++ // prop tips breaking sound barrier
++ pitch += log(f->v_rel_wind + 0.8)/10;
++ }
++ //fprintf(stderr, "pitch2: %f ", pitch);
++ //fprintf(stderr, "AoA: %f ", FG_Gamma_vert_rad);
++
++ // Angle of Attack next... -x^3(e^x) is my best guess Just
++ // need to calculate some reasonable scaling factor and
++ // then clamp it on the positive aoa (neg adj) side
++ double aoa = f->get_Gamma_vert_rad() * 2.2;
++ double tmp = 3.0;
++ double aoa_adj = pow(-aoa, tmp) * pow(M_E, aoa);
++ if (aoa_adj < -0.8) aoa_adj = -0.8;
++ pitch += aoa_adj;
++ //fprintf(stderr, "pitch3: %f ", pitch);
++
++ // don't run at absurdly slow rates -- not realistic
++ // and sounds bad to boot. :-)
++ if (pitch < 0.8) pitch = 0.8;
++ }
++ //fprintf(stderr, "pitch4: %f\n", pitch);
++
++ double volume = controls.get_throttle(0) * 1.15 + 0.3 +
++ log(f->v_rel_wind + 1.0)/14.0;
++ // fprintf(stderr, "volume: %f\n", volume);
++
++ pitch_envelope.setStep ( 0, 0.01, pitch );
++ volume_envelope.setStep ( 0, 0.01, volume );
++
++# else
++
++ double param = controls.get_throttle( 0 ) * 2.0 + 1.0;
++ pitch_envelope.setStep ( 0, 0.01, param );
++ volume_envelope.setStep ( 0, 0.01, param );
++
++# endif // experimental throttle patch
++
++ audio_sched -> update();
++ }
++#endif
++
++ // redraw display
++ fgRenderFrame();
++
++ FG_LOG( FG_ALL, FG_DEBUG, "" );
++}
++
++
++// This is the top level master main function that is registered as
++// our idle funciton
++//
++
++// The first few passes take care of initialization things (a couple
++// per pass) and once everything has been initialized fgMainLoop from
++// then on.
++
++static void fgIdleFunction ( void ) {
++ // printf("idle state == %d\n", idle_state);
++
++ if ( idle_state == 0 ) {
++ // Initialize the splash screen right away
++ if ( current_options.get_splash_screen() ) {
++ fgSplashInit();
++ }
++
++ idle_state++;
++ } else if ( idle_state == 1 ) {
++ // Start the intro music
++#if !defined(WIN32)
++ if ( current_options.get_intro_music() ) {
++ string lockfile = "/tmp/mpg123.running";
++ string mp3file = current_options.get_fg_root() +
++ "/Sounds/intro.mp3";
++ string command = "(touch " + lockfile + "; mpg123 " + mp3file +
++ "> /dev/null 2>&1; /bin/rm " + lockfile + ") &";
++ FG_LOG( FG_GENERAL, FG_INFO,
++ "Starting intro music: " << mp3file );
++ system ( command.c_str() );
++ }
++#endif
++
++ idle_state++;
++ } else if ( idle_state == 2 ) {
++ // These are a few miscellaneous things that aren't really
++ // "subsystems" but still need to be initialized.
++
++#ifdef USE_GLIDE
++ if ( strstr ( general.get_glRenderer(), "Glide" ) ) {
++ grTexLodBiasValue ( GR_TMU0, 1.0 ) ;
++ }
++#endif
++
++ idle_state++;
++ } else if ( idle_state == 3 ) {
++ // This is the top level init routine which calls all the
++ // other subsystem initialization routines. If you are adding
++ // a subsystem to flight gear, its initialization call should
++ // located in this routine.
++ if( !fgInitSubsystems()) {
++ FG_LOG( FG_GENERAL, FG_ALERT,
++ "Subsystem initializations failed ..." );
++ exit(-1);
++ }
++
++ idle_state++;
++ } else if ( idle_state == 4 ) {
++ // setup OpenGL view parameters
++ fgInitVisuals();
++
++ if ( use_signals ) {
++ // init timer routines, signals, etc. Arrange for an alarm
++ // signal to be generated, etc.
++ fgInitTimeDepCalcs();
++ }
++
++ idle_state++;
++ } else if ( idle_state == 5 ) {
++
++ idle_state++;
++ } else if ( idle_state == 6 ) {
++ // Initialize audio support
++#ifdef ENABLE_AUDIO_SUPPORT
++
++#if !defined(WIN32)
++ if ( current_options.get_intro_music() ) {
++ // Let's wait for mpg123 to finish
++ string lockfile = "/tmp/mpg123.running";
++ struct stat stat_buf;
++
++ FG_LOG( FG_GENERAL, FG_INFO,
++ "Waiting for mpg123 player to finish ..." );
++ while ( stat(lockfile.c_str(), &stat_buf) == 0 ) {
++ // file exist, wait ...
++ sleep(1);
++ FG_LOG( FG_GENERAL, FG_INFO, ".");
++ }
++ FG_LOG( FG_GENERAL, FG_INFO, "");
++ }
++#endif // WIN32
++
++ audio_sched = new slScheduler ( 8000 );
++ audio_mixer = new smMixer;
++ audio_mixer -> setMasterVolume ( 80 ) ; /* 80% of max volume. */
++ audio_sched -> setSafetyMargin ( 1.0 ) ;
++ string slfile = current_options.get_fg_root() + "/Sounds/wasp.wav";
++
++ s1 = new slSample ( (char *)slfile.c_str() );
++ FG_LOG( FG_GENERAL, FG_INFO,
++ "Rate = " << s1 -> getRate()
++ << " Bps = " << s1 -> getBps()
++ << " Stereo = " << s1 -> getStereo() );
++ audio_sched -> loopSample ( s1 );
++
++ if ( audio_sched->not_working() ) {
++ // skip
++ } else {
++ pitch_envelope.setStep ( 0, 0.01, 0.6 );
++ volume_envelope.setStep ( 0, 0.01, 0.6 );
++
++ audio_sched -> addSampleEnvelope( s1, 0, 0, &
++ pitch_envelope,
++ SL_PITCH_ENVELOPE );
++ audio_sched -> addSampleEnvelope( s1, 0, 1,
++ &volume_envelope,
++ SL_VOLUME_ENVELOPE );
++ }
++
++ // strcpy(slfile, path);
++ // strcat(slfile, "thunder.wav");
++ // s2 -> loadFile ( slfile );
++ // s2 -> adjustVolume(0.5);
++ // audio_sched -> playSample ( s2 );
++#endif
++
++ // sleep(1);
++ idle_state = 1000;
++ }
++
++ if ( idle_state == 1000 ) {
++ // We've finished all our initialization steps, from now on we
++ // run the main loop.
++
++ fgMainLoop();
++ } else {
++ if ( current_options.get_splash_screen() == 1 ) {
++ fgSplashUpdate(0.0);
++ }
++ }
++}
++
++
++// Handle new window size or exposure
++static void fgReshape( int width, int height ) {
++ // Do this so we can call fgReshape(0,0) ourselves without having
++ // to know what the values of width & height are.
++ if ( (height > 0) && (width > 0) ) {
++ if ( ! current_options.get_panel_status() ) {
++ current_view.set_win_ratio( (GLfloat) width / (GLfloat) height );
++ } else {
++ current_view.set_win_ratio( (GLfloat) width /
++ ((GLfloat) (height)*0.4232) );
++ }
++ }
++
++ current_view.set_winWidth( width );
++ current_view.set_winHeight( height );
++ current_view.force_update_fov_math();
++
++ // Inform gl of our view window size (now handled elsewhere)
++ // xglViewport(0, 0, (GLint)width, (GLint)height);
++ if ( idle_state == 1000 ) {
++ // yes we've finished all our initializations and are running
++ // the main loop, so this will now work without seg faulting
++ // the system.
++ current_view.UpdateViewParams();
++ if ( current_options.get_panel_status() ) {
++ FGPanel::OurPanel->ReInit(0, 0, 1024, 768);
++ }
++ }
++}
++
++
++// Initialize GLUT and define a main window
++int fgGlutInit( int *argc, char **argv ) {
++ // GLUT will extract all glut specific options so later on we only
++ // need wory about our own.
++ xglutInit(argc, argv);
++
++ // Define Display Parameters
++ xglutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );
++
++ FG_LOG( FG_GENERAL, FG_INFO, "Opening a window: " <<
++ current_options.get_xsize() << "x" << current_options.get_ysize() );
++
++ // Define initial window size
++ xglutInitWindowSize( current_options.get_xsize(),
++ current_options.get_ysize() );
++
++ // Initialize windows
++ if ( current_options.get_game_mode() == 0 ) {
++ // Open the regular window
++ xglutCreateWindow("Flight Gear");
++ } else {
++ // Open the cool new 'game mode' window
++ char game_mode_str[256];
++ sprintf( game_mode_str, "width=%d height=%d bpp=16",
++ current_options.get_xsize(),
++ current_options.get_ysize() );
++
++ FG_LOG( FG_GENERAL, FG_INFO,
++ "game mode params = " << game_mode_str );
++ glutGameModeString( game_mode_str );
++ glutEnterGameMode();
++ }
++
++ // This seems to be the absolute earliest in the init sequence
++ // that these calls will return valid info. Too bad it's after
++ // we've already created and sized out window. :-(
++ general.set_glVendor( (char *)glGetString ( GL_VENDOR ) );
++ general.set_glRenderer( (char *)glGetString ( GL_RENDERER ) );
++ general.set_glVersion( (char *)glGetString ( GL_VERSION ) );
++
++ FG_LOG ( FG_GENERAL, FG_INFO, general.get_glRenderer() );
++
++#if 0
++ // try to determine if we should adjust the initial default
++ // display resolution. The options class defaults (is
++ // initialized) to 640x480.
++ string renderer = general.glRenderer;
++
++ // currently we only know how to deal with Mesa/Glide/Voodoo cards
++ if ( renderer.find( "Glide" ) != string::npos ) {
++ FG_LOG( FG_GENERAL, FG_INFO, "Detected a Glide driver" );
++ if ( renderer.find( "FB/8" ) != string::npos ) {
++ // probably a voodoo-2
++ if ( renderer.find( "TMU/SLI" ) != string::npos ) {
++ // probably two SLI'd Voodoo-2's
++ current_options.set_xsize( 1024 );
++ current_options.set_ysize( 768 );
++ FG_LOG( FG_GENERAL, FG_INFO,
++ "It looks like you have two sli'd voodoo-2's." << endl
++ << "upgrading your win resolution to 1024 x 768" );
++ glutReshapeWindow(1024, 768);
++ } else {
++ // probably a single non-SLI'd Voodoo-2
++ current_options.set_xsize( 800 );
++ current_options.set_ysize( 600 );
++ FG_LOG( FG_GENERAL, FG_INFO,
++ "It looks like you have a voodoo-2." << endl
++ << "upgrading your win resolution to 800 x 600" );
++ glutReshapeWindow(800, 600);
++ }
++ } else if ( renderer.find( "FB/2" ) != string::npos ) {
++ // probably a voodoo-1, stick with the default
++ }
++ } else {
++ // we have no special knowledge of this card, stick with the default
++ }
++#endif
++
++ return(1);
++}
++
++
++// Initialize GLUT event handlers
++int fgGlutInitEvents( void ) {
++ // call fgReshape() on window resizes
++ xglutReshapeFunc( fgReshape );
++
++ // call GLUTkey() on keyboard event
++ xglutKeyboardFunc( GLUTkey );
++ glutSpecialFunc( GLUTspecialkey );
++
++ // call guiMouseFunc() whenever our little rodent is used
++ glutMouseFunc ( guiMouseFunc );
++ glutMotionFunc (guiMotionFunc );
++ glutPassiveMotionFunc (guiMotionFunc );
++
++ // call fgMainLoop() whenever there is
++ // nothing else to do
++ xglutIdleFunc( fgIdleFunction );
++
++ // draw the scene
++ xglutDisplayFunc( fgRenderFrame );
++
++ return(1);
++}
++
++
++// Main ...
++int main( int argc, char **argv ) {
++ FGInterface *f;
++
++ f = current_aircraft.fdm_state;
++
++#ifdef HAVE_BC5PLUS
++ _control87(MCW_EM, MCW_EM); /* defined in float.h */
++#endif
++
++ // set default log levels
++ fglog().setLogLevels( FG_ALL, FG_INFO );
++
++ FG_LOG( FG_GENERAL, FG_INFO, "Flight Gear: Version " << VERSION << endl );
++
++ string root;
++
++ FG_LOG( FG_GENERAL, FG_INFO, "General Initialization" );
++ FG_LOG( FG_GENERAL, FG_INFO, "======= ==============" );
++
++ // seed the random number generater
++ fg_srandom();
++
++ // Attempt to locate and parse a config file
++ // First check fg_root
++ string config = current_options.get_fg_root() + "/system.fgfsrc";
++ current_options.parse_config_file( config );
++
++ // Next check home directory
++ char* envp = ::getenv( "HOME" );
++ if ( envp != NULL ) {
++ config = envp;
++ config += "/.fgfsrc";
++ current_options.parse_config_file( config );
++ }
++
++ // Parse remaining command line options
++ // These will override anything specified in a config file
++ if ( current_options.parse_command_line(argc, argv) !=
++ fgOPTIONS::FG_OPTIONS_OK )
++ {
++ // Something must have gone horribly wrong with the command
++ // line parsing or maybe the user just requested help ... :-)
++ current_options.usage();
++ FG_LOG( FG_GENERAL, FG_ALERT, "\nExiting ...");
++ exit(-1);
++ }
++
++ // Initialize the Window/Graphics environment.
++ if( !fgGlutInit(&argc, argv) ) {
++ FG_LOG( FG_GENERAL, FG_ALERT, "GLUT initialization failed ..." );
++ exit(-1);
++ }
++
++ // Initialize the various GLUT Event Handlers.
++ if( !fgGlutInitEvents() ) {
++ FG_LOG( FG_GENERAL, FG_ALERT,
++ "GLUT event handler initialization failed ..." );
++ exit(-1);
++ }
++
++ // First do some quick general initializations
++ if( !fgInitGeneral()) {
++ FG_LOG( FG_GENERAL, FG_ALERT,
++ "General initializations failed ..." );
++ exit(-1);
++ }
++
++ // Init the user interface (we need to do this before passing off
++ // control to glut
++ guiInit();
++
++ // pass control off to the master GLUT event handler
++ glutMainLoop();
++
++ // we never actually get here ... but just in case ... :-)
++ return(0);
++}
++
++
++// $Log$
++// Revision 1.88 1999/04/03 04:21:02 curt
++// Integration of Steve's plib conglomeration.
++// Optimizations (tm) by Norman Vine.
++//
++// Revision 1.87 1999/03/08 21:56:37 curt
++// Added panel changes sent in by Friedemann.
++// Added a splash screen randomization since we have several nice splash screens.
++//
++// Revision 1.86 1999/02/26 22:09:47 curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.85 1999/02/05 21:29:08 curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.84 1999/02/02 20:13:34 curt
++// MSVC++ portability changes by Bernie Bright:
++//
++// Lib/Serial/serial.[ch]xx: Initial Windows support - incomplete.
++// Simulator/Astro/stars.cxx: typo? included <stdio> instead of <cstdio>
++// Simulator/Cockpit/hud.cxx: Added Standard headers
++// Simulator/Cockpit/panel.cxx: Redefinition of default parameter
++// Simulator/Flight/flight.cxx: Replaced cout with FG_LOG. Deleted <stdio.h>
++// Simulator/Main/fg_init.cxx:
++// Simulator/Main/GLUTmain.cxx:
++// Simulator/Main/options.hxx: Shuffled <fg_serial.hxx> dependency
++// Simulator/Objects/material.hxx:
++// Simulator/Time/timestamp.hxx: VC++ friend kludge
++// Simulator/Scenery/tile.[ch]xx: Fixed using std::X declarations
++// Simulator/Main/views.hxx: Added a constant
++//
++// Revision 1.83 1999/01/27 04:49:17 curt
++// Game mode fixes from Norman Vine.
++// Initial altitude setting tweaks and fixes (especially for when starting
++// below sea level.)
++//
++// Revision 1.82 1999/01/20 13:42:24 curt
++// Tweaked FDM interface.
++// Testing check sum support for NMEA serial output.
++//
++// Revision 1.81 1999/01/19 20:57:03 curt
++// MacOS portability changes contributed by "Robert Puyol" <puyol@abvent.fr>
++//
++// Revision 1.80 1999/01/09 13:37:40 curt
++// Convert fgTIMESTAMP to FGTimeStamp which holds usec instead of ms.
++//
++// Revision 1.79 1999/01/08 03:23:56 curt
++// Beginning work on compensating for sim time vs. real world time "jitter".
++//
++// Revision 1.78 1999/01/07 20:25:08 curt
++// Updated struct fgGENERAL to class FGGeneral.
++//
++// Revision 1.77 1998/12/18 23:40:55 curt
++// New frame rate counting mechanism.
++//
++// Revision 1.76 1998/12/11 20:26:26 curt
++// Fixed view frustum culling accuracy bug so we can look out the sides and
++// back without tri-stripes dropping out.
++//
++// Revision 1.75 1998/12/09 18:50:23 curt
++// Converted "class fgVIEW" to "class FGView" and updated to make data
++// members private and make required accessor functions.
++//
++// Revision 1.74 1998/12/06 14:52:54 curt
++// Fixed a problem with the initial starting altitude. "v->abs_view_pos" wasn't
++// being calculated correctly at the beginning causing the first terrain
++// intersection to fail, returning a ground altitude of zero, causing the plane
++// to free fall for one frame, until the ground altitude was corrected, but now
++// being under the ground we got a big bounce and the plane always ended up
++// upside down.
++//
++// Revision 1.73 1998/12/06 13:51:22 curt
++// Turned "struct fgWEATHER" into "class FGWeather".
++//
++// Revision 1.72 1998/12/05 15:54:18 curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.71 1998/12/05 14:19:51 curt
++// Looking into a problem with cur_view_params.abs_view_pos initialization.
++//
++// Revision 1.70 1998/12/03 01:17:14 curt
++// Converted fgFLIGHT to a class.
++//
++// Revision 1.69 1998/11/23 20:51:26 curt
++// Fiddling with when I can get info from the opengl driver.
++//
++// Revision 1.68 1998/11/20 01:02:35 curt
++// Try to detect Mesa/Glide/Voodoo and chose the appropriate resolution.
++//
++// Revision 1.67 1998/11/16 13:59:58 curt
++// Added pow() macro bug work around.
++// Added support for starting FGFS at various resolutions.
++// Added some initial serial port support.
++// Specify default log levels in main().
++//
++// Revision 1.66 1998/11/11 00:24:00 curt
++// Added Michael Johnson's audio patches for testing.
++// Also did a few tweaks to avoid numerical problems when starting at a place
++// with no (or bogus) scenery.
++//
++// Revision 1.65 1998/11/09 23:39:22 curt
++// Tweaks for the instrument panel.
++//
++// Revision 1.64 1998/11/07 19:07:09 curt
++// Enable release builds using the --without-logging option to the configure
++// script. Also a couple log message cleanups, plus some C to C++ comment
++// conversion.
++//
++// Revision 1.63 1998/11/06 21:18:08 curt
++// Converted to new logstream debugging facility. This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.62 1998/10/27 02:14:35 curt
++// Changes to support GLUT joystick routines as fall back.
++//
++// Revision 1.61 1998/10/25 14:08:47 curt
++// Turned "struct fgCONTROLS" into a class, with inlined accessor functions.
++//
++// Revision 1.60 1998/10/25 10:57:18 curt
++// Changes to use the new joystick library if it is available.
++//
++// Revision 1.59 1998/10/17 01:34:21 curt
++// C++ ifying ...
++//
++// Revision 1.58 1998/10/16 23:27:52 curt
++// C++-ifying.
++//
++// Revision 1.57 1998/10/16 00:54:00 curt
++// Converted to Point3D class.
++//
++// Revision 1.56 1998/10/02 12:46:47 curt
++// Added an "auto throttle"
++//
++// Revision 1.55 1998/09/29 14:58:18 curt
++// Use working() instead of !not_working() for audio.
++//
++// Revision 1.54 1998/09/29 02:03:38 curt
++// Autopilot mods.
++//
++// Revision 1.53 1998/09/26 13:18:35 curt
++// Check if audio "working()" before doing audio manipulations.
++//
++// Revision 1.52 1998/09/25 16:02:07 curt
++// Added support for pitch and volume envelopes and tied them to the
++// throttle setting.
++//
++// Revision 1.51 1998/09/15 04:27:28 curt
++// Changes for new Astro code.
++//
++// Revision 1.50 1998/09/15 02:09:24 curt
++// Include/fg_callback.hxx
++// Moved code inline to stop g++ 2.7 from complaining.
++//
++// Simulator/Time/event.[ch]xx
++// Changed return type of fgEVENT::printStat(). void caused g++ 2.7 to
++// complain bitterly.
++//
++// Minor bugfix and changes.
++//
++// Simulator/Main/GLUTmain.cxx
++// Added missing type to idle_state definition - eliminates a warning.
++//
++// Simulator/Main/fg_init.cxx
++// Changes to airport lookup.
++//
++// Simulator/Main/options.cxx
++// Uses fg_gzifstream when loading config file.
++//
++// Revision 1.49 1998/09/09 16:25:39 curt
++// Only use GLUT_STENCIL if the instument panel has been requested.
++//
++// Revision 1.48 1998/08/28 18:15:03 curt
++// Added new cockpit code from Friedemann Reinhard
++// <mpt218@faupt212.physik.uni-erlangen.de>
++//
++// Revision 1.47 1998/08/27 17:02:04 curt
++// Contributions from Bernie Bright <bbright@c031.aone.net.au>
++// - use strings for fg_root and airport_id and added methods to return
++// them as strings,
++// - inlined all access methods,
++// - made the parsing functions private methods,
++// - deleted some unused functions.
++// - propogated some of these changes out a bit further.
++//
++// Revision 1.46 1998/08/22 14:49:56 curt
++// Attempting to iron out seg faults and crashes.
++// Did some shuffling to fix a initialization order problem between view
++// position, scenery elevation.
++//
++// Revision 1.45 1998/08/20 20:32:31 curt
++// Reshuffled some of the code in and around views.[ch]xx
++//
++// Revision 1.44 1998/08/20 15:10:33 curt
++// Added GameGLUT support.
++//
++// Revision 1.43 1998/08/12 21:01:47 curt
++// Master volume from 30% -> 80%
++//
++// Revision 1.42 1998/07/30 23:48:25 curt
++// Output position & orientation when pausing.
++// Eliminated libtool use.
++// Added options to specify initial position and orientation.
++// Changed default fov to 55 degrees.
++// Added command line option to start in paused or unpaused state.
++//
++// Revision 1.41 1998/07/27 18:41:24 curt
++// Added a pause command "p"
++// Fixed some initialization order problems between pui and glut.
++// Added an --enable/disable-sound option.
++//
++// Revision 1.40 1998/07/24 21:56:59 curt
++// Set near clip plane to 0.5 meters when close to the ground. Also, let the view get a bit closer to the ground before hitting the hard limit.
++//
++// Revision 1.39 1998/07/24 21:39:08 curt
++// Debugging output tweaks.
++// Cast glGetString to (char *) to avoid compiler errors.
++// Optimizations to fgGluLookAt() by Norman Vine.
++//
++// Revision 1.38 1998/07/22 21:40:43 curt
++// Clear to adjusted fog color (for sunrise/sunset effects)
++// Make call to fog sunrise/sunset adjustment method.
++// Add a stdc++ library bug work around to fg_init.cxx
++//
++// Revision 1.37 1998/07/20 12:49:44 curt
++// Tweaked color buffer clearing defaults. We clear the color buffer if we
++// are doing textures. Assumptions: If we are doing textures we have hardware
++// support that can clear the color buffer for "free." If we are doing software
++// rendering with textures, then the extra clear time gets lost in the noise.
++//
++// Revision 1.36 1998/07/16 17:33:35 curt
++// "H" / "h" now control hud brightness as well with off being one of the
++// states.
++// Better checking for xmesa/fx 3dfx fullscreen/window support for deciding
++// whether or not to build in the feature.
++// Translucent menu support.
++// HAVE_AUDIO_SUPPORT -> ENABLE_AUDIO_SUPPORT
++// Use fork() / wait() for playing mp3 init music in background under unix.
++// Changed default tile diameter to 5.
++//
++// Revision 1.35 1998/07/13 21:01:36 curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.34 1998/07/13 15:32:37 curt
++// Clear color buffer if drawing wireframe.
++// When specifying and airport, start elevation at -1000 and let the system
++// position you at ground level.
++//
++// Revision 1.33 1998/07/12 03:14:42 curt
++// Added ground collision detection.
++// Did some serious horsing around to be able to "hug" the ground properly
++// and still be able to take off.
++// Set the near clip plane to 1.0 meters when less than 10 meters above the
++// ground.
++// Did some serious horsing around getting the initial airplane position to be
++// correct based on rendered terrain elevation.
++// Added a little cheat/hack that will prevent the view position from ever
++// dropping below the terrain, even when the flight model doesn't quite
++// put you as high as you'd like.
++//
++// Revision 1.32 1998/07/08 14:45:07 curt
++// polar3d.h renamed to polar3d.hxx
++// vector.h renamed to vector.hxx
++// updated audio support so it waits to create audio classes (and tie up
++// /dev/dsp) until the mpg123 player is finished.
++//
++// Revision 1.31 1998/07/06 21:34:17 curt
++// Added an enable/disable splash screen option.
++// Added an enable/disable intro music option.
++// Added an enable/disable instrument panel option.
++// Added an enable/disable mouse pointer option.
++// Added using namespace std for compilers that support this.
++//
++// Revision 1.30 1998/07/06 02:42:03 curt
++// Added support for switching between fullscreen and window mode for
++// Mesa/3dfx/glide.
++//
++// Added a basic splash screen. Restructured the main loop and top level
++// initialization routines to do this.
++//
++// Hacked in some support for playing a startup mp3 sound file while rest
++// of sim initializes. Currently only works in Unix using the mpg123 player.
++// Waits for the mpg123 player to finish before initializing internal
++// sound drivers.
++//
++// Revision 1.29 1998/07/04 00:52:22 curt
++// Add my own version of gluLookAt() (which is nearly identical to the
++// Mesa/glu version.) But, by calculating the Model View matrix our selves
++// we can save this matrix without having to read it back in from the video
++// card. This hopefully allows us to save a few cpu cycles when rendering
++// out the fragments because we can just use glLoadMatrixd() with the
++// precalculated matrix for each tile rather than doing a push(), translate(),
++// pop() for every fragment.
++//
++// Panel status defaults to off for now until it gets a bit more developed.
++//
++// Extract OpenGL driver info on initialization.
++//
++// Revision 1.28 1998/06/27 16:54:32 curt
++// Replaced "extern displayInstruments" with a entry in fgOPTIONS.
++// Don't change the view port when displaying the panel.
++//
++// Revision 1.27 1998/06/17 21:35:10 curt
++// Refined conditional audio support compilation.
++// Moved texture parameter setup calls to ../Scenery/materials.cxx
++// #include <string.h> before various STL includes.
++// Make HUD default state be enabled.
++//
++// Revision 1.26 1998/06/13 00:40:32 curt
++// Tweaked fog command line options.
++//
++// Revision 1.25 1998/06/12 14:27:26 curt
++// Pui -> PUI, Gui -> GUI.
++//
++// Revision 1.24 1998/06/12 00:57:39 curt
++// Added support for Pui/Gui.
++// Converted fog to GL_FOG_EXP2.
++// Link to static simulator parts.
++// Update runfg.bat to try to be a little smarter.
++//
++// Revision 1.23 1998/06/08 17:57:04 curt
++// Minor sound/startup position tweaks.
++//
++// Revision 1.22 1998/06/05 18:18:40 curt
++// A bit of fiddling with audio ...
++//
++// Revision 1.21 1998/06/03 22:01:06 curt
++// Tweaking sound library usage.
++//
++// Revision 1.20 1998/06/03 00:47:11 curt
++// Updated to compile in audio support if OSS available.
++// Updated for new version of Steve's audio library.
++// STL includes don't use .h
++// Small view optimizations.
++//
++// Revision 1.19 1998/06/01 17:54:40 curt
++// Added Linux audio support.
++// avoid glClear( COLOR_BUFFER_BIT ) when not using it to set the sky color.
++// map stl tweaks.
++//
++// Revision 1.18 1998/05/29 20:37:19 curt
++// Tweaked material properties & lighting a bit in GLUTmain.cxx.
++// Read airport list into a "map" STL for dynamic list sizing and fast tree
++// based lookups.
++//
++// Revision 1.17 1998/05/22 21:28:52 curt
++// Modifications to use the new fgEVENT_MGR class.
++//
++// Revision 1.16 1998/05/20 20:51:33 curt
++// Tweaked smooth shaded texture lighting properties.
++// Converted fgLIGHT to a C++ class.
++//
++// Revision 1.15 1998/05/16 13:08:34 curt
++// C++ - ified views.[ch]xx
++// Shuffled some additional view parameters into the fgVIEW class.
++// Changed tile-radius to tile-diameter because it is a much better
++// name.
++// Added a WORLD_TO_EYE transformation to views.cxx. This allows us
++// to transform world space to eye space for view frustum culling.
++//
++// Revision 1.14 1998/05/13 18:29:57 curt
++// Added a keyboard binding to dynamically adjust field of view.
++// Added a command line option to specify fov.
++// Adjusted terrain color.
++// Root path info moved to fgOPTIONS.
++// Added ability to parse options out of a config file.
++//
++// Revision 1.13 1998/05/11 18:18:15 curt
++// For flat shading use "glHint (GL_FOG_HINT, GL_FASTEST )"
++//
++// Revision 1.12 1998/05/07 23:14:15 curt
++// Added "D" key binding to set autopilot heading.
++// Made frame rate calculation average out over last 10 frames.
++// Borland C++ floating point exception workaround.
++// Added a --tile-radius=n option.
++//
++// Revision 1.11 1998/05/06 03:16:23 curt
++// Added an averaged global frame rate counter.
++// Added an option to control tile radius.
++//
++// Revision 1.10 1998/05/03 00:47:31 curt
++// Added an option to enable/disable full-screen mode.
++//
++// Revision 1.9 1998/04/30 12:34:17 curt
++// Added command line rendering options:
++// enable/disable fog/haze
++// specify smooth/flat shading
++// disable sky blending and just use a solid color
++// enable wireframe drawing mode
++//
++// Revision 1.8 1998/04/28 01:20:21 curt
++// Type-ified fgTIME and fgVIEW.
++// Added a command line option to disable textures.
++//
++// Revision 1.7 1998/04/26 05:10:02 curt
++// "struct fgLIGHT" -> "fgLIGHT" because fgLIGHT is typedef'd.
++//
++// Revision 1.6 1998/04/25 22:06:30 curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.5 1998/04/25 20:24:01 curt
++// Cleaned up initialization sequence to eliminate interdependencies
++// between sun position, lighting, and view position. This creates a
++// valid single pass initialization path.
++//
++// Revision 1.4 1998/04/24 14:19:30 curt
++// Fog tweaks.
++//
++// Revision 1.3 1998/04/24 00:49:18 curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Trying out some different option parsing code.
++// Some code reorganization.
++//
++// Revision 1.2 1998/04/22 13:25:41 curt
++// C++ - ifing the code.
++// Starting a bit of reorganization of lighting code.
++//
++// Revision 1.1 1998/04/21 17:02:39 curt
++// Prepairing for C++ integration.
++//
++// Revision 1.71 1998/04/18 04:11:26 curt
++// Moved fg_debug to it's own library, added zlib support.
++//
++// Revision 1.70 1998/04/14 02:21:02 curt
++// Incorporated autopilot heading hold contributed by: Jeff Goeke-Smith
++// <jgoeke@voyager.net>
++//
++// Revision 1.69 1998/04/08 23:35:34 curt
++// Tweaks to Gnu automake/autoconf system.
++//
++// Revision 1.68 1998/04/03 22:09:03 curt
++// Converting to Gnu autoconf system.
++//
++// Revision 1.67 1998/03/23 21:24:37 curt
++// Source code formating tweaks.
++//
++// Revision 1.66 1998/03/14 00:31:20 curt
++// Beginning initial terrain texturing experiments.
++//
++// Revision 1.65 1998/03/09 22:45:57 curt
++// Minor tweaks for building on sparc platform.
++//
++// Revision 1.64 1998/02/20 00:16:23 curt
++// Thursday's tweaks.
++//
++// Revision 1.63 1998/02/16 16:17:39 curt
++// Minor tweaks.
++//
++// Revision 1.62 1998/02/16 13:39:42 curt
++// Miscellaneous weekend tweaks. Fixed? a cache problem that caused whole
++// tiles to occasionally be missing.
++//
++// Revision 1.61 1998/02/12 21:59:46 curt
++// Incorporated code changes contributed by Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.60 1998/02/11 02:50:40 curt
++// Minor changes.
++//
++// Revision 1.59 1998/02/09 22:56:54 curt
++// Removed "depend" files from cvs control. Other minor make tweaks.
++//
++// Revision 1.58 1998/02/09 15:07:49 curt
++// Minor tweaks.
++//
++// Revision 1.57 1998/02/07 15:29:40 curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.56 1998/02/03 23:20:23 curt
++// Lots of little tweaks to fix various consistency problems discovered by
++// Solaris' CC. Fixed a bug in fg_debug.c with how the fgPrintf() wrapper
++// passed arguments along to the real printf(). Also incorporated HUD changes
++// by Michele America.
++//
++// Revision 1.55 1998/02/02 20:53:58 curt
++// Incorporated Durk's changes.
++//
++// Revision 1.54 1998/01/31 00:43:10 curt
++// Added MetroWorks patches from Carmen Volpe.
++//
++// Revision 1.53 1998/01/27 18:35:54 curt
++// Minor tweaks.
++//
++// Revision 1.52 1998/01/27 00:47:56 curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.51 1998/01/26 15:57:05 curt
++// Tweaks for dynamic scenery development.
++//
++// Revision 1.50 1998/01/19 19:27:07 curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.49 1998/01/19 18:40:31 curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.48 1998/01/19 18:35:46 curt
++// Minor tweaks and fixes for cygwin32.
++//
++// Revision 1.47 1998/01/13 00:23:08 curt
++// Initial changes to support loading and management of scenery tiles. Note,
++// there's still a fair amount of work left to be done.
++//
++// Revision 1.46 1998/01/08 02:22:06 curt
++// Beginning to integrate Tile management subsystem.
++//
++// Revision 1.45 1998/01/07 03:18:55 curt
++// Moved astronomical stuff from .../Src/Scenery to .../Src/Astro/
++//
++// Revision 1.44 1997/12/30 22:22:31 curt
++// Further integration of event manager.
++//
++// Revision 1.43 1997/12/30 20:47:43 curt
++// Integrated new event manager with subsystem initializations.
++//
++// Revision 1.42 1997/12/30 16:36:47 curt
++// Merged in Durk's changes ...
++//
++// Revision 1.41 1997/12/30 13:06:56 curt
++// A couple lighting tweaks ...
++//
++// Revision 1.40 1997/12/30 01:38:37 curt
++// Switched back to per vertex normals and smooth shading for terrain.
++//
++// Revision 1.39 1997/12/22 23:45:45 curt
++// First stab at sunset/sunrise sky glow effects.
++//
++// Revision 1.38 1997/12/22 04:14:28 curt
++// Aligned sky with sun so dusk/dawn effects can be correct relative to the sun.
++//
++// Revision 1.37 1997/12/19 23:34:03 curt
++// Lot's of tweaking with sky rendering and lighting.
++//
++// Revision 1.36 1997/12/19 16:44:57 curt
++// Working on scene rendering order and options.
++//
++// Revision 1.35 1997/12/18 23:32:32 curt
++// First stab at sky dome actually starting to look reasonable. :-)
++//
++// Revision 1.34 1997/12/17 23:13:34 curt
++// Began working on rendering a sky.
++//
++// Revision 1.33 1997/12/15 23:54:45 curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.32 1997/12/15 20:59:08 curt
++// Misc. tweaks.
++//
++// Revision 1.31 1997/12/12 21:41:25 curt
++// More light/material property tweaking ... still a ways off.
++//
++// Revision 1.30 1997/12/12 19:52:47 curt
++// Working on lightling and material properties.
++//
++// Revision 1.29 1997/12/11 04:43:54 curt
++// Fixed sun vector and lighting problems. I thing the moon is now lit
++// correctly.
++//
++// Revision 1.28 1997/12/10 22:37:45 curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.27 1997/12/09 05:11:54 curt
++// Working on tweaking lighting.
++//
++// Revision 1.26 1997/12/09 04:25:29 curt
++// Working on adding a global lighting params structure.
++//
++// Revision 1.25 1997/12/08 22:54:09 curt
++// Enabled GL_CULL_FACE.
++//
++// Revision 1.24 1997/11/25 19:25:32 curt
++// Changes to integrate Durk's moon/sun code updates + clean up.
++//
++// Revision 1.23 1997/11/15 18:16:34 curt
++// minor tweaks.
++//
++// Revision 1.22 1997/10/30 12:38:41 curt
++// Working on new scenery subsystem.
++//
++// Revision 1.21 1997/09/23 00:29:38 curt
++// Tweaks to get things to compile with gcc-win32.
++//
++// Revision 1.20 1997/09/22 14:44:19 curt
++// Continuing to try to align stars correctly.
++//
++// Revision 1.19 1997/09/18 16:20:08 curt
++// At dusk/dawn add/remove stars in stages.
++//
++// Revision 1.18 1997/09/16 22:14:51 curt
++// Tweaked time of day lighting equations. Don't draw stars during the day.
++//
++// Revision 1.17 1997/09/16 15:50:29 curt
++// Working on star alignment and time issues.
++//
++// Revision 1.16 1997/09/13 02:00:06 curt
++// Mostly working on stars and generating sidereal time for accurate star
++// placement.
++//
++// Revision 1.15 1997/09/05 14:17:27 curt
++// More tweaking with stars.
++//
++// Revision 1.14 1997/09/05 01:35:53 curt
++// Working on getting stars right.
++//
++// Revision 1.13 1997/09/04 02:17:34 curt
++// Shufflin' stuff.
++//
++// Revision 1.12 1997/08/27 21:32:24 curt
++// Restructured view calculation code. Added stars.
++//
++// Revision 1.11 1997/08/27 03:30:16 curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.10 1997/08/25 20:27:22 curt
++// Merged in initial HUD and Joystick code.
++//
++// Revision 1.9 1997/08/22 21:34:39 curt
++// Doing a bit of reorganizing and house cleaning.
++//
++// Revision 1.8 1997/08/19 23:55:03 curt
++// Worked on better simulating real lighting.
++//
++// Revision 1.7 1997/08/16 12:22:38 curt
++// Working on improving the lighting/shading.
++//
++// Revision 1.6 1997/08/13 20:24:56 curt
++// Changes due to changing sunpos interface.
++//
++// Revision 1.5 1997/08/06 21:08:32 curt
++// Sun position now really* works (I think) ... I still have sun time warping
++// code in place, probably should remove it soon.
++//
++// Revision 1.4 1997/08/06 15:41:26 curt
++// Working on correct sun position.
++//
++// Revision 1.3 1997/08/06 00:24:22 curt
++// Working on correct real time sun lighting.
++//
++// Revision 1.2 1997/08/04 20:25:15 curt
++// Organizational tweaking.
++//
++// Revision 1.1 1997/08/02 18:45:00 curt
++// Renamed GLmain.c GLUTmain.c
++//
++// Revision 1.43 1997/08/02 16:23:47 curt
++// Misc. tweaks.
++//
++// Revision 1.42 1997/08/01 19:43:33 curt
++// Making progress with coordinate system overhaul.
++//
++// Revision 1.41 1997/07/31 22:52:37 curt
++// Working on redoing internal coordinate systems & scenery transformations.
++//
++// Revision 1.40 1997/07/30 16:12:42 curt
++// Moved fg_random routines from Util/ to Math/
++//
++// Revision 1.39 1997/07/21 14:45:01 curt
++// Minor tweaks.
++//
++// Revision 1.38 1997/07/19 23:04:47 curt
++// Added an initial weather section.
++//
++// Revision 1.37 1997/07/19 22:34:02 curt
++// Moved PI definitions to ../constants.h
++// Moved random() stuff to ../Utils/ and renamed fg_random()
++//
++// Revision 1.36 1997/07/18 23:41:25 curt
++// Tweaks for building with Cygnus Win32 compiler.
++//
++// Revision 1.35 1997/07/18 14:28:34 curt
++// Hacked in some support for wind/turbulence.
++//
++// Revision 1.34 1997/07/16 20:04:48 curt
++// Minor tweaks to aid Win32 port.
++//
++// Revision 1.33 1997/07/12 03:50:20 curt
++// Added an #include <Windows32/Base.h> to help compiling for Win32
++//
++// Revision 1.32 1997/07/11 03:23:18 curt
++// Solved some scenery display/orientation problems. Still have a positioning
++// (or transformation?) problem.
++//
++// Revision 1.31 1997/07/11 01:29:58 curt
++// More tweaking of terrian floor.
++//
++// Revision 1.30 1997/07/10 04:26:37 curt
++// We now can interpolated ground elevation for any position in the grid. We
++// can use this to enforce a "hard" ground. We still need to enforce some
++// bounds checking so that we don't try to lookup data points outside the
++// grid data set.
++//
++// Revision 1.29 1997/07/09 21:31:12 curt
++// Working on making the ground "hard."
++//
++// Revision 1.28 1997/07/08 18:20:12 curt
++// Working on establishing a hard ground.
++//
++// Revision 1.27 1997/07/07 20:59:49 curt
++// Working on scenery transformations to enable us to fly fluidly over the
++// poles with no discontinuity/distortion in scenery.
++//
++// Revision 1.26 1997/07/05 20:43:34 curt
++// renamed mat3 directory to Math so we could add other math related routines.
++//
++// Revision 1.25 1997/06/29 21:19:17 curt
++// Working on scenery management system.
++//
++// Revision 1.24 1997/06/26 22:14:53 curt
++// Beginning work on a scenery management system.
++//
++// Revision 1.23 1997/06/26 19:08:33 curt
++// Restructuring make, adding automatic "make dep" support.
++//
++// Revision 1.22 1997/06/25 15:39:47 curt
++// Minor changes to compile with rsxnt/win32.
++//
++// Revision 1.21 1997/06/22 21:44:41 curt
++// Working on intergrating the VRML (subset) parser.
++//
++// Revision 1.20 1997/06/21 17:12:53 curt
++// Capitalized subdirectory names.
++//
++// Revision 1.19 1997/06/18 04:10:31 curt
++// A couple more runway tweaks ...
++//
++// Revision 1.18 1997/06/18 02:21:24 curt
++// Hacked in a runway
++//
++// Revision 1.17 1997/06/17 16:51:58 curt
++// Timer interval stuff now uses gettimeofday() instead of ftime()
++//
++// Revision 1.16 1997/06/17 04:19:16 curt
++// More timer related tweaks with respect to view direction changes.
++//
++// Revision 1.15 1997/06/17 03:41:10 curt
++// Nonsignal based interval timing is now working.
++// This would be a good time to look at cleaning up the code structure a bit.
++//
++// Revision 1.14 1997/06/16 19:32:51 curt
++// Starting to add general timer support.
++//
++// Revision 1.13 1997/06/02 03:40:06 curt
++// A tiny bit more view tweaking.
++//
++// Revision 1.12 1997/06/02 03:01:38 curt
++// Working on views (side, front, back, transitions, etc.)
++//
++// Revision 1.11 1997/05/31 19:16:25 curt
++// Elevator trim added.
++//
++// Revision 1.10 1997/05/31 04:13:52 curt
++// WE CAN NOW FLY!!!
++//
++// Continuing work on the LaRCsim flight model integration.
++// Added some MSFS-like keyboard input handling.
++//
++// Revision 1.9 1997/05/30 19:27:01 curt
++// The LaRCsim flight model is starting to look like it is working.
++//
++// Revision 1.8 1997/05/30 03:54:10 curt
++// Made a bit more progress towards integrating the LaRCsim flight model.
++//
++// Revision 1.7 1997/05/29 22:39:49 curt
++// Working on incorporating the LaRCsim flight model.
++//
++// Revision 1.6 1997/05/29 12:31:39 curt
++// Minor tweaks, moving towards general flight model integration.
++//
++// Revision 1.5 1997/05/29 02:33:23 curt
++// Updated to reflect changing interfaces in other "modules."
++//
++// Revision 1.4 1997/05/27 17:44:31 curt
++// Renamed & rearranged variables and routines. Added some initial simple
++// timer/alarm routines so the flight model can be updated on a regular
++// interval.
++//
++// Revision 1.3 1997/05/23 15:40:25 curt
++// Added GNU copyright headers.
++// Fog now works!
++//
++// Revision 1.2 1997/05/23 00:35:12 curt
++// Trying to get fog to work ...
++//
++// Revision 1.1 1997/05/21 15:57:51 curt
++// Renamed due to added GLUT support.
++//
++// Revision 1.3 1997/05/19 18:22:42 curt
++// Parameter tweaking ... starting to stub in fog support.
++//
++// Revision 1.2 1997/05/17 00:17:34 curt
++// Trying to stub in support for standard OpenGL.
++//
++// Revision 1.1 1997/05/16 16:05:52 curt
++// Initial revision.
++//
--- /dev/null
--- /dev/null
++if ENABLE_AUDIO_SUPPORT
++DEFS += -DENABLE_AUDIO_SUPPORT
++AUDIO_LIBS = -L$(top_builddir)/Lib/plib/src/sl -lsl -lsm
++endif
++
++if ENABLE_IRIX_AUDIO
++LIBS += -laudio
++endif
++
++if ENABLE_WIN32_AUDIO
++LIBS += -lwinmm
++endif
++
++if ENABLE_LINUX_JOYSTICK
++DEFS += -DENABLE_LINUX_JOYSTICK
++else
++DEFS += -DENABLE_GLUT_JOYSTICK
++endif
++
++if ENABLE_XMESA_FX
++DEFS += -DXMESA -DFX
++endif
++
++if ENABLE_UNIX_SERIAL
++SERIAL_LIBS = $(top_builddir)/Lib/Serial/libSerial.a
++else
++SERIAL_LIBS =
++endif
++
++EXTRA_DIST = runfgfs.in runfgfs.bat.in
++
++bin_PROGRAMS = fgfs
++
++bin_SCRIPTS = runfgfs runfgfs.bat
++
++fgfs_SOURCES = \
++ GLUTkey.cxx GLUTkey.hxx GLUTmain.cxx \
++ fg_config.h \
++ fg_init.cxx fg_init.hxx \
++ fg_serial.cxx fg_serial.hxx \
++ options.cxx options.hxx \
++ splash.cxx splash.hxx \
++ views.cxx views.hxx
++
++fgfs_LDADD = \
++ $(top_builddir)/Simulator/Aircraft/libAircraft.a \
++ $(top_builddir)/Simulator/Astro/libAstro.a \
++ $(top_builddir)/Simulator/Autopilot/libAutopilot.a \
++ $(top_builddir)/Simulator/Cockpit/libCockpit.a \
++ $(top_builddir)/Simulator/Controls/libControls.a \
++ $(top_builddir)/Simulator/FDM/libFlight.a \
++ $(top_builddir)/Simulator/FDM/External/libExternal.a \
++ $(top_builddir)/Simulator/FDM/JSBsim/libJSBsim.a \
++ $(top_builddir)/Simulator/FDM/LaRCsim/libLaRCsim.a \
++ $(top_builddir)/Simulator/FDM/Slew/libSlew.a \
++ $(top_builddir)/Simulator/GUI/libGUI.a \
++ $(top_builddir)/Simulator/Scenery/libScenery.a \
++ $(top_builddir)/Simulator/Airports/libAirports.a \
++ $(top_builddir)/Simulator/Objects/libObjects.a \
++ $(top_builddir)/Simulator/Time/libTime.a \
++ $(top_builddir)/Simulator/Weather/libWeather.a \
++ $(top_builddir)/Simulator/Joystick/libJoystick.a \
++ $(AUDIO_LIBS) \
++ $(SERIAL_LIBS) \
++ $(top_builddir)/Lib/Math/libMath.a \
++ $(top_builddir)/Lib/Bucket/libBucket.a \
++ $(top_builddir)/Lib/Debug/libDebug.a \
++ -L$(top_builddir)/Lib/plib/src/pui -lpu \
++ $(top_builddir)/Lib/zlib/libz.a \
++ $(top_builddir)/Lib/Misc/libMisc.a \
++ $(opengl_LIBS)
++
++INCLUDES += \
++ -I$(top_builddir) \
++ -I$(top_builddir)/Lib \
++ -I$(top_builddir)/Lib/plib/include \
++ -I$(top_builddir)/Simulator
--- /dev/null
--- /dev/null
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++# include <config.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 );
++ }
++
++ f->set_sin_cos_longitude(current_options.get_lon() * DEG_TO_RAD);
++ f->set_sin_cos_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 )
++{
++ FGInterface *f; // assigned later
++ fgLIGHT *l = &cur_light_params;
++ fgTIME *t = &cur_time_params;
++ FGView *v = ¤t_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 );
++
++ // 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
++ fgTimeInit(t);
++ fgTimeUpdate(f, t);
++
++ // 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( ¤t_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(¤t_aircraft);
++
++ // Initialize serial ports
++ fgSerialInit();
++
++ FG_LOG( FG_GENERAL, FG_INFO, endl);
++
++ return(1);
++}
++
++
++// $Log$
++// Revision 1.72 1999/04/05 02:13:58 curt
++// Minor patch from Norman Vine.
++//
++// Revision 1.71 1999/03/22 02:08:13 curt
++// Changes contributed by Durk Talsma:
++//
++// Here's a few changes I made to fg-0.58 this weekend. Included are the
++// following features:
++// - Sun and moon have a halo
++// - The moon has a light vector, moon_angle, etc. etc. so that we can have
++// some moonlight during the night.
++// - Lot's of small changes tweakes, including some stuff Norman Vine sent
++// me earlier.
++//
++// Revision 1.70 1999/03/11 23:09:49 curt
++// When "Help" is selected from the menu check to see if netscape is running.
++// If so, command it to go to the flight gear user guide url. Otherwise
++// start a new version of netscape with this url.
++//
++// Revision 1.69 1999/03/08 21:56:39 curt
++// Added panel changes sent in by Friedemann.
++// Added a splash screen randomization since we have several nice splash screens.
++//
++// Revision 1.68 1999/03/02 01:03:15 curt
++// Tweaks for building with native SGI compilers.
++//
++// Revision 1.67 1999/02/26 22:09:48 curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.66 1999/02/05 21:29:10 curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.65 1999/02/02 20:13:36 curt
++// MSVC++ portability changes by Bernie Bright:
++//
++// Lib/Serial/serial.[ch]xx: Initial Windows support - incomplete.
++// Simulator/Astro/stars.cxx: typo? included <stdio> instead of <cstdio>
++// Simulator/Cockpit/hud.cxx: Added Standard headers
++// Simulator/Cockpit/panel.cxx: Redefinition of default parameter
++// Simulator/Flight/flight.cxx: Replaced cout with FG_LOG. Deleted <stdio.h>
++// Simulator/Main/fg_init.cxx:
++// Simulator/Main/GLUTmain.cxx:
++// Simulator/Main/options.hxx: Shuffled <fg_serial.hxx> dependency
++// Simulator/Objects/material.hxx:
++// Simulator/Time/timestamp.hxx: VC++ friend kludge
++// Simulator/Scenery/tile.[ch]xx: Fixed using std::X declarations
++// Simulator/Main/views.hxx: Added a constant
++//
++// Revision 1.64 1999/02/01 21:15:43 curt
++// Removed unused variables.
++//
++// Revision 1.63 1999/01/27 04:49:19 curt
++// Game mode fixes from Norman Vine.
++// Initial altitude setting tweaks and fixes (especially for when starting
++// below sea level.)
++//
++// Revision 1.62 1999/01/20 13:42:25 curt
++// Tweaked FDM interface.
++// Testing check sum support for NMEA serial output.
++//
++// Revision 1.61 1999/01/08 03:23:57 curt
++// Beginning work on compensating for sim time vs. real world time "jitter".
++//
++// Revision 1.60 1999/01/07 20:25:09 curt
++// Updated struct fgGENERAL to class FGGeneral.
++//
++// Revision 1.59 1998/12/18 23:40:57 curt
++// New frame rate counting mechanism.
++//
++// Revision 1.58 1998/12/09 18:50:25 curt
++// Converted "class fgVIEW" to "class FGView" and updated to make data
++// members private and make required accessor functions.
++//
++// Revision 1.57 1998/12/06 14:52:56 curt
++// Fixed a problem with the initial starting altitude. "v->abs_view_pos" wasn't
++// being calculated correctly at the beginning causing the first terrain
++// intersection to fail, returning a ground altitude of zero, causing the plane
++// to free fall for one frame, until the ground altitude was corrected, but now
++// being under the ground we got a big bounce and the plane always ended up
++// upside down.
++//
++// Revision 1.56 1998/12/06 13:51:23 curt
++// Turned "struct fgWEATHER" into "class FGWeather".
++//
++// Revision 1.55 1998/12/05 15:54:20 curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.54 1998/12/05 14:19:53 curt
++// Looking into a problem with cur_view_params.abs_view_pos initialization.
++//
++// Revision 1.53 1998/12/03 04:25:05 curt
++// Working on fixing up new fgFLIGHT class.
++//
++// Revision 1.52 1998/12/03 01:17:17 curt
++// Converted fgFLIGHT to a class.
++//
++// Revision 1.51 1998/11/20 01:02:37 curt
++// Try to detect Mesa/Glide/Voodoo and chose the appropriate resolution.
++//
++// Revision 1.50 1998/11/16 14:00:01 curt
++// Added pow() macro bug work around.
++// Added support for starting FGFS at various resolutions.
++// Added some initial serial port support.
++// Specify default log levels in main().
++//
++// Revision 1.49 1998/11/11 00:24:02 curt
++// Added Michael Johnson's audio patches for testing.
++// Also did a few tweaks to avoid numerical problems when starting at a place
++// with no (or bogus) scenery.
++//
++// Revision 1.48 1998/11/07 19:07:10 curt
++// Enable release builds using the --without-logging option to the configure
++// script. Also a couple log message cleanups, plus some C to C++ comment
++// conversion.
++//
++// Revision 1.47 1998/11/06 21:18:10 curt
++// Converted to new logstream debugging facility. This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.46 1998/10/27 02:14:38 curt
++// Changes to support GLUT joystick routines as fall back.
++//
++// Revision 1.45 1998/10/25 10:57:21 curt
++// Changes to use the new joystick library if it is available.
++//
++// Revision 1.44 1998/10/18 01:17:17 curt
++// Point3D tweaks.
++//
++// Revision 1.43 1998/10/17 01:34:22 curt
++// C++ ifying ...
++//
++// Revision 1.42 1998/10/16 23:27:54 curt
++// C++-ifying.
++//
++// Revision 1.41 1998/10/16 00:54:01 curt
++// Converted to Point3D class.
++//
++// Revision 1.40 1998/10/02 12:46:49 curt
++// Added an "auto throttle"
++//
++// Revision 1.39 1998/09/29 02:03:39 curt
++// Autopilot mods.
++//
++// Revision 1.38 1998/09/15 04:27:30 curt
++// Changes for new Astro code.
++//
++// Revision 1.37 1998/09/15 02:09:26 curt
++// Include/fg_callback.hxx
++// Moved code inline to stop g++ 2.7 from complaining.
++//
++// Simulator/Time/event.[ch]xx
++// Changed return type of fgEVENT::printStat(). void caused g++ 2.7 to
++// complain bitterly.
++//
++// Minor bugfix and changes.
++//
++// Simulator/Main/GLUTmain.cxx
++// Added missing type to idle_state definition - eliminates a warning.
++//
++// Simulator/Main/fg_init.cxx
++// Changes to airport lookup.
++//
++// Simulator/Main/options.cxx
++// Uses fg_gzifstream when loading config file.
++//
++// Revision 1.36 1998/09/08 21:40:08 curt
++// Fixes by Charlie Hotchkiss.
++//
++// Revision 1.35 1998/08/29 13:09:26 curt
++// Changes to event manager from Bernie Bright.
++//
++// Revision 1.34 1998/08/27 17:02:06 curt
++// Contributions from Bernie Bright <bbright@c031.aone.net.au>
++// - use strings for fg_root and airport_id and added methods to return
++// them as strings,
++// - inlined all access methods,
++// - made the parsing functions private methods,
++// - deleted some unused functions.
++// - propogated some of these changes out a bit further.
++//
++// Revision 1.33 1998/08/25 20:53:32 curt
++// Shuffled $FG_ROOT file layout.
++//
++// Revision 1.32 1998/08/25 16:59:09 curt
++// Directory reshuffling.
++//
++// Revision 1.31 1998/08/22 14:49:57 curt
++// Attempting to iron out seg faults and crashes.
++// Did some shuffling to fix a initialization order problem between view
++// position, scenery elevation.
++//
++// Revision 1.30 1998/08/20 20:32:33 curt
++// Reshuffled some of the code in and around views.[ch]xx
++//
++// Revision 1.29 1998/07/30 23:48:27 curt
++// Output position & orientation when pausing.
++// Eliminated libtool use.
++// Added options to specify initial position and orientation.
++// Changed default fov to 55 degrees.
++// Added command line option to start in paused or unpaused state.
++//
++// Revision 1.28 1998/07/27 18:41:25 curt
++// Added a pause command "p"
++// Fixed some initialization order problems between pui and glut.
++// Added an --enable/disable-sound option.
++//
++// Revision 1.27 1998/07/24 21:39:10 curt
++// Debugging output tweaks.
++// Cast glGetString to (char *) to avoid compiler errors.
++// Optimizations to fgGluLookAt() by Norman Vine.
++//
++// Revision 1.26 1998/07/22 21:40:44 curt
++// Clear to adjusted fog color (for sunrise/sunset effects)
++// Make call to fog sunrise/sunset adjustment method.
++// Add a stdc++ library bug work around to fg_init.cxx
++//
++// Revision 1.25 1998/07/13 21:01:38 curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.24 1998/07/13 15:32:39 curt
++// Clear color buffer if drawing wireframe.
++// When specifying and airport, start elevation at -1000 and let the system
++// position you at ground level.
++//
++// Revision 1.23 1998/07/12 03:14:43 curt
++// Added ground collision detection.
++// Did some serious horsing around to be able to "hug" the ground properly
++// and still be able to take off.
++// Set the near clip plane to 1.0 meters when less than 10 meters above the
++// ground.
++// Did some serious horsing around getting the initial airplane position to be
++// correct based on rendered terrain elevation.
++// Added a little cheat/hack that will prevent the view position from ever
++// dropping below the terrain, even when the flight model doesn't quite
++// put you as high as you'd like.
++//
++// Revision 1.22 1998/07/04 00:52:25 curt
++// Add my own version of gluLookAt() (which is nearly identical to the
++// Mesa/glu version.) But, by calculating the Model View matrix our selves
++// we can save this matrix without having to read it back in from the video
++// card. This hopefully allows us to save a few cpu cycles when rendering
++// out the fragments because we can just use glLoadMatrixd() with the
++// precalculated matrix for each tile rather than doing a push(), translate(),
++// pop() for every fragment.
++//
++// Panel status defaults to off for now until it gets a bit more developed.
++//
++// Extract OpenGL driver info on initialization.
++//
++// Revision 1.21 1998/06/27 16:54:33 curt
++// Replaced "extern displayInstruments" with a entry in fgOPTIONS.
++// Don't change the view port when displaying the panel.
++//
++// Revision 1.20 1998/06/17 21:35:12 curt
++// Refined conditional audio support compilation.
++// Moved texture parameter setup calls to ../Scenery/materials.cxx
++// #include <string.h> before various STL includes.
++// Make HUD default state be enabled.
++//
++// Revision 1.19 1998/06/08 17:57:05 curt
++// Minor sound/startup position tweaks.
++//
++// Revision 1.18 1998/06/03 00:47:14 curt
++// Updated to compile in audio support if OSS available.
++// Updated for new version of Steve's audio library.
++// STL includes don't use .h
++// Small view optimizations.
++//
++// Revision 1.17 1998/06/01 17:54:42 curt
++// Added Linux audio support.
++// avoid glClear( COLOR_BUFFER_BIT ) when not using it to set the sky color.
++// map stl tweaks.
++//
++// Revision 1.16 1998/05/29 20:37:24 curt
++// Tweaked material properties & lighting a bit in GLUTmain.cxx.
++// Read airport list into a "map" STL for dynamic list sizing and fast tree
++// based lookups.
++//
++// Revision 1.15 1998/05/22 21:28:53 curt
++// Modifications to use the new fgEVENT_MGR class.
++//
++// Revision 1.14 1998/05/20 20:51:35 curt
++// Tweaked smooth shaded texture lighting properties.
++// Converted fgLIGHT to a C++ class.
++//
++// Revision 1.13 1998/05/16 13:08:35 curt
++// C++ - ified views.[ch]xx
++// Shuffled some additional view parameters into the fgVIEW class.
++// Changed tile-radius to tile-diameter because it is a much better
++// name.
++// Added a WORLD_TO_EYE transformation to views.cxx. This allows us
++// to transform world space to eye space for view frustum culling.
++//
++// Revision 1.12 1998/05/13 18:29:58 curt
++// Added a keyboard binding to dynamically adjust field of view.
++// Added a command line option to specify fov.
++// Adjusted terrain color.
++// Root path info moved to fgOPTIONS.
++// Added ability to parse options out of a config file.
++//
++// Revision 1.11 1998/05/07 23:14:15 curt
++// Added "D" key binding to set autopilot heading.
++// Made frame rate calculation average out over last 10 frames.
++// Borland C++ floating point exception workaround.
++// Added a --tile-radius=n option.
++//
++// Revision 1.10 1998/05/06 03:16:24 curt
++// Added an averaged global frame rate counter.
++// Added an option to control tile radius.
++//
++// Revision 1.9 1998/05/03 00:47:31 curt
++// Added an option to enable/disable full-screen mode.
++//
++// Revision 1.8 1998/04/30 12:34:18 curt
++// Added command line rendering options:
++// enable/disable fog/haze
++// specify smooth/flat shading
++// disable sky blending and just use a solid color
++// enable wireframe drawing mode
++//
++// Revision 1.7 1998/04/28 01:20:22 curt
++// Type-ified fgTIME and fgVIEW.
++// Added a command line option to disable textures.
++//
++// Revision 1.6 1998/04/26 05:10:03 curt
++// "struct fgLIGHT" -> "fgLIGHT" because fgLIGHT is typedef'd.
++//
++// Revision 1.5 1998/04/25 22:06:30 curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.4 1998/04/25 20:24:01 curt
++// Cleaned up initialization sequence to eliminate interdependencies
++// between sun position, lighting, and view position. This creates a
++// valid single pass initialization path.
++//
++// Revision 1.3 1998/04/25 15:11:11 curt
++// Added an command line option to set starting position based on airport ID.
++//
++// Revision 1.2 1998/04/24 00:49:20 curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Trying out some different option parsing code.
++// Some code reorganization.
++//
++// Revision 1.1 1998/04/22 13:25:44 curt
++// C++ - ifing the code.
++// Starting a bit of reorganization of lighting code.
++//
++// Revision 1.56 1998/04/18 04:11:28 curt
++// Moved fg_debug to it's own library, added zlib support.
++//
++// Revision 1.55 1998/04/14 02:21:03 curt
++// Incorporated autopilot heading hold contributed by: Jeff Goeke-Smith
++// <jgoeke@voyager.net>
++//
++// Revision 1.54 1998/04/08 23:35:36 curt
++// Tweaks to Gnu automake/autoconf system.
++//
++// Revision 1.53 1998/04/03 22:09:06 curt
++// Converting to Gnu autoconf system.
++//
++// Revision 1.52 1998/03/23 21:24:38 curt
++// Source code formating tweaks.
++//
++// Revision 1.51 1998/03/14 00:31:22 curt
++// Beginning initial terrain texturing experiments.
++//
++// Revision 1.50 1998/03/09 22:46:19 curt
++// Minor tweaks.
++//
++// Revision 1.49 1998/02/23 19:07:59 curt
++// Incorporated Durk's Astro/ tweaks. Includes unifying the sun position
++// calculation code between sun display, and other FG sections that use this
++// for things like lighting.
++//
++// Revision 1.48 1998/02/21 14:53:15 curt
++// Added Charlie's HUD changes.
++//
++// Revision 1.47 1998/02/19 13:05:53 curt
++// Incorporated some HUD tweaks from Michelle America.
++// Tweaked the sky's sunset/rise colors.
++// Other misc. tweaks.
++//
++// Revision 1.46 1998/02/18 15:07:06 curt
++// Tweaks to build with SGI OpenGL (and therefor hopefully other accelerated
++// drivers will work.)
++//
++// Revision 1.45 1998/02/16 13:39:43 curt
++// Miscellaneous weekend tweaks. Fixed? a cache problem that caused whole
++// tiles to occasionally be missing.
++//
++// Revision 1.44 1998/02/12 21:59:50 curt
++// Incorporated code changes contributed by Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.43 1998/02/11 02:50:40 curt
++// Minor changes.
++//
++// Revision 1.42 1998/02/09 22:56:58 curt
++// Removed "depend" files from cvs control. Other minor make tweaks.
++//
++// Revision 1.41 1998/02/09 15:07:50 curt
++// Minor tweaks.
++//
++// Revision 1.40 1998/02/07 15:29:44 curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.39 1998/02/03 23:20:25 curt
++// Lots of little tweaks to fix various consistency problems discovered by
++// Solaris' CC. Fixed a bug in fg_debug.c with how the fgPrintf() wrapper
++// passed arguments along to the real printf(). Also incorporated HUD changes
++// by Michele America.
++//
++// Revision 1.38 1998/02/02 20:53:58 curt
++// Incorporated Durk's changes.
++//
++// Revision 1.37 1998/02/01 03:39:54 curt
++// Minor tweaks.
++//
++// Revision 1.36 1998/01/31 00:43:13 curt
++// Added MetroWorks patches from Carmen Volpe.
++//
++// Revision 1.35 1998/01/27 00:47:57 curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.34 1998/01/22 02:59:37 curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.33 1998/01/21 21:11:34 curt
++// Misc. tweaks.
++//
++// Revision 1.32 1998/01/19 19:27:08 curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.31 1998/01/19 18:40:32 curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.30 1998/01/13 00:23:09 curt
++// Initial changes to support loading and management of scenery tiles. Note,
++// there's still a fair amount of work left to be done.
++//
++// Revision 1.29 1998/01/08 02:22:08 curt
++// Beginning to integrate Tile management subsystem.
++//
++// Revision 1.28 1998/01/07 03:18:58 curt
++// Moved astronomical stuff from .../Src/Scenery to .../Src/Astro/
++//
++// Revision 1.27 1998/01/05 18:44:35 curt
++// Add an option to advance/decrease time from keyboard.
++//
++// Revision 1.26 1997/12/30 23:09:04 curt
++// Tweaking initialization sequences.
++//
++// Revision 1.25 1997/12/30 22:22:33 curt
++// Further integration of event manager.
++//
++// Revision 1.24 1997/12/30 20:47:44 curt
++// Integrated new event manager with subsystem initializations.
++//
++// Revision 1.23 1997/12/30 16:36:50 curt
++// Merged in Durk's changes ...
++//
++// Revision 1.22 1997/12/19 23:34:05 curt
++// Lot's of tweaking with sky rendering and lighting.
++//
++// Revision 1.21 1997/12/19 16:45:00 curt
++// Working on scene rendering order and options.
++//
++// Revision 1.20 1997/12/18 23:32:33 curt
++// First stab at sky dome actually starting to look reasonable. :-)
++//
++// Revision 1.19 1997/12/17 23:13:36 curt
++// Began working on rendering a sky.
++//
++// Revision 1.18 1997/12/15 23:54:49 curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.17 1997/12/15 20:59:09 curt
++// Misc. tweaks.
++//
++// Revision 1.16 1997/12/12 19:52:48 curt
++// Working on lightling and material properties.
++//
++// Revision 1.15 1997/12/11 04:43:55 curt
++// Fixed sun vector and lighting problems. I thing the moon is now lit
++// correctly.
++//
++// Revision 1.14 1997/12/10 22:37:47 curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.13 1997/11/25 19:25:32 curt
++// Changes to integrate Durk's moon/sun code updates + clean up.
++//
++// Revision 1.12 1997/11/15 18:16:35 curt
++// minor tweaks.
++//
++// Revision 1.11 1997/10/30 12:38:42 curt
++// Working on new scenery subsystem.
++//
++// Revision 1.10 1997/10/25 03:24:23 curt
++// Incorporated sun, moon, and star positioning code contributed by Durk Talsma.
++//
++// Revision 1.9 1997/09/23 00:29:39 curt
++// Tweaks to get things to compile with gcc-win32.
++//
++// Revision 1.8 1997/09/22 14:44:20 curt
++// Continuing to try to align stars correctly.
++//
++// Revision 1.7 1997/09/16 15:50:30 curt
++// Working on star alignment and time issues.
++//
++// Revision 1.6 1997/09/05 14:17:30 curt
++// More tweaking with stars.
++//
++// Revision 1.5 1997/09/04 02:17:36 curt
++// Shufflin' stuff.
++//
++// Revision 1.4 1997/08/27 21:32:26 curt
++// Restructured view calculation code. Added stars.
++//
++// Revision 1.3 1997/08/27 03:30:19 curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.2 1997/08/25 20:27:23 curt
++// Merged in initial HUD and Joystick code.
++//
++// Revision 1.1 1997/08/23 01:46:20 curt
++// Initial revision.
++//
++
--- /dev/null
--- /dev/null
++//
++// fg_init.hxx -- 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$
++// (Log is kept at end of this file)
++
++
++#ifndef _FG_INIT_HXX
++#define _FG_INIT_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++
++// General house keeping initializations
++int fgInitGeneral ( void );
++
++
++// 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.
++int fgInitSubsystems( void );
++
++
++#endif // _FG_INIT_H
++
++
++// $Log$
++// Revision 1.2 1998/04/25 15:11:12 curt
++// Added an command line option to set starting position based on airport ID.
++//
++// Revision 1.1 1998/04/22 13:25:44 curt
++// C++ - ifing the code.
++// Starting a bit of reorganization of lighting code.
++//
++// Revision 1.4 1998/04/21 17:02:41 curt
++// Prepairing for C++ integration.
++//
++// Revision 1.3 1998/02/12 21:59:50 curt
++// Incorporated code changes contributed by Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.2 1998/01/22 02:59:38 curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.1 1997/08/23 01:46:20 curt
++// Initial revision.
++//
--- /dev/null
--- /dev/null
++// fg_serial.cxx -- higher level serial port management routines
++//
++// Written by Curtis Olson, started November 1998.
++//
++// Copyright (C) 1998 Curtis L. Olson - curt@flightgear.org
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#include <Include/compiler.h>
++
++#ifdef FG_HAVE_STD_INCLUDES
++# include <cstdlib> // atoi()
++#else
++# include <stdlib.h> // atoi()
++#endif
++
++#include STL_STRING
++#include STL_IOSTREAM
++#include <vector>
++
++#include <Debug/logstream.hxx>
++#include <Aircraft/aircraft.hxx>
++#include <Include/fg_constants.h>
++#include <Serial/serial.hxx>
++#include <Time/fg_time.hxx>
++
++#include "options.hxx"
++
++#include "fg_serial.hxx"
++
++FG_USING_STD(string);
++FG_USING_STD(vector);
++
++// support an arbitrary number of serial channels. Each channel can
++// be assigned to an arbitrary port. Bi-directional communication is
++// supported by the underlying layer, but probably will never be
++// needed by FGFS?
++
++typedef vector < fgIOCHANNEL > io_container;
++typedef io_container::iterator io_iterator;
++typedef io_container::const_iterator const_io_iterator;
++
++// define the four channels
++io_container port_list;
++
++
++fgIOCHANNEL::fgIOCHANNEL() :
++ kind( FG_SERIAL_DISABLED ),
++ valid_config( false )
++{
++}
++
++
++fgIOCHANNEL::~fgIOCHANNEL() {
++}
++
++
++// configure a port based on the config string
++static fgIOCHANNEL parse_port_config( const string& config )
++{
++ fgIOCHANNEL p;
++
++ string::size_type begin, end;
++
++ begin = 0;
++
++ FG_LOG( FG_SERIAL, FG_INFO, "Parse serial port config: " << config );
++
++ // device name
++ end = config.find(",", begin);
++ if ( end == string::npos ) {
++ return p;
++ }
++
++ p.device = config.substr(begin, end - begin);
++ begin = end + 1;
++ FG_LOG( FG_SERIAL, FG_INFO, " device = " << p.device );
++
++ // format
++ end = config.find(",", begin);
++ if ( end == string::npos ) {
++ return p;
++ }
++
++ p.format = config.substr(begin, end - begin);
++ begin = end + 1;
++ FG_LOG( FG_SERIAL, FG_INFO, " format = " << p.format );
++
++ // baud
++ end = config.find(",", begin);
++ if ( end == string::npos ) {
++ return p;
++ }
++
++ p.baud = config.substr(begin, end - begin);
++ begin = end + 1;
++ FG_LOG( FG_SERIAL, FG_INFO, " baud = " << p.baud );
++
++ // direction
++ p.direction = config.substr(begin);
++ FG_LOG( FG_SERIAL, FG_INFO, " direction = " << p.direction );
++
++ p.valid_config = true;
++
++ return p;
++}
++
++
++// configure a port based on the config info
++static bool config_port( fgIOCHANNEL &p )
++{
++ if ( p.port.is_enabled() ) {
++ FG_LOG( FG_SERIAL, FG_ALERT, "This shouldn't happen, but the port "
++ << "is already in use, ignoring" );
++ return false;
++ }
++
++ if ( ! p.port.open_port( p.device ) ) {
++ FG_LOG( FG_SERIAL, FG_ALERT, "Error opening device: " << p.device );
++ return false;
++ }
++
++ // cout << "fd = " << p.port.fd << endl;
++
++ if ( ! p.port.set_baud( atoi( p.baud.c_str() ) ) ) {
++ FG_LOG( FG_SERIAL, FG_ALERT, "Error setting baud: " << p.baud );
++ return false;
++ }
++
++ if ( p.format == "nmea" ) {
++ if ( p.direction == "out" ) {
++ p.kind = fgIOCHANNEL::FG_SERIAL_NMEA_OUT;
++ } else if ( p.direction == "in" ) {
++ p.kind = fgIOCHANNEL::FG_SERIAL_NMEA_IN;
++ } else {
++ FG_LOG( FG_SERIAL, FG_ALERT, "Unknown direction" );
++ return false;
++ }
++ } else if ( p.format == "garmin" ) {
++ if ( p.direction == "out" ) {
++ p.kind = fgIOCHANNEL::FG_SERIAL_GARMIN_OUT;
++ } else if ( p.direction == "in" ) {
++ p.kind = fgIOCHANNEL::FG_SERIAL_GARMIN_IN;
++ } else {
++ FG_LOG( FG_SERIAL, FG_ALERT, "Unknown direction" );
++ return false;
++ }
++ } else if ( p.format == "fgfs" ) {
++ if ( p.direction == "out" ) {
++ p.kind = fgIOCHANNEL::FG_SERIAL_FGFS_OUT;
++ } else if ( p.direction == "in" ) {
++ p.kind = fgIOCHANNEL::FG_SERIAL_FGFS_IN;
++ } else {
++ FG_LOG( FG_SERIAL, FG_ALERT, "Unknown direction" );
++ return false;
++ }
++ } else {
++ FG_LOG( FG_SERIAL, FG_ALERT, "Unknown format" );
++ return false;
++ }
++
++ return true;
++}
++
++
++// step through the port config streams (from fgOPTIONS) and setup
++// serial port channels for each
++void fgSerialInit() {
++ fgIOCHANNEL port;
++ bool result;
++ str_container port_options_list = current_options.get_port_options_list();
++
++ // we could almost do this in a single step except pushing a valid
++ // port onto the port list copies the structure and destroys the
++ // original, which closes the port and frees up the fd ... doh!!!
++
++ // parse the configuration strings and store the results in stub
++ // fgIOCHANNEL structures
++ const_str_iterator current_str = port_options_list.begin();
++ const_str_iterator last_str = port_options_list.end();
++ for ( ; current_str != last_str; ++current_str ) {
++ port = parse_port_config( *current_str );
++ if ( port.valid_config ) {
++ result = config_port( port );
++ if ( result ) {
++ port_list.push_back( port );
++ }
++ }
++ }
++}
++
++
++char calc_nmea_cksum(char *sentence) {
++ unsigned char sum = 0;
++ int i, len;
++
++ // printf("%s\n", sentence);
++
++ len = strlen(sentence);
++ sum = sentence[0];
++ for ( i = 1; i < len; i++ ) {
++ // printf("%c", sentence[i]);
++ sum ^= sentence[i];
++ }
++ // printf("\n");
++
++ // printf("sum = %02x\n", sum);
++ return sum;
++}
++
++
++static void send_nmea_out( fgIOCHANNEL *p ) {
++ char rmc[256], gga[256];
++ char rmc_sum[10], gga_sum[10];
++ char dir;
++ int deg;
++ double min;
++ FGInterface *f;
++ fgTIME *t;
++
++ // run once every two seconds
++ if ( p->last_time == cur_time_params.cur_time ) {
++ return;
++ }
++ p->last_time = cur_time_params.cur_time;
++ if ( cur_time_params.cur_time % 2 != 0 ) {
++ return;
++ }
++
++ f = current_aircraft.fdm_state;
++ t = &cur_time_params;
++
++ char utc[10];
++ sprintf( utc, "%02d%02d%02d",
++ t->gmt->tm_hour, t->gmt->tm_min, t->gmt->tm_sec );
++
++ char lat[20];
++ double latd = f->get_Latitude() * RAD_TO_DEG;
++ if ( latd < 0.0 ) {
++ latd *= -1.0;
++ dir = 'S';
++ } else {
++ dir = 'N';
++ }
++ deg = (int)(latd);
++ min = (latd - (double)deg) * 60.0;
++ sprintf( lat, "%02d%06.3f,%c", abs(deg), min, dir);
++
++ char lon[20];
++ double lond = f->get_Longitude() * RAD_TO_DEG;
++ if ( lond < 0.0 ) {
++ lond *= -1.0;
++ dir = 'W';
++ } else {
++ dir = 'E';
++ }
++ deg = (int)(lond);
++ min = (lond - (double)deg) * 60.0;
++ sprintf( lon, "%03d%06.3f,%c", abs(deg), min, dir);
++
++ char speed[10];
++ sprintf( speed, "%05.1f", f->get_V_equiv_kts() );
++
++ char heading[10];
++ sprintf( heading, "%05.1f", f->get_Psi() * RAD_TO_DEG );
++
++ char altitude_m[10];
++ sprintf( altitude_m, "%02d", (int)(f->get_Altitude() * FEET_TO_METER) );
++
++ char altitude_ft[10];
++ sprintf( altitude_ft, "%02d", (int)f->get_Altitude() );
++
++ char date[10];
++ sprintf( date, "%02d%02d%02d",
++ t->gmt->tm_mday, t->gmt->tm_mon+1, t->gmt->tm_year );
++
++ // $GPRMC,HHMMSS,A,DDMM.MMM,N,DDDMM.MMM,W,XXX.X,XXX.X,DDMMYY,XXX.X,E*XX
++ sprintf( rmc, "GPRMC,%s,A,%s,%s,%s,%s,%s,0.000,E",
++ utc, lat, lon, speed, heading, date );
++ sprintf( rmc_sum, "%02X", calc_nmea_cksum(rmc) );
++
++ sprintf( gga, "GPGGA,%s,%s,%s,1,,,%s,F,,,,",
++ utc, lat, lon, altitude_ft );
++ sprintf( gga_sum, "%02X", calc_nmea_cksum(gga) );
++
++
++ FG_LOG( FG_SERIAL, FG_DEBUG, rmc );
++ FG_LOG( FG_SERIAL, FG_DEBUG, gga );
++
++ // RMC sentence
++ string rmc_sentence = "$";
++ rmc_sentence += rmc;
++ rmc_sentence += "*";
++ rmc_sentence += rmc_sum;
++ rmc_sentence += "\n";
++ p->port.write_port(rmc_sentence);
++ // cout << rmc_sentence;
++
++ // GGA sentence
++ string gga_sentence = "$";
++ gga_sentence += gga;
++ gga_sentence += "*";
++ gga_sentence += gga_sum;
++ gga_sentence += "\n";
++ p->port.write_port(gga_sentence);
++ // cout << gga_sentence;
++}
++
++static void read_nmea_in( fgIOCHANNEL *p ) {
++}
++
++static void send_garmin_out( fgIOCHANNEL *p ) {
++ char rmc[256], rmc_sum[256], rmz[256], rmz_sum[256];
++ char dir;
++ int deg;
++ double min;
++ FGInterface *f;
++ fgTIME *t;
++
++ // run once per second
++ if ( p->last_time == cur_time_params.cur_time ) {
++ return;
++ }
++ p->last_time = cur_time_params.cur_time;
++ if ( cur_time_params.cur_time % 2 != 0 ) {
++ return;
++ }
++
++ f = current_aircraft.fdm_state;
++ t = &cur_time_params;
++
++ char utc[10];
++ sprintf( utc, "%02d%02d%02d",
++ t->gmt->tm_hour, t->gmt->tm_min, t->gmt->tm_sec );
++
++ char lat[20];
++ double latd = f->get_Latitude() * RAD_TO_DEG;
++ if ( latd < 0.0 ) {
++ latd *= -1.0;
++ dir = 'S';
++ } else {
++ dir = 'N';
++ }
++ deg = (int)(latd);
++ min = (latd - (double)deg) * 60.0;
++ sprintf( lat, "%02d%06.3f,%c", abs(deg), min, dir);
++
++ char lon[20];
++ double lond = f->get_Longitude() * RAD_TO_DEG;
++ if ( lond < 0.0 ) {
++ lond *= -1.0;
++ dir = 'W';
++ } else {
++ dir = 'E';
++ }
++ deg = (int)(lond);
++ min = (lond - (double)deg) * 60.0;
++ sprintf( lon, "%03d%06.3f,%c", abs(deg), min, dir);
++
++ char speed[10];
++ sprintf( speed, "%05.1f", f->get_V_equiv_kts() );
++
++ char heading[10];
++ sprintf( heading, "%05.1f", f->get_Psi() * RAD_TO_DEG );
++
++ char altitude_m[10];
++ sprintf( altitude_m, "%02d", (int)(f->get_Altitude() * FEET_TO_METER) );
++
++ char altitude_ft[10];
++ sprintf( altitude_ft, "%02d", (int)f->get_Altitude() );
++
++ char date[10];
++ sprintf( date, "%02d%02d%02d",
++ t->gmt->tm_mday, t->gmt->tm_mon+1, t->gmt->tm_year );
++
++ // $GPRMC,HHMMSS,A,DDMM.MMM,N,DDDMM.MMM,W,XXX.X,XXX.X,DDMMYY,XXX.X,E*XX
++ sprintf( rmc, "GPRMC,%s,A,%s,%s,%s,%s,%s,000.0,E",
++ utc, lat, lon, speed, heading, date );
++ sprintf( rmc_sum, "%02X", calc_nmea_cksum(rmc) );
++
++ // sprintf( gga, "$GPGGA,%s,%s,%s,1,04,0.0,%s,M,00.0,M,,*00\r\n",
++ // utc, lat, lon, altitude_m );
++
++ sprintf( rmz, "PGRMZ,%s,f,3", altitude_ft );
++ sprintf( rmz_sum, "%02X", calc_nmea_cksum(rmz) );
++
++ FG_LOG( FG_SERIAL, FG_DEBUG, rmc );
++ FG_LOG( FG_SERIAL, FG_DEBUG, rmz );
++
++ // RMC sentence
++ string rmc_sentence = "$";
++ rmc_sentence += rmc;
++ rmc_sentence += "*";
++ rmc_sentence += rmc_sum;
++ rmc_sentence += "\n";
++ p->port.write_port(rmc_sentence);
++ // cout << rmc_sentence;
++
++ // RMZ sentence (garmin proprietary)
++ string rmz_sentence = "$";
++ rmz_sentence += rmz;
++ rmz_sentence += "*";
++ rmz_sentence += rmz_sum;
++ rmz_sentence += "\n";
++ p->port.write_port(rmz_sentence);
++ // cout << rmz_sentence;
++}
++
++static void read_garmin_in( fgIOCHANNEL *p ) {
++}
++
++static void send_fgfs_out( fgIOCHANNEL *p ) {
++}
++
++static void read_fgfs_in( fgIOCHANNEL *p ) {
++}
++
++
++// one more level of indirection ...
++static void process_port( fgIOCHANNEL *p ) {
++ if ( p->kind == fgIOCHANNEL::FG_SERIAL_NMEA_OUT ) {
++ send_nmea_out(p);
++ } else if ( p->kind == fgIOCHANNEL::FG_SERIAL_NMEA_IN ) {
++ read_nmea_in(p);
++ } else if ( p->kind == fgIOCHANNEL::FG_SERIAL_GARMIN_OUT ) {
++ send_garmin_out(p);
++ } else if ( p->kind == fgIOCHANNEL::FG_SERIAL_GARMIN_IN ) {
++ read_garmin_in(p);
++ } else if ( p->kind == fgIOCHANNEL::FG_SERIAL_FGFS_OUT ) {
++ send_fgfs_out(p);
++ } else if ( p->kind == fgIOCHANNEL::FG_SERIAL_FGFS_IN ) {
++ read_fgfs_in(p);
++ }
++}
++
++
++// process any serial port work
++void fgSerialProcess() {
++ fgIOCHANNEL *port;
++
++ io_iterator current = port_list.begin();
++ io_iterator last = port_list.end();
++
++ for ( ; current != last; ++current ) {
++ port = current;
++ if ( port->kind != fgIOCHANNEL::FG_SERIAL_DISABLED ) {
++ process_port ( port );
++ }
++ }
++}
++
++
++// $Log$
++// Revision 1.13 1999/03/02 01:03:16 curt
++// Tweaks for building with native SGI compilers.
++//
++// Revision 1.12 1999/02/26 22:09:50 curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.11 1999/02/05 21:29:11 curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.10 1999/01/21 00:55:01 curt
++// Fixed some problems with timing of output strings.
++// Added checksum support for nmea and garmin output.
++//
++// Revision 1.9 1999/01/20 13:42:26 curt
++// Tweaked FDM interface.
++// Testing check sum support for NMEA serial output.
++//
++// Revision 1.8 1999/01/19 20:57:04 curt
++// MacOS portability changes contributed by "Robert Puyol" <puyol@abvent.fr>
++//
++// Revision 1.7 1998/12/05 15:54:21 curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.6 1998/12/03 01:17:18 curt
++// Converted fgFLIGHT to a class.
++//
++// Revision 1.5 1998/11/30 17:43:32 curt
++// Lots of tweaking to get serial output to actually work.
++//
++// Revision 1.4 1998/11/25 01:33:58 curt
++// Support for an arbitrary number of serial ports.
++//
++// Revision 1.3 1998/11/23 20:51:51 curt
++// Tweaking serial stuff.
++//
++// Revision 1.2 1998/11/19 13:53:25 curt
++// Added a "Garmin" mode.
++//
++// Revision 1.1 1998/11/16 13:57:42 curt
++// Initial revision.
++//
--- /dev/null
--- /dev/null
++// fg_serial.hxx -- Higher level serial port managment routines
++//
++// Written by Curtis Olson, started November 1998.
++//
++// Copyright (C) 1998 Curtis L. Olson - curt@flightgear.org
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#ifndef _FG_SERIAL_HXX
++#define _FG_SERIAL_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++#include "Include/compiler.h"
++
++#include <string>
++
++#ifdef FG_HAVE_STD_INCLUDES
++# include <ctime>
++#else
++# include <time.h>
++#endif
++
++#include <Serial/serial.hxx>
++
++
++class fgIOCHANNEL {
++
++public:
++
++ // Types of serial port protocols
++ enum fgPortKind {
++ FG_SERIAL_DISABLED = 0,
++ FG_SERIAL_NMEA_OUT = 1,
++ FG_SERIAL_NMEA_IN = 2,
++ FG_SERIAL_GARMIN_OUT = 3,
++ FG_SERIAL_GARMIN_IN = 4,
++ FG_SERIAL_FGFS_OUT = 5,
++ FG_SERIAL_FGFS_IN = 6
++ };
++
++ string device;
++ string format;
++ string baud;
++ string direction;
++
++ fgPortKind kind;
++ fgSERIAL port;
++ time_t last_time;
++ bool valid_config;
++
++ fgIOCHANNEL();
++ ~fgIOCHANNEL();
++};
++
++
++// support up to four serial channels. Each channel can be assigned
++// to an arbitrary port. Bi-directional communication is supported by
++// the underlying layer.
++
++// define the four channels
++// extern fgIOCHANNEL port_a;
++// extern fgIOCHANNEL port_b;
++// extern fgIOCHANNEL port_c;
++// extern fgIOCHANNEL port_d;
++
++
++// initialize serial ports based on command line options (if any)
++void fgSerialInit();
++
++
++// process any serial port work
++void fgSerialProcess();
++
++
++#endif // _FG_SERIAL_HXX
++
++
++// $Log$
++// Revision 1.5 1999/01/21 00:55:02 curt
++// Fixed some problems with timing of output strings.
++// Added checksum support for nmea and garmin output.
++//
++// Revision 1.4 1998/11/30 17:43:34 curt
++// Lots of tweaking to get serial output to actually work.
++//
++// Revision 1.3 1998/11/25 01:33:59 curt
++// Support for an arbitrary number of serial ports.
++//
++// Revision 1.2 1998/11/19 13:53:27 curt
++// Added a "Garmin" mode.
++//
++// Revision 1.1 1998/11/16 13:57:43 curt
++// Initial revision.
++//
--- /dev/null
--- /dev/null
++// options.cxx -- class to handle command line options
++//
++// Written by Curtis Olson, started April 1998.
++//
++// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#if defined(FX) && defined(XMESA)
++bool global_fullscreen = true;
++#endif
++
++#include <Include/compiler.h>
++
++#include <math.h> // rint()
++#include <stdio.h>
++#include <stdlib.h> // atof(), atoi()
++#include <string.h>
++
++#include STL_STRING
++
++#include <Debug/logstream.hxx>
++#include <Misc/fgstream.hxx>
++#include <FDM/flight.hxx>
++#include <Include/fg_constants.h>
++#include <Main/options.hxx>
++
++#include "fg_serial.hxx"
++
++FG_USING_STD(string);
++FG_USING_NAMESPACE(std);
++
++
++inline double
++atof( const string& str )
++{
++ return ::atof( str.c_str() );
++}
++
++inline int
++atoi( const string& str )
++{
++ return ::atoi( str.c_str() );
++}
++
++// Defined the shared options class here
++fgOPTIONS current_options;
++
++
++// Constructor
++fgOPTIONS::fgOPTIONS() :
++ // starting longitude in degrees (west = -)
++ // starting latitude in degrees (south = -)
++
++ // Default initial position is Globe, AZ (P13)
++ lon(-110.6642444),
++ lat( 33.3528917),
++
++ // North of the city of Globe
++ // lon(-110.7),
++ // lat( 33.4),
++
++ // North of the city of Globe
++ // lon(-110.742578),
++ // lat( 33.507122),
++
++ // Near where I used to live in Globe, AZ
++ // lon(-110.766000),
++ // lat( 33.377778),
++
++ // 10125 Jewell St. NE
++ // lon(-93.15),
++ // lat( 45.15),
++
++ // Near KHSP (Hot Springs, VA)
++ // lon(-79.8338964 + 0.01),
++ // lat( 37.9514564 + 0.008),
++
++ // (SEZ) SEDONA airport
++ // lon(-111.7884614 + 0.01),
++ // lat( 34.8486289 - 0.015),
++
++ // Jim Brennon's Kingmont Observatory
++ // lon(-121.1131667),
++ // lat( 38.8293917),
++
++ // Huaras, Peru (S09d 31.871' W077d 31.498')
++ // lon(-77.5249667),
++ // lat( -9.5311833),
++
++ // Eclipse Watching w73.5 n10 (approx) 18:00 UT
++ // lon(-73.5),
++ // lat( 10.0),
++
++ // Timms Hill (WI)
++ // lon(-90.1953055556),
++ // lat( 45.4511388889),
++
++ // starting altitude in meters (this will be reset to ground level
++ // if it is lower than the terrain
++ altitude(-9999.0),
++
++ // Initial Orientation
++ heading(270.0), // heading (yaw) angle in degress (Psi)
++ roll(0.0), // roll angle in degrees (Phi)
++ pitch(0.424), // pitch angle in degrees (Theta)
++
++ // Miscellaneous
++ game_mode(0),
++ splash_screen(1),
++ intro_music(1),
++ mouse_pointer(0),
++ pause(0),
++
++ // Features
++ hud_status(1),
++ panel_status(0),
++ sound(1),
++
++ // Flight Model options
++ flight_model(FGInterface::FG_LARCSIM),
++
++ // Rendering options
++ fog(FG_FOG_NICEST), // nicest
++ fov(55.0),
++ fullscreen(0),
++ shading(1),
++ skyblend(1),
++ textures(1),
++ wireframe(0),
++ xsize(640),
++ ysize(480),
++
++ // Scenery options
++ tile_diameter(5),
++
++ // HUD options
++ units(FG_UNITS_FEET),
++ tris_or_culled(0),
++
++ // Time options
++ time_offset(0)
++
++{
++ // set initial values/defaults
++ char* envp = ::getenv( "FG_ROOT" );
++
++ if ( envp != NULL ) {
++ // fg_root could be anywhere, so default to environmental
++ // variable $FG_ROOT if it is set.
++ fg_root = envp;
++ } else {
++ // Otherwise, default to a random compiled in location if
++ // $FG_ROOT is not set. This can still be overridden from the
++ // command line or a config file.
++
++#if defined(WIN32)
++ fg_root = "\\FlightGear";
++#else
++ fg_root = "/usr/local/lib/FlightGear";
++#endif
++ }
++
++ airport_id = ""; // default airport id
++
++ // initialize port config string list
++ port_options_list.erase ( port_options_list.begin(),
++ port_options_list.end() );
++}
++
++
++double
++fgOPTIONS::parse_time(const string& time_in) {
++ char *time_str, num[256];
++ double hours, minutes, seconds;
++ double result = 0.0;
++ int sign = 1;
++ int i;
++
++ time_str = (char *)time_in.c_str();
++
++ // printf("parse_time(): %s\n", time_str);
++
++ // check for sign
++ if ( strlen(time_str) ) {
++ if ( time_str[0] == '+' ) {
++ sign = 1;
++ time_str++;
++ } else if ( time_str[0] == '-' ) {
++ sign = -1;
++ time_str++;
++ }
++ }
++ // printf("sign = %d\n", sign);
++
++ // get hours
++ if ( strlen(time_str) ) {
++ i = 0;
++ while ( (time_str[0] != ':') && (time_str[0] != '\0') ) {
++ num[i] = time_str[0];
++ time_str++;
++ i++;
++ }
++ if ( time_str[0] == ':' ) {
++ time_str++;
++ }
++ num[i] = '\0';
++ hours = atof(num);
++ // printf("hours = %.2lf\n", hours);
++
++ result += hours;
++ }
++
++ // get minutes
++ if ( strlen(time_str) ) {
++ i = 0;
++ while ( (time_str[0] != ':') && (time_str[0] != '\0') ) {
++ num[i] = time_str[0];
++ time_str++;
++ i++;
++ }
++ if ( time_str[0] == ':' ) {
++ time_str++;
++ }
++ num[i] = '\0';
++ minutes = atof(num);
++ // printf("minutes = %.2lf\n", minutes);
++
++ result += minutes / 60.0;
++ }
++
++ // get seconds
++ if ( strlen(time_str) ) {
++ i = 0;
++ while ( (time_str[0] != ':') && (time_str[0] != '\0') ) {
++ num[i] = time_str[0];
++ time_str++;
++ i++;
++ }
++ num[i] = '\0';
++ seconds = atof(num);
++ // printf("seconds = %.2lf\n", seconds);
++
++ result += seconds / 3600.0;
++ }
++
++ return(sign * result);
++}
++
++
++// parse degree in the form of [+/-]hhh:mm:ss
++double
++fgOPTIONS::parse_degree( const string& degree_str) {
++ double result = parse_time( degree_str );
++
++ // printf("Degree = %.4f\n", result);
++
++ return(result);
++}
++
++
++// parse time offset command line option
++int
++fgOPTIONS::parse_time_offset( const string& time_str) {
++ int result;
++
++ // printf("time offset = %s\n", time_str);
++
++#ifdef HAVE_RINT
++ result = (int)rint(parse_time(time_str) * 3600.0);
++#else
++ result = (int)(parse_time(time_str) * 3600.0);
++#endif
++
++ // printf("parse_time_offset(): %d\n", result);
++
++ return( result );
++}
++
++
++// Parse --tile-diameter=n type option
++
++int
++fgOPTIONS::parse_tile_radius( const string& arg ) {
++ int radius = atoi( arg );
++
++ if ( radius < FG_RADIUS_MIN ) { radius = FG_RADIUS_MIN; }
++ if ( radius > FG_RADIUS_MAX ) { radius = FG_RADIUS_MAX; }
++
++ // printf("parse_tile_radius(): radius = %d\n", radius);
++
++ return(radius);
++}
++
++
++// Parse --fdm=abcdefg type option
++int
++fgOPTIONS::parse_fdm( const string& fm ) {
++ // printf("fdm = %s\n", fm);
++
++ if ( fm == "slew" ) {
++ return FGInterface::FG_SLEW;
++ } else if ( fm == "jsb" ) {
++ return FGInterface::FG_JSBSIM;
++ } else if ( (fm == "larcsim") || (fm == "LaRCsim") ) {
++ return FGInterface::FG_LARCSIM;
++ } else if ( fm == "external" ) {
++ return FGInterface::FG_EXTERNAL;
++ } else {
++ FG_LOG( FG_GENERAL, FG_ALERT, "Unknown fdm = " << fm );
++ exit(-1);
++ }
++
++ // we'll never get here, but it makes the compiler happy.
++ return -1;
++}
++
++
++// Parse --fov=x.xx type option
++double
++fgOPTIONS::parse_fov( const string& arg ) {
++ double fov = atof(arg);
++
++ if ( fov < FG_FOV_MIN ) { fov = FG_FOV_MIN; }
++ if ( fov > FG_FOV_MAX ) { fov = FG_FOV_MAX; }
++
++ // printf("parse_fov(): result = %.4f\n", fov);
++
++ return(fov);
++}
++
++
++// Parse serial port option --serial=/dev/ttyS1,nmea,4800,out
++//
++// Format is "--serial=device,format,baud,direction" where
++//
++// device = OS device name to be open()'ed
++// format = {nmea, fgfs}
++// baud = {300, 1200, 2400, ..., 230400}
++// direction = {in, out, bi}
++
++bool
++fgOPTIONS::parse_serial( const string& serial_str ) {
++ string::size_type pos;
++
++ // cout << "Serial string = " << serial_str << endl;
++
++ // a flailing attempt to see if the port config string has a
++ // chance at being valid
++ pos = serial_str.find(",");
++ if ( pos == string::npos ) {
++ FG_LOG( FG_GENERAL, FG_ALERT,
++ "Malformed serial port configure string" );
++ return false;
++ }
++
++ port_options_list.push_back( serial_str );
++
++ return true;
++}
++
++
++// Parse a single option
++int fgOPTIONS::parse_option( const string& arg ) {
++ // General Options
++ if ( (arg == "--help") || (arg == "-h") ) {
++ // help/usage request
++ return(FG_OPTIONS_HELP);
++ } else if ( arg == "--disable-game-mode") {
++ game_mode = false;
++ } else if ( arg == "--enable-game-mode" ) {
++ game_mode = true;
++ } else if ( arg == "--disable-splash-screen" ) {
++ splash_screen = false;
++ } else if ( arg == "--enable-splash-screen" ) {
++ splash_screen = true;
++ } else if ( arg == "--disable-intro-music" ) {
++ intro_music = false;
++ } else if ( arg == "--enable-intro-music" ) {
++ intro_music = true;
++ } else if ( arg == "--disable-mouse-pointer" ) {
++ mouse_pointer = 1;
++ } else if ( arg == "--enable-mouse-pointer" ) {
++ mouse_pointer = 2;
++ } else if ( arg == "--disable-pause" ) {
++ pause = false;
++ } else if ( arg == "--enable-pause" ) {
++ pause = true;
++ } else if ( arg == "--disable-hud" ) {
++ hud_status = false;
++ } else if ( arg == "--enable-hud" ) {
++ hud_status = true;
++ } else if ( arg == "--disable-panel" ) {
++ panel_status = false;
++ } else if ( arg == "--enable-panel" ) {
++ panel_status = true;
++ fov *= 0.4232;
++ } else if ( arg == "--disable-sound" ) {
++ sound = false;
++ } else if ( arg == "--enable-sound" ) {
++ sound = true;
++ } else if ( arg.find( "--airport-id=") != string::npos ) {
++ airport_id = arg.substr( 13 );
++ } else if ( arg.find( "--lon=" ) != string::npos ) {
++ lon = parse_degree( arg.substr(6) );
++ } else if ( arg.find( "--lat=" ) != string::npos ) {
++ lat = parse_degree( arg.substr(6) );
++ } else if ( arg.find( "--altitude=" ) != string::npos ) {
++ if ( units == FG_UNITS_FEET ) {
++ altitude = atof( arg.substr(11) ) * FEET_TO_METER;
++ } else {
++ altitude = atof( arg.substr(11) );
++ }
++ } else if ( arg.find( "--heading=" ) != string::npos ) {
++ heading = atof( arg.substr(10) );
++ } else if ( arg.find( "--roll=" ) != string::npos ) {
++ roll = atof( arg.substr(7) );
++ } else if ( arg.find( "--pitch=" ) != string::npos ) {
++ pitch = atof( arg.substr(8) );
++ } else if ( arg.find( "--fg-root=" ) != string::npos ) {
++ fg_root = arg.substr( 10 );
++ } else if ( arg.find( "--fdm=" ) != string::npos ) {
++ flight_model = parse_fdm( arg.substr(6) );
++ } else if ( arg == "--fog-disable" ) {
++ fog = FG_FOG_DISABLED;
++ } else if ( arg == "--fog-fastest" ) {
++ fog = FG_FOG_FASTEST;
++ } else if ( arg == "--fog-nicest" ) {
++ fog = FG_FOG_NICEST;
++ } else if ( arg.find( "--fov=" ) != string::npos ) {
++ fov = parse_fov( arg.substr(6) );
++ } else if ( arg == "--disable-fullscreen" ) {
++ fullscreen = false;
++ } else if ( arg== "--enable-fullscreen") {
++ fullscreen = true;
++ } else if ( arg == "--shading-flat") {
++ shading = 0;
++ } else if ( arg == "--shading-smooth") {
++ shading = 1;
++ } else if ( arg == "--disable-skyblend") {
++ skyblend = false;
++ } else if ( arg== "--enable-skyblend" ) {
++ skyblend = true;
++ } else if ( arg == "--disable-textures" ) {
++ textures = false;
++ } else if ( arg == "--enable-textures" ) {
++ textures = true;
++ } else if ( arg == "--disable-wireframe" ) {
++ wireframe = false;
++ } else if ( arg == "--enable-wireframe" ) {
++ wireframe = true;
++ } else if ( arg.find( "--geometry=" ) != string::npos ) {
++ string geometry = arg.substr( 11 );
++ if ( geometry == "640x480" ) {
++ xsize = 640;
++ ysize = 480;
++ } else if ( geometry == "800x600" ) {
++ xsize = 800;
++ ysize = 600;
++ } else if ( geometry == "1024x768" ) {
++ xsize = 1024;
++ ysize = 768;
++ } else {
++ FG_LOG( FG_GENERAL, FG_ALERT, "Unknown geometry: " << geometry );
++ exit(-1);
++ }
++ } else if ( arg == "--units-feet" ) {
++ units = FG_UNITS_FEET;
++ } else if ( arg == "--units-meters" ) {
++ units = FG_UNITS_METERS;
++ } else if ( arg.find( "--tile-radius=" ) != string::npos ) {
++ tile_radius = parse_tile_radius( arg.substr(14) );
++ tile_diameter = tile_radius * 2 + 1;
++ } else if ( arg.find( "--time-offset=" ) != string::npos ) {
++ time_offset = parse_time_offset( (arg.substr(14)) );
++ } else if ( arg == "--hud-tris" ) {
++ tris_or_culled = 0;
++ } else if ( arg == "--hud-culled" ) {
++ tris_or_culled = 1;
++ } else if ( arg.find( "--serial=" ) != string::npos ) {
++ parse_serial( arg.substr(9) );
++ } else {
++ FG_LOG( FG_GENERAL, FG_ALERT, "Unknown option '" << arg << "'" );
++ return FG_OPTIONS_ERROR;
++ }
++
++ return FG_OPTIONS_OK;
++}
++
++
++// Parse the command line options
++int fgOPTIONS::parse_command_line( int argc, char **argv ) {
++ int i = 1;
++ int result;
++
++ FG_LOG(FG_GENERAL, FG_INFO, "Processing command line arguments");
++
++ while ( i < argc ) {
++ FG_LOG( FG_GENERAL, FG_DEBUG, "argv[" << i << "] = " << argv[i] );
++
++ result = parse_option(argv[i]);
++ if ( (result == FG_OPTIONS_HELP) || (result == FG_OPTIONS_ERROR) ) {
++ return(result);
++ }
++
++ i++;
++ }
++
++ return(FG_OPTIONS_OK);
++}
++
++
++// Parse config file options
++int fgOPTIONS::parse_config_file( const string& path ) {
++ fg_gzifstream in( path );
++ if ( !in )
++ return(FG_OPTIONS_ERROR);
++
++ FG_LOG( FG_GENERAL, FG_INFO, "Processing config file: " << path );
++
++ in >> skipcomment;
++ while ( !in.eof() )
++ {
++ string line;
++ getline( in, line );
++
++ if ( parse_option( line ) == FG_OPTIONS_ERROR ) {
++ FG_LOG( FG_GENERAL, FG_ALERT,
++ "Config file parse error: " << path << " '"
++ << line << "'" );
++ exit(-1);
++ }
++ in >> skipcomment;
++ }
++
++ return FG_OPTIONS_OK;
++}
++
++
++// Print usage message
++void fgOPTIONS::usage ( void ) {
++ printf("Usage: fg [ options ... ]\n");
++ printf("\n");
++
++ printf("General Options:\n");
++ printf("\t--help -h: print usage\n");
++ printf("\t--fg-root=path: specify the root path for all the data files\n");
++ printf("\t--disable-game-mode: disable full-screen game mode\n");
++ printf("\t--enable-game-mode: enable full-screen game mode\n");
++ printf("\t--disable-splash-screen: disable splash screen\n");
++ printf("\t--enable-splash-screen: enable splash screen\n");
++ printf("\t--disable-intro-music: disable introduction music\n");
++ printf("\t--enable-intro-music: enable introduction music\n");
++ printf("\t--disable-mouse-pointer: disable extra mouse pointer\n");
++ printf("\t--enable-mouse-pointer: enable extra mouse pointer (i.e. for\n");
++ printf("\t\tfull screen voodoo/voodoo-II based cards.)\n");
++ printf("\t--disable-pause: start out in an active state\n");
++ printf("\t--enable-pause: start out in a paused state\n");
++ printf("\n");
++
++ printf("Features:\n");
++ printf("\t--disable-hud: disable heads up display\n");
++ printf("\t--enable-hud: enable heads up display\n");
++ printf("\t--disable-panel: disable instrument panel\n");
++ printf("\t--enable-panel: enable instrumetn panel\n");
++ printf("\t--disable-sound: disable sound effects\n");
++ printf("\t--enable-sound: enable sound effects\n");
++ printf("\n");
++
++ printf("Flight Model:\n");
++ printf("\t--fdm=abcd: one of slew, jsb, larcsim, or external\n");
++ printf("\n");
++
++ printf("Initial Position and Orientation:\n");
++ printf("\t--airport-id=ABCD: specify starting postion by airport id\n");
++ printf("\t--lon=degrees: starting longitude in degrees (west = -)\n");
++ printf("\t--lat=degrees: starting latitude in degrees (south = -)\n");
++ printf("\t--altitude=feet: starting altitude in feet\n");
++ printf("\t\t(unless --units-meters specified\n");
++ printf("\t--heading=degrees: heading (yaw) angle in degress (Psi)\n");
++ printf("\t--roll=degrees: roll angle in degrees (Phi)\n");
++ printf("\t--pitch=degrees: pitch angle in degrees (Theta)\n");
++ printf("\n");
++
++ printf("Rendering Options:\n");
++ printf("\t--fog-disable: disable fog/haze\n");
++ printf("\t--fog-fastest: enable fastest fog/haze\n");
++ printf("\t--fog-nicest: enable nicest fog/haze\n");
++ printf("\t--fov=xx.x: specify initial field of view angle in degrees\n");
++ printf("\t--disable-fullscreen: disable fullscreen mode\n");
++ printf("\t--enable-fullscreen: enable fullscreen mode\n");
++ printf("\t--shading-flat: enable flat shading\n");
++ printf("\t--shading-smooth: enable smooth shading\n");
++ printf("\t--disable-skyblend: disable sky blending\n");
++ printf("\t--enable-skyblend: enable sky blending\n");
++ printf("\t--disable-textures: disable textures\n");
++ printf("\t--enable-textures: enable textures\n");
++ printf("\t--disable-wireframe: disable wireframe drawing mode\n");
++ printf("\t--enable-wireframe: enable wireframe drawing mode\n");
++ printf("\t--geometry=WWWxHHH: window geometry: 640x480, 800x600, etc.\n");
++ printf("\n");
++
++ printf("Scenery Options:\n");
++ printf("\t--tile-radius=n: specify tile radius, must be 1 - 4\n");
++ printf("\n");
++
++ printf("Hud Options:\n");
++ printf("\t--units-feet: Hud displays units in feet\n");
++ printf("\t--units-meters: Hud displays units in meters\n");
++ printf("\t--hud-tris: Hud displays number of triangles rendered\n");
++ printf("\t--hud-culled: Hud displays percentage of triangles culled\n");
++ printf("\n");
++
++ printf("Time Options:\n");
++ printf("\t--time-offset=[+-]hh:mm:ss: offset local time by this amount\n");
++}
++
++
++// Destructor
++fgOPTIONS::~fgOPTIONS( void ) {
++}
++
++
++// $Log$
++// Revision 1.43 1999/03/22 23:47:55 curt
++// FOV set properly when panel activated.
++//
++// Revision 1.42 1999/03/11 23:09:50 curt
++// When "Help" is selected from the menu check to see if netscape is running.
++// If so, command it to go to the flight gear user guide url. Otherwise
++// start a new version of netscape with this url.
++//
++// Revision 1.41 1999/03/02 01:03:17 curt
++// Tweaks for building with native SGI compilers.
++//
++// Revision 1.40 1999/02/26 22:09:51 curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.39 1999/02/05 21:29:12 curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.38 1999/02/01 21:33:35 curt
++// Renamed FlightGear/Simulator/Flight to FlightGear/Simulator/FDM since
++// Jon accepted my offer to do this and thought it was a good idea.
++//
++// Revision 1.37 1999/01/19 20:57:05 curt
++// MacOS portability changes contributed by "Robert Puyol" <puyol@abvent.fr>
++//
++// Revision 1.36 1999/01/07 20:25:10 curt
++// Updated struct fgGENERAL to class FGGeneral.
++//
++// Revision 1.35 1998/12/06 14:52:57 curt
++// Fixed a problem with the initial starting altitude. "v->abs_view_pos" wasn't
++// being calculated correctly at the beginning causing the first terrain
++// intersection to fail, returning a ground altitude of zero, causing the plane
++// to free fall for one frame, until the ground altitude was corrected, but now
++// being under the ground we got a big bounce and the plane always ended up
++// upside down.
++//
++// Revision 1.34 1998/12/05 15:54:22 curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.33 1998/12/04 01:30:44 curt
++// Added support for the External flight model.
++//
++// Revision 1.32 1998/11/25 01:34:00 curt
++// Support for an arbitrary number of serial ports.
++//
++// Revision 1.31 1998/11/23 21:49:04 curt
++// Borland portability tweaks.
++//
++// Revision 1.30 1998/11/16 14:00:02 curt
++// Added pow() macro bug work around.
++// Added support for starting FGFS at various resolutions.
++// Added some initial serial port support.
++// Specify default log levels in main().
++//
++// Revision 1.29 1998/11/06 21:18:12 curt
++// Converted to new logstream debugging facility. This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.28 1998/11/06 14:47:03 curt
++// Changes to track Bernie's updates to fgstream.
++//
++// Revision 1.27 1998/11/02 23:04:04 curt
++// HUD units now display in feet by default with meters being a command line
++// option.
++//
++// Revision 1.26 1998/10/17 01:34:24 curt
++// C++ ifying ...
++//
++// Revision 1.25 1998/09/15 02:09:27 curt
++// Include/fg_callback.hxx
++// Moved code inline to stop g++ 2.7 from complaining.
++//
++// Simulator/Time/event.[ch]xx
++// Changed return type of fgEVENT::printStat(). void caused g++ 2.7 to
++// complain bitterly.
++//
++// Minor bugfix and changes.
++//
++// Simulator/Main/GLUTmain.cxx
++// Added missing type to idle_state definition - eliminates a warning.
++//
++// Simulator/Main/fg_init.cxx
++// Changes to airport lookup.
++//
++// Simulator/Main/options.cxx
++// Uses fg_gzifstream when loading config file.
++//
++// Revision 1.24 1998/09/08 15:04:33 curt
++// Optimizations by Norman Vine.
++//
++// Revision 1.23 1998/08/27 17:02:07 curt
++// Contributions from Bernie Bright <bbright@c031.aone.net.au>
++// - use strings for fg_root and airport_id and added methods to return
++// them as strings,
++// - inlined all access methods,
++// - made the parsing functions private methods,
++// - deleted some unused functions.
++// - propogated some of these changes out a bit further.
++//
++// Revision 1.22 1998/08/24 20:11:13 curt
++// Added i/I to toggle full vs. minimal HUD.
++// Added a --hud-tris vs --hud-culled option.
++// Moved options accessor funtions to options.hxx.
++//
++// Revision 1.21 1998/08/20 15:10:34 curt
++// Added GameGLUT support.
++//
++// Revision 1.20 1998/07/30 23:48:28 curt
++// Output position & orientation when pausing.
++// Eliminated libtool use.
++// Added options to specify initial position and orientation.
++// Changed default fov to 55 degrees.
++// Added command line option to start in paused or unpaused state.
++//
++// Revision 1.19 1998/07/27 18:41:25 curt
++// Added a pause command "p"
++// Fixed some initialization order problems between pui and glut.
++// Added an --enable/disable-sound option.
++//
++// Revision 1.18 1998/07/22 01:27:03 curt
++// Strip out \r when parsing config file in case we are on a windoze system.
++//
++// Revision 1.17 1998/07/16 17:33:38 curt
++// "H" / "h" now control hud brightness as well with off being one of the
++// states.
++// Better checking for xmesa/fx 3dfx fullscreen/window support for deciding
++// whether or not to build in the feature.
++// Translucent menu support.
++// HAVE_AUDIO_SUPPORT -> ENABLE_AUDIO_SUPPORT
++// Use fork() / wait() for playing mp3 init music in background under unix.
++// Changed default tile diameter to 5.
++//
++// Revision 1.16 1998/07/13 21:01:39 curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.15 1998/07/06 21:34:19 curt
++// Added an enable/disable splash screen option.
++// Added an enable/disable intro music option.
++// Added an enable/disable instrument panel option.
++// Added an enable/disable mouse pointer option.
++// Added using namespace std for compilers that support this.
++//
++// Revision 1.14 1998/07/04 00:52:26 curt
++// Add my own version of gluLookAt() (which is nearly identical to the
++// Mesa/glu version.) But, by calculating the Model View matrix our selves
++// we can save this matrix without having to read it back in from the video
++// card. This hopefully allows us to save a few cpu cycles when rendering
++// out the fragments because we can just use glLoadMatrixd() with the
++// precalculated matrix for each tile rather than doing a push(), translate(),
++// pop() for every fragment.
++//
++// Panel status defaults to off for now until it gets a bit more developed.
++//
++// Extract OpenGL driver info on initialization.
++//
++// Revision 1.13 1998/06/27 16:54:34 curt
++// Replaced "extern displayInstruments" with a entry in fgOPTIONS.
++// Don't change the view port when displaying the panel.
++//
++// Revision 1.12 1998/06/17 21:35:13 curt
++// Refined conditional audio support compilation.
++// Moved texture parameter setup calls to ../Scenery/materials.cxx
++// #include <string.h> before various STL includes.
++// Make HUD default state be enabled.
++//
++// Revision 1.11 1998/06/13 00:40:33 curt
++// Tweaked fog command line options.
++//
++// Revision 1.10 1998/05/16 13:08:36 curt
++// C++ - ified views.[ch]xx
++// Shuffled some additional view parameters into the fgVIEW class.
++// Changed tile-radius to tile-diameter because it is a much better
++// name.
++// Added a WORLD_TO_EYE transformation to views.cxx. This allows us
++// to transform world space to eye space for view frustum culling.
++//
++// Revision 1.9 1998/05/13 18:29:59 curt
++// Added a keyboard binding to dynamically adjust field of view.
++// Added a command line option to specify fov.
++// Adjusted terrain color.
++// Root path info moved to fgOPTIONS.
++// Added ability to parse options out of a config file.
++//
++// Revision 1.8 1998/05/07 23:14:16 curt
++// Added "D" key binding to set autopilot heading.
++// Made frame rate calculation average out over last 10 frames.
++// Borland C++ floating point exception workaround.
++// Added a --tile-radius=n option.
++//
++// Revision 1.7 1998/05/06 03:16:25 curt
++// Added an averaged global frame rate counter.
++// Added an option to control tile radius.
++//
++// Revision 1.6 1998/05/03 00:47:32 curt
++// Added an option to enable/disable full-screen mode.
++//
++// Revision 1.5 1998/04/30 12:34:19 curt
++// Added command line rendering options:
++// enable/disable fog/haze
++// specify smooth/flat shading
++// disable sky blending and just use a solid color
++// enable wireframe drawing mode
++//
++// Revision 1.4 1998/04/28 01:20:22 curt
++// Type-ified fgTIME and fgVIEW.
++// Added a command line option to disable textures.
++//
++// Revision 1.3 1998/04/26 05:01:19 curt
++// Added an rint() / HAVE_RINT check.
++//
++// Revision 1.2 1998/04/25 15:11:12 curt
++// Added an command line option to set starting position based on airport ID.
++//
++// Revision 1.1 1998/04/24 00:49:21 curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Trying out some different option parsing code.
++// Some code reorganization.
++//
++//
--- /dev/null
--- /dev/null
++// options.hxx -- class to handle command line options
++//
++// Written by Curtis Olson, started April 1998.
++//
++// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#ifndef _OPTIONS_HXX
++#define _OPTIONS_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#include <Include/compiler.h>
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#if defined(FX) && defined(XMESA)
++extern bool global_fullscreen;
++#endif
++
++#include STL_STRING
++#include <vector>
++
++FG_USING_STD(vector);
++FG_USING_STD(string);
++
++typedef vector < string > str_container;
++typedef str_container::iterator str_iterator;
++typedef str_container::const_iterator const_str_iterator;
++
++
++class fgOPTIONS {
++
++public:
++
++ enum
++ {
++ FG_OPTIONS_OK = 0,
++ FG_OPTIONS_HELP = 1,
++ FG_OPTIONS_ERROR = 2
++ };
++
++ enum
++ {
++ FG_UNITS_FEET = 0,
++ FG_UNITS_METERS = 1
++ };
++
++ enum fgFogKind
++ {
++ FG_FOG_DISABLED = 0,
++ FG_FOG_FASTEST = 1,
++ FG_FOG_NICEST = 2
++ };
++
++ enum
++ {
++ FG_RADIUS_MIN = 1,
++ FG_RADIUS_MAX = 4
++ };
++
++private:
++
++ // The flight gear "root" directory
++ string fg_root;
++
++ // Starting position and orientation
++ string airport_id; // ID of initial starting airport
++ double lon; // starting longitude in degrees (west = -)
++ double lat; // starting latitude in degrees (south = -)
++ double altitude; // starting altitude in meters
++ double heading; // heading (yaw) angle in degress (Psi)
++ double roll; // roll angle in degrees (Phi)
++ double pitch; // pitch angle in degrees (Theta)
++
++ // Miscellaneous
++ bool game_mode; // Game mode enabled/disabled
++ bool splash_screen; // show splash screen
++ bool intro_music; // play introductory music
++ int mouse_pointer; // show mouse pointer
++ bool pause; // pause intially enabled/disabled
++
++ // Features
++ bool hud_status; // HUD on/off
++ bool panel_status; // Panel on/off
++ bool sound; // play sound effects
++
++ // Flight Model options
++ int flight_model; // Flight Model: FG_SLEW, FG_LARCSIM, etc.
++
++ // Rendering options
++ fgFogKind fog; // Fog nicest/fastest/disabled
++ double fov; // Field of View
++ bool fullscreen; // Full screen mode enabled/disabled
++ int shading; // shading method, 0 = Flat, 1 = Smooth
++ bool skyblend; // Blend sky to haze (using polygons) or just clear
++ bool textures; // Textures enabled/disabled
++ bool wireframe; // Wireframe mode enabled/disabled
++ int xsize, ysize; // window size derived from geometry string
++
++ // Scenery options
++ int tile_radius; // Square radius of rendered tiles (around center
++ // square.)
++ int tile_diameter; // Diameter of rendered tiles. for instance
++ // if tile_diameter = 3 then a 3 x 3 grid of tiles will
++ // be drawn. Increase this to see terrain that is
++ // further away.
++
++ // HUD options
++ int units; // feet or meters
++ int tris_or_culled;
++
++ // Time options
++ int time_offset; // Offset true time by this many seconds
++
++ // Serial Ports, we currently support up to four channels
++ // fgSerialPortKind port_a_kind; // Port a kind
++ // fgSerialPortKind port_b_kind; // Port b kind
++ // fgSerialPortKind port_c_kind; // Port c kind
++ // fgSerialPortKind port_d_kind; // Port d kind
++
++ // Serial port configuration strings
++ str_container port_options_list;
++
++public:
++
++ fgOPTIONS();
++ ~fgOPTIONS();
++
++ // Parse a single option
++ int parse_option( const string& arg );
++
++ // Parse the command line options
++ int parse_command_line( int argc, char **argv );
++
++ // Parse the command line options
++ int parse_config_file( const string& path );
++
++ // Print usage message
++ void usage ( void );
++
++ // Query functions
++ inline string get_fg_root() const { return fg_root; }
++ inline string get_airport_id() const { return airport_id; }
++ inline double get_lon() const { return lon; }
++ inline double get_lat() const { return lat; }
++ inline double get_altitude() const { return altitude; }
++ inline double get_heading() const { return heading; }
++ inline double get_roll() const { return roll; }
++ inline double get_pitch() const { return pitch; }
++ inline bool get_game_mode() const { return game_mode; }
++ inline bool get_splash_screen() const { return splash_screen; }
++ inline bool get_intro_music() const { return intro_music; }
++ inline int get_mouse_pointer() const { return mouse_pointer; }
++ inline bool get_pause() const { return pause; }
++ inline bool get_hud_status() const { return hud_status; }
++ inline bool get_panel_status() const { return panel_status; }
++ inline bool get_sound() const { return sound; }
++ inline int get_flight_model() const { return flight_model; }
++ inline bool fog_enabled() const { return fog != FG_FOG_DISABLED; }
++ inline fgFogKind get_fog() const { return fog; }
++ inline double get_fov() const { return fov; }
++ inline bool get_fullscreen() const { return fullscreen; }
++ inline int get_shading() const { return shading; }
++ inline bool get_skyblend() const { return skyblend; }
++ inline bool get_textures() const { return textures; }
++ inline bool get_wireframe() const { return wireframe; }
++ inline int get_xsize() const { return xsize; }
++ inline int get_ysize() const { return ysize; }
++ inline int get_tile_radius() const { return tile_radius; }
++ inline int get_tile_diameter() const { return tile_diameter; }
++
++ inline int get_units() const { return units; }
++ inline int get_tris_or_culled() const { return tris_or_culled; }
++
++ inline int get_time_offset() const { return time_offset; }
++
++ inline str_container get_port_options_list() const {
++ return port_options_list;
++ }
++
++ // Update functions
++ inline void set_hud_status( bool status ) { hud_status = status; }
++ inline void set_fov( double amount ) { fov = amount; }
++ inline void set_textures( bool status ) { textures = status; }
++ inline void cycle_fog( void ) {
++ if ( fog == FG_FOG_DISABLED ) {
++ fog = FG_FOG_FASTEST;
++ } else if ( fog == FG_FOG_FASTEST ) {
++ fog = FG_FOG_NICEST;
++ xglHint ( GL_FOG_HINT, GL_NICEST );
++ } else if ( fog == FG_FOG_NICEST ) {
++ fog = FG_FOG_DISABLED;
++ xglHint ( GL_FOG_HINT, GL_FASTEST );
++ }
++ }
++ inline void set_xsize( int x ) { xsize= x; }
++ inline void set_ysize( int y ) { xsize= y; }
++
++private:
++
++ double parse_time( const string& time_str );
++ double parse_degree( const string& degree_str );
++ int parse_time_offset( const string& time_str );
++ int parse_tile_radius( const string& arg );
++ int parse_fdm( const string& fm );
++ double parse_fov( const string& arg );
++ bool parse_serial( const string& serial_str );
++};
++
++
++extern fgOPTIONS current_options;
++
++
++#endif /* _OPTIONS_HXX */
++
++
++// $Log$
++// Revision 1.30 1999/03/11 23:09:51 curt
++// When "Help" is selected from the menu check to see if netscape is running.
++// If so, command it to go to the flight gear user guide url. Otherwise
++// start a new version of netscape with this url.
++//
++// Revision 1.29 1999/03/02 01:03:19 curt
++// Tweaks for building with native SGI compilers.
++//
++// Revision 1.28 1999/02/26 22:09:52 curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.27 1999/02/05 21:29:13 curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.26 1999/02/02 20:13:37 curt
++// MSVC++ portability changes by Bernie Bright:
++//
++// Lib/Serial/serial.[ch]xx: Initial Windows support - incomplete.
++// Simulator/Astro/stars.cxx: typo? included <stdio> instead of <cstdio>
++// Simulator/Cockpit/hud.cxx: Added Standard headers
++// Simulator/Cockpit/panel.cxx: Redefinition of default parameter
++// Simulator/Flight/flight.cxx: Replaced cout with FG_LOG. Deleted <stdio.h>
++// Simulator/Main/fg_init.cxx:
++// Simulator/Main/GLUTmain.cxx:
++// Simulator/Main/options.hxx: Shuffled <fg_serial.hxx> dependency
++// Simulator/Objects/material.hxx:
++// Simulator/Time/timestamp.hxx: VC++ friend kludge
++// Simulator/Scenery/tile.[ch]xx: Fixed using std::X declarations
++// Simulator/Main/views.hxx: Added a constant
++//
++// Revision 1.25 1999/01/19 20:57:06 curt
++// MacOS portability changes contributed by "Robert Puyol" <puyol@abvent.fr>
++//
++// Revision 1.24 1998/11/25 01:34:01 curt
++// Support for an arbitrary number of serial ports.
++//
++// Revision 1.23 1998/11/23 21:49:05 curt
++// Borland portability tweaks.
++//
++// Revision 1.22 1998/11/20 01:02:38 curt
++// Try to detect Mesa/Glide/Voodoo and chose the appropriate resolution.
++//
++// Revision 1.21 1998/11/16 14:00:04 curt
++// Added pow() macro bug work around.
++// Added support for starting FGFS at various resolutions.
++// Added some initial serial port support.
++// Specify default log levels in main().
++//
++// Revision 1.20 1998/11/02 23:04:05 curt
++// HUD units now display in feet by default with meters being a command line
++// option.
++//
++// Revision 1.19 1998/10/25 14:08:49 curt
++// Turned "struct fgCONTROLS" into a class, with inlined accessor functions.
++//
++// Revision 1.18 1998/09/17 18:35:31 curt
++// Added F8 to toggle fog and F9 to toggle texturing.
++//
++// Revision 1.17 1998/09/08 21:40:10 curt
++// Fixes by Charlie Hotchkiss.
++//
++// Revision 1.16 1998/08/27 17:02:08 curt
++// Contributions from Bernie Bright <bbright@c031.aone.net.au>
++// - use strings for fg_root and airport_id and added methods to return
++// them as strings,
++// - inlined all access methods,
++// - made the parsing functions private methods,
++// - deleted some unused functions.
++// - propogated some of these changes out a bit further.
++//
++// Revision 1.15 1998/08/24 20:11:15 curt
++// Added i/I to toggle full vs. minimal HUD.
++// Added a --hud-tris vs --hud-culled option.
++// Moved options accessor funtions to options.hxx.
++//
++// Revision 1.14 1998/08/20 15:10:35 curt
++// Added GameGLUT support.
++//
++// Revision 1.13 1998/07/30 23:48:29 curt
++// Output position & orientation when pausing.
++// Eliminated libtool use.
++// Added options to specify initial position and orientation.
++// Changed default fov to 55 degrees.
++// Added command line option to start in paused or unpaused state.
++//
++// Revision 1.12 1998/07/27 18:41:26 curt
++// Added a pause command "p"
++// Fixed some initialization order problems between pui and glut.
++// Added an --enable/disable-sound option.
++//
++// Revision 1.11 1998/07/13 21:01:39 curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.10 1998/07/06 21:34:20 curt
++// Added an enable/disable splash screen option.
++// Added an enable/disable intro music option.
++// Added an enable/disable instrument panel option.
++// Added an enable/disable mouse pointer option.
++// Added using namespace std for compilers that support this.
++//
++// Revision 1.9 1998/06/27 16:54:34 curt
++// Replaced "extern displayInstruments" with a entry in fgOPTIONS.
++// Don't change the view port when displaying the panel.
++//
++// Revision 1.8 1998/05/16 13:08:36 curt
++// C++ - ified views.[ch]xx
++// Shuffled some additional view parameters into the fgVIEW class.
++// Changed tile-radius to tile-diameter because it is a much better
++// name.
++// Added a WORLD_TO_EYE transformation to views.cxx. This allows us
++// to transform world space to eye space for view frustum culling.
++//
++// Revision 1.7 1998/05/13 18:29:59 curt
++// Added a keyboard binding to dynamically adjust field of view.
++// Added a command line option to specify fov.
++// Adjusted terrain color.
++// Root path info moved to fgOPTIONS.
++// Added ability to parse options out of a config file.
++//
++// Revision 1.6 1998/05/06 03:16:26 curt
++// Added an averaged global frame rate counter.
++// Added an option to control tile radius.
++//
++// Revision 1.5 1998/05/03 00:47:32 curt
++// Added an option to enable/disable full-screen mode.
++//
++// Revision 1.4 1998/04/30 12:34:19 curt
++// Added command line rendering options:
++// enable/disable fog/haze
++// specify smooth/flat shading
++// disable sky blending and just use a solid color
++// enable wireframe drawing mode
++//
++// Revision 1.3 1998/04/28 01:20:23 curt
++// Type-ified fgTIME and fgVIEW.
++// Added a command line option to disable textures.
++//
++// Revision 1.2 1998/04/25 15:11:13 curt
++// Added an command line option to set starting position based on airport ID.
++//
++// Revision 1.1 1998/04/24 00:49:21 curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Trying out some different option parsing code.
++// Some code reorganization.
++//
++//
--- /dev/null
--- /dev/null
++REM @ECHO OFF\r
++\r
++REM Skip ahead to RUN1 if %FG_ROOT%\BIN\FGFS.EXE exists\r
++IF EXIST %FG_ROOT%\BIN\FGFS.EXE GOTO RUN1\r
++\r
++REM %FG_ROOT% wasn't set right so let's try "."\r
++SET FG_ROOT=.\r
++IF EXIST %FG_ROOT%\BIN\FGFS.EXE GOTO RUN1\r
++\r
++REM %FG_ROOT% wasn't set right so let's try ".."\r
++SET FG_ROOT=..\r
++IF EXIST %FG_ROOT%\BIN\FGFS.EXE GOTO RUN1\r
++\r
++REM %FG_ROOT% wasn't set right so let's try "@prefix@"\r
++SET FG_ROOT=@prefix@\r
++IF EXIST %FG_ROOT%\BIN\FGFS.EXE GOTO RUN1\r
++\r
++ECHO Cannot find %FG_ROOT%\BIN\FGFS.EXE\r
++GOTO END\r
++\r
++:RUN1\r
++REM Now that FG_ROOT has been set, run the program\r
++ECHO FG_ROOT = %FG_ROOT%\r
++%FG_ROOT%\BIN\FGFS.EXE %1 %2 %3 %4 %5 %6 %7 %8 %9\r
++\r
++GOTO END\r
++\r
++:END\r
--- /dev/null
--- /dev/null
++#!/usr/bin/perl
++#
++# runfg -- front end for setting up the FG_ROOT env variable and launching
++# the fg executable.
++#
++# Written by Curtis Olson, started September 1997.
++#
++# Copyright (C) 1997 - 1998 Curtis L. Olson - curt@me.umn.edu
++#
++# 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$
++# (Log is kept at end of this file)
++#---------------------------------------------------------------------------
++
++
++$prefix = "@prefix@";
++# print "-> $prefix\n";
++
++# potential names of Flight Gear executable to try
++@files = ( "fg", "fg.exe" );
++
++# search for the executable
++# potential paths where the executable may be found
++@paths = ( ".", "Simulator/Main", $prefix );
++
++$savepath = "";
++$savefile = "";
++
++foreach $path (@paths) {
++ foreach $file (@files) {
++ # print "'$savepath'\n";
++ if ( $savepath eq "" ) {
++ # don't search again if we've already found one
++ # print "checking $path" . "bin/$file and $path" . "$file\n";
++ if ( -x "$path/bin/$file" ) {
++ $saveprefix = $path;
++ $savepath = "$path/bin";
++ $savefile = "$file";
++ } elsif ( -x "$path/$file" ) {
++ $saveprefix = $path;
++ $savepath = "$path";
++ $savefile = "$file";
++ }
++ } else {
++ # print "skipping $path/bin/$file and $path/$file\n";
++ }
++ }
++}
++
++die "Cannot locate program.\n" if ( $savepath eq "" );
++
++
++# search for the "FlightGear" root directory
++@paths = ( $prefix, $saveprefix, $ENV{HOME} );
++
++$fg_root = "";
++
++foreach $path (@paths) {
++ # print "trying $path\n";
++
++ if ( $fg_root eq "" ) {
++ if ( -d "$path/FlightGear" ) {
++ $fg_root = "$path/FlightGear";
++ } elsif ( -d "$path/lib/FlightGear" ) {
++ $fg_root = "$path/lib/FlightGear";
++ }
++ }
++}
++
++die "Cannot locate FG root directory (data)\n" if ( $fg_root eq "" );
++
++# run Flight Gear
++print "Running $savepath/$savefile --fg-root=$fg_root @ARGV\n";
++exec("$savepath/$savefile --fg-root=$fg_root @ARGV");
++
++
++#---------------------------------------------------------------------------
++# $Log$
++# Revision 1.2 1998/08/25 16:59:10 curt
++# Directory reshuffling.
++#
++# Revision 1.1 1998/08/24 20:32:41 curt
++# runfg.in renamed to runfgfs.in
++#
++# Revision 1.3 1998/08/03 22:16:42 curt
++# Updated to be smarter about finding $FG_ROOT.
++#
++# Revision 1.2 1998/04/25 22:06:31 curt
++# Edited cvs log messages in source files ... bad bad bad!
++#
++# Revision 1.1 1998/04/09 01:45:31 curt
++# Moved to Main/ and incorperated with automake
++#
++# Revision 1.4 1998/03/09 22:52:38 curt
++# Mod's to better support win32 if perl exists.
++#
++# Revision 1.3 1998/02/16 16:17:34 curt
++# Minor tweaks.
++#
++# Revision 1.2 1998/01/27 00:47:43 curt
++# Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++# system and commandline/config file processing code.
++#
++# Revision 1.1 1997/10/28 18:47:27 curt
++# Initial revision.
++#
--- /dev/null
--- /dev/null
++// splash.cxx -- draws the initial splash screen
++//
++// Written by Curtis Olson, started July 1998. (With a little looking
++// at Freidemann's panel code.) :-)
++//
++// Copyright (C) 1997 Michele F. America - nomimarketing@mail.telepac.pt
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#include <string.h>
++
++#include <Debug/logstream.hxx>
++#include <Main/options.hxx>
++#include <Math/fg_random.h>
++#include <Objects/texload.h>
++
++#include "splash.hxx"
++#include "views.hxx"
++
++
++static GLuint splash_texid;
++static GLubyte *splash_texbuf;
++
++
++// Initialize the splash screen
++void fgSplashInit ( void ) {
++ string tpath, fg_tpath;
++ int width, height;
++
++ FG_LOG( FG_GENERAL, FG_INFO, "Initializing splash screen" );
++#ifdef GL_VERSION_1_1
++ xglGenTextures(1, &splash_texid);
++ xglBindTexture(GL_TEXTURE_2D, splash_texid);
++#elif GL_EXT_texture_object
++ xglGenTexturesEXT(1, &splash_texid);
++ xglBindTextureEXT(GL_TEXTURE_2D, splash_texid);
++#else
++# error port me
++#endif
++
++ xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
++ xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
++ xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
++ xglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
++
++ // load in the texture data
++ int num = (int)(fg_random() * 4.0 + 1.0);
++ char num_str[256];
++ sprintf(num_str, "%d", num);
++ tpath = current_options.get_fg_root() + "/Textures/Splash";
++ tpath += num_str;
++ tpath += ".rgb";
++
++ if ( (splash_texbuf =
++ read_rgb_texture(tpath.c_str(), &width, &height)) == NULL )
++ {
++ // Try compressed
++ fg_tpath = tpath + ".gz";
++ if ( (splash_texbuf =
++ read_rgb_texture(fg_tpath.c_str(), &width, &height)) == NULL )
++ {
++ FG_LOG( FG_GENERAL, FG_ALERT,
++ "Error in loading splash screen texture " << tpath );
++ exit(-1);
++ }
++ }
++
++ xglTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB,
++ GL_UNSIGNED_BYTE, (GLvoid *)(splash_texbuf) );
++}
++
++
++// Update the splash screen with progress specified from 0.0 to 1.0
++void fgSplashUpdate ( double progress ) {
++ int xmin, ymin, xmax, ymax;
++ int xsize = 480;
++ int ysize = 380;
++
++ xmin = (current_view.get_winWidth() - xsize) / 2;
++ xmax = xmin + xsize;
++
++ ymin = (current_view.get_winHeight() - ysize) / 2;
++ ymax = ymin + ysize;
++
++ // first clear the screen;
++ xglClearColor(0.0, 0.0, 0.0, 1.0);
++ xglClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT );
++
++ // now draw the logo
++ xglMatrixMode(GL_PROJECTION);
++ xglPushMatrix();
++ xglLoadIdentity();
++ gluOrtho2D(0, current_view.get_winWidth(), 0, current_view.get_winHeight());
++ xglMatrixMode(GL_MODELVIEW);
++ xglPushMatrix();
++ xglLoadIdentity();
++
++ xglDisable(GL_DEPTH_TEST);
++ xglDisable(GL_LIGHTING);
++ xglEnable(GL_TEXTURE_2D);
++#ifdef GL_VERSION_1_1
++ xglBindTexture(GL_TEXTURE_2D, splash_texid);
++#elif GL_EXT_texture_object
++ xglBindTextureEXT(GL_TEXTURE_2D, splash_texid);
++#else
++# error port me
++#endif
++ xglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
++
++ xglBegin(GL_POLYGON);
++ xglTexCoord2f(0.0, 0.0); glVertex2f(xmin, ymin);
++ xglTexCoord2f(1.0, 0.0); glVertex2f(xmax, ymin);
++ xglTexCoord2f(1.0, 1.0); glVertex2f(xmax, ymax);
++ xglTexCoord2f(0.0, 1.0); glVertex2f(xmin, ymax);
++ xglEnd();
++
++ xglutSwapBuffers();
++
++ xglEnable(GL_DEPTH_TEST);
++ xglEnable(GL_LIGHTING);
++ xglDisable(GL_TEXTURE_2D);
++
++ xglMatrixMode(GL_PROJECTION);
++ xglPopMatrix();
++ xglMatrixMode(GL_MODELVIEW);
++ xglPopMatrix();
++}
++
++
++// $Log$
++// Revision 1.10 1999/03/08 21:56:40 curt
++// Added panel changes sent in by Friedemann.
++// Added a splash screen randomization since we have several nice splash screens.
++//
++// Revision 1.9 1998/12/09 18:50:26 curt
++// Converted "class fgVIEW" to "class FGView" and updated to make data
++// members private and make required accessor functions.
++//
++// Revision 1.8 1998/11/16 14:00:05 curt
++// Added pow() macro bug work around.
++// Added support for starting FGFS at various resolutions.
++// Added some initial serial port support.
++// Specify default log levels in main().
++//
++// Revision 1.7 1998/11/06 21:18:14 curt
++// Converted to new logstream debugging facility. This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.6 1998/10/17 01:34:25 curt
++// C++ ifying ...
++//
++// Revision 1.5 1998/09/26 13:17:29 curt
++// Clear screen to "black" before drawing splash screen.
++//
++// Revision 1.4 1998/08/27 17:02:08 curt
++// Contributions from Bernie Bright <bbright@c031.aone.net.au>
++// - use strings for fg_root and airport_id and added methods to return
++// them as strings,
++// - inlined all access methods,
++// - made the parsing functions private methods,
++// - deleted some unused functions.
++// - propogated some of these changes out a bit further.
++//
++// Revision 1.3 1998/08/25 16:59:10 curt
++// Directory reshuffling.
++//
++// Revision 1.2 1998/07/13 21:01:40 curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.1 1998/07/06 02:42:36 curt
++// Initial revision.
++//
++
--- /dev/null
--- /dev/null
++// splash.hxx -- draws the initial splash screen
++//
++// Written by Curtis Olson, started July 1998. (With a little looking
++// at Freidemann's panel code.) :-)
++//
++// Copyright (C) 1997 Michele F. America - nomimarketing@mail.telepac.pt
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#ifndef _SPLASH_HXX
++#define _SPLASH_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++
++// Initialize the splash screen
++void fgSplashInit ( void );
++
++// Update the splash screen with progress specified from 0.0 to 1.0
++void fgSplashUpdate ( double progress );
++
++
++#endif // _SPLASH_HXX
++
++
++// $Log$
++// Revision 1.1 1998/07/06 02:42:37 curt
++// Initial revision.
++//
++//
--- /dev/null
--- /dev/null
++// views.cxx -- data structures and routines for managing and view
++// parameters.
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#include <Aircraft/aircraft.hxx>
++#include <Cockpit/panel.hxx>
++#include <Debug/logstream.hxx>
++#include <Include/fg_constants.h>
++#include <Math/mat3.h>
++#include <Math/point3d.hxx>
++#include <Math/polar3d.hxx>
++#include <Math/vector.hxx>
++#include <Scenery/scenery.hxx>
++#include <Time/fg_time.hxx>
++
++#include "options.hxx"
++#include "views.hxx"
++
++
++// Define following to extract various vectors directly
++// from matrices we have allready computed
++// rather then performing 'textbook algebra' to rederive them
++// Norman Vine -- nhv@yahoo.com
++// #define FG_VIEW_INLINE_OPTIMIZATIONS
++
++// temporary (hopefully) hack
++static int panel_hist = 0;
++
++
++// specify code paths ... these are done as variable rather than
++// #define's because down the road we may want to choose between them
++// on the fly for different flight models ... this way magic carpet
++// and external modes wouldn't need to recreate the LaRCsim matrices
++// themselves.
++
++static const bool use_larcsim_local_to_body = false;
++
++
++// This is a record containing current view parameters
++FGView current_view;
++
++
++// Constructor
++FGView::FGView( void ) {
++ MAT3identity(WORLD);
++}
++
++
++// Initialize a view structure
++void FGView::Init( void ) {
++ FG_LOG( FG_VIEW, FG_INFO, "Initializing View parameters" );
++
++ view_offset = 0.0;
++ goal_view_offset = 0.0;
++
++ winWidth = current_options.get_xsize();
++ winHeight = current_options.get_ysize();
++
++ if ( ! current_options.get_panel_status() ) {
++ current_view.set_win_ratio( (GLfloat) winWidth / (GLfloat) winHeight );
++ } else {
++ current_view.set_win_ratio( (GLfloat) winWidth /
++ ((GLfloat) (winHeight)*0.4232) );
++ }
++
++ force_update_fov_math();
++}
++
++
++// Update the field of view coefficients
++void FGView::UpdateFOV( const fgOPTIONS& o ) {
++ double fov, theta_x, theta_y;
++
++ fov = o.get_fov();
++
++ // printf("win_ratio = %.2f\n", win_ratio);
++ // calculate sin() and cos() of fov / 2 in X direction;
++ theta_x = (fov * win_ratio * DEG_TO_RAD) / 2.0;
++ // printf("theta_x = %.2f\n", theta_x);
++ sin_fov_x = sin(theta_x);
++ cos_fov_x = cos(theta_x);
++ slope_x = -cos_fov_x / sin_fov_x;
++ // printf("slope_x = %.2f\n", slope_x);
++
++ // fov_x_clip and fov_y_clip convoluted algebraic simplification
++ // see code executed in tilemgr.cxx when USE_FAST_FOV_CLIP not
++ // defined Norman Vine -- nhv@yahoo.com
++#if defined( USE_FAST_FOV_CLIP )
++ fov_x_clip = slope_x*cos_fov_x - sin_fov_x;
++#endif // defined( USE_FAST_FOV_CLIP )
++
++ // calculate sin() and cos() of fov / 2 in Y direction;
++ theta_y = (fov * DEG_TO_RAD) / 2.0;
++ // printf("theta_y = %.2f\n", theta_y);
++ sin_fov_y = sin(theta_y);
++ cos_fov_y = cos(theta_y);
++ slope_y = cos_fov_y / sin_fov_y;
++ // printf("slope_y = %.2f\n", slope_y);
++
++#if defined( USE_FAST_FOV_CLIP )
++ fov_y_clip = -(slope_y*cos_fov_y + sin_fov_y);
++#endif // defined( USE_FAST_FOV_CLIP )
++}
++
++
++// Basically, this is a modified version of the Mesa gluLookAt()
++// function that's been modified slightly so we can capture the
++// result before sending it off to OpenGL land.
++void FGView::LookAt( GLdouble eyex, GLdouble eyey, GLdouble eyez,
++ GLdouble centerx, GLdouble centery, GLdouble centerz,
++ GLdouble upx, GLdouble upy, GLdouble upz ) {
++ GLdouble *m;
++ GLdouble x[3], y[3], z[3];
++ GLdouble mag;
++
++ m = current_view.MODEL_VIEW;
++
++ /* Make rotation matrix */
++
++ /* Z vector */
++ z[0] = eyex - centerx;
++ z[1] = eyey - centery;
++ z[2] = eyez - centerz;
++ mag = sqrt( z[0]*z[0] + z[1]*z[1] + z[2]*z[2] );
++ if (mag) { /* mpichler, 19950515 */
++ z[0] /= mag;
++ z[1] /= mag;
++ z[2] /= mag;
++ }
++
++ /* Y vector */
++ y[0] = upx;
++ y[1] = upy;
++ y[2] = upz;
++
++ /* X vector = Y cross Z */
++ x[0] = y[1]*z[2] - y[2]*z[1];
++ x[1] = -y[0]*z[2] + y[2]*z[0];
++ x[2] = y[0]*z[1] - y[1]*z[0];
++
++ /* Recompute Y = Z cross X */
++ y[0] = z[1]*x[2] - z[2]*x[1];
++ y[1] = -z[0]*x[2] + z[2]*x[0];
++ y[2] = z[0]*x[1] - z[1]*x[0];
++
++ /* mpichler, 19950515 */
++ /* cross product gives area of parallelogram, which is < 1.0 for
++ * non-perpendicular unit-length vectors; so normalize x, y here
++ */
++
++ mag = sqrt( x[0]*x[0] + x[1]*x[1] + x[2]*x[2] );
++ if (mag) {
++ x[0] /= mag;
++ x[1] /= mag;
++ x[2] /= mag;
++ }
++
++ mag = sqrt( y[0]*y[0] + y[1]*y[1] + y[2]*y[2] );
++ if (mag) {
++ y[0] /= mag;
++ y[1] /= mag;
++ y[2] /= mag;
++ }
++
++#define M(row,col) m[col*4+row]
++ M(0,0) = x[0]; M(0,1) = x[1]; M(0,2) = x[2]; M(0,3) = 0.0;
++ M(1,0) = y[0]; M(1,1) = y[1]; M(1,2) = y[2]; M(1,3) = 0.0;
++ M(2,0) = z[0]; M(2,1) = z[1]; M(2,2) = z[2]; M(2,3) = 0.0;
++ // the following is part of the original gluLookAt(), but we are
++ // commenting it out because we know we are going to be doing a
++ // translation below which will set these values anyways
++ // M(3,0) = 0.0; M(3,1) = 0.0; M(3,2) = 0.0; M(3,3) = 1.0;
++#undef M
++
++ // Translate Eye to Origin
++ // replaces: glTranslated( -eyex, -eyey, -eyez );
++
++ // this has been slightly modified from the original glTranslate()
++ // code because we know that coming into this m[12] = m[13] =
++ // m[14] = 0.0, and m[15] = 1.0;
++ m[12] = m[0] * -eyex + m[4] * -eyey + m[8] * -eyez /* + m[12] */;
++ m[13] = m[1] * -eyex + m[5] * -eyey + m[9] * -eyez /* + m[13] */;
++ m[14] = m[2] * -eyex + m[6] * -eyey + m[10] * -eyez /* + m[14] */;
++ m[15] = 1.0 /* m[3] * -eyex + m[7] * -eyey + m[11] * -eyez + m[15] */;
++
++ // xglMultMatrixd( m );
++ xglLoadMatrixd( m );
++}
++
++
++// Update the view volume, position, and orientation
++void FGView::UpdateViewParams( void ) {
++ FGInterface *f = current_aircraft.fdm_state;
++
++ UpdateViewMath(f);
++ UpdateWorldToEye(f);
++
++ if ((current_options.get_panel_status() != panel_hist) && (current_options.get_panel_status()))
++ {
++ FGPanel::OurPanel->ReInit( 0, 0, 1024, 768);
++ }
++
++ if ( ! current_options.get_panel_status() ) {
++ xglViewport(0, 0 , (GLint)(winWidth), (GLint)(winHeight) );
++ } else {
++ xglViewport(0, (GLint)((winHeight)*0.5768), (GLint)(winWidth),
++ (GLint)((winHeight)*0.4232) );
++ }
++
++ // Tell GL we are about to modify the projection parameters
++ xglMatrixMode(GL_PROJECTION);
++ xglLoadIdentity();
++ if ( f->get_Altitude() * FEET_TO_METER - scenery.cur_elev > 10.0 ) {
++ gluPerspective(current_options.get_fov(), win_ratio, 10.0, 100000.0);
++ } else {
++ gluPerspective(current_options.get_fov(), win_ratio, 0.5, 100000.0);
++ // printf("Near ground, minimizing near clip plane\n");
++ }
++ // }
++
++ xglMatrixMode(GL_MODELVIEW);
++ xglLoadIdentity();
++
++ // set up our view volume (default)
++#if !defined(FG_VIEW_INLINE_OPTIMIZATIONS)
++ LookAt(view_pos.x(), view_pos.y(), view_pos.z(),
++ view_pos.x() + view_forward[0],
++ view_pos.y() + view_forward[1],
++ view_pos.z() + view_forward[2],
++ view_up[0], view_up[1], view_up[2]);
++
++ // look almost straight up (testing and eclipse watching)
++ /* LookAt(view_pos.x(), view_pos.y(), view_pos.z(),
++ view_pos.x() + view_up[0] + .001,
++ view_pos.y() + view_up[1] + .001,
++ view_pos.z() + view_up[2] + .001,
++ view_up[0], view_up[1], view_up[2]); */
++
++ // lock view horizontally towards sun (testing)
++ /* LookAt(view_pos.x(), view_pos.y(), view_pos.z(),
++ view_pos.x() + surface_to_sun[0],
++ view_pos.y() + surface_to_sun[1],
++ view_pos.z() + surface_to_sun[2],
++ view_up[0], view_up[1], view_up[2]); */
++
++ // lock view horizontally towards south (testing)
++ /* LookAt(view_pos.x(), view_pos.y(), view_pos.z(),
++ view_pos.x() + surface_south[0],
++ view_pos.y() + surface_south[1],
++ view_pos.z() + surface_south[2],
++ view_up[0], view_up[1], view_up[2]); */
++
++#else // defined(FG_VIEW_INLINE_OPTIMIZATIONS)
++ //void FGView::LookAt( GLdouble eyex, GLdouble eyey, GLdouble eyez,
++ // GLdouble centerx, GLdouble centery, GLdouble centerz,
++ // GLdouble upx, GLdouble upy, GLdouble upz )
++ {
++ GLdouble *m;
++ GLdouble x[3], y[3], z[3];
++ // GLdouble mag;
++
++ m = current_view.MODEL_VIEW;
++
++ /* Make rotation matrix */
++
++ /* Z vector */
++ z[0] = -view_forward[0]; //eyex - centerx;
++ z[1] = -view_forward[1]; //eyey - centery;
++ z[2] = -view_forward[2]; //eyez - centerz;
++
++ // In our case this is a unit vector NHV
++
++ // mag = sqrt( z[0]*z[0] + z[1]*z[1] + z[2]*z[2] );
++ // if (mag) { /* mpichler, 19950515 */
++ // mag = 1.0/mag;
++ // printf("mag(%f) ", mag);
++ // z[0] *= mag;
++ // z[1] *= mag;
++ // z[2] *= mag;
++ // }
++
++ /* Y vector */
++ y[0] = view_up[0]; //upx;
++ y[1] = view_up[1]; //upy;
++ y[2] = view_up[2]; //upz;
++
++ /* X vector = Y cross Z */
++ x[0] = y[1]*z[2] - y[2]*z[1];
++ x[1] = -y[0]*z[2] + y[2]*z[0];
++ x[2] = y[0]*z[1] - y[1]*z[0];
++
++ // printf(" %f %f %f ", y[0], y[1], y[2]);
++
++ /* Recompute Y = Z cross X */
++ // y[0] = z[1]*x[2] - z[2]*x[1];
++ // y[1] = -z[0]*x[2] + z[2]*x[0];
++ // y[2] = z[0]*x[1] - z[1]*x[0];
++
++ // printf(" %f %f %f\n", y[0], y[1], y[2]);
++
++ // In our case these are unit vectors NHV
++
++ /* mpichler, 19950515 */
++ /* cross product gives area of parallelogram, which is < 1.0 for
++ * non-perpendicular unit-length vectors; so normalize x, y here
++ */
++
++ // mag = sqrt( x[0]*x[0] + x[1]*x[1] + x[2]*x[2] );
++ // if (mag) {
++ // mag = 1.0/mag;
++ // printf("mag2(%f) ", mag);
++ // x[0] *= mag;
++ // x[1] *= mag;
++ // x[2] *= mag;
++ // }
++
++ // mag = sqrt( y[0]*y[0] + y[1]*y[1] + y[2]*y[2] );
++ // if (mag) {
++ // mag = 1.0/mag;
++ // printf("mag3(%f)\n", mag);
++ // y[0] *= mag;
++ // y[1] *= mag;
++ // y[2] *= mag;
++ // }
++
++#define M(row,col) m[col*4+row]
++ M(0,0) = x[0]; M(0,1) = x[1]; M(0,2) = x[2]; M(0,3) = 0.0;
++ M(1,0) = y[0]; M(1,1) = y[1]; M(1,2) = y[2]; M(1,3) = 0.0;
++ M(2,0) = z[0]; M(2,1) = z[1]; M(2,2) = z[2]; M(2,3) = 0.0;
++ // the following is part of the original gluLookAt(), but we are
++ // commenting it out because we know we are going to be doing a
++ // translation below which will set these values anyways
++ // M(3,0) = 0.0; M(3,1) = 0.0; M(3,2) = 0.0; M(3,3) = 1.0;
++#undef M
++
++ // Translate Eye to Origin
++ // replaces: glTranslated( -eyex, -eyey, -eyez );
++
++ // this has been slightly modified from the original glTranslate()
++ // code because we know that coming into this m[12] = m[13] =
++ // m[14] = 0.0, and m[15] = 1.0;
++ m[12] = m[0] * -view_pos.x() + m[4] * -view_pos.y() + m[8] * -view_pos.z() /* + m[12] */;
++ m[13] = m[1] * -view_pos.x() + m[5] * -view_pos.y() + m[9] * -view_pos.z() /* + m[13] */;
++ m[14] = m[2] * -view_pos.x() + m[6] * -view_pos.y() + m[10] * -view_pos.z() /* + m[14] */;
++ m[15] = 1.0 /* m[3] * -view_pos.x() + m[7] * -view_pos.y() + m[11] * -view_pos.z() + m[15] */;
++
++ // xglMultMatrixd( m );
++ xglLoadMatrixd( m );
++ }
++#endif // FG_VIEW_INLINE_OPTIMIZATIONS
++
++
++ panel_hist = current_options.get_panel_status();
++}
++
++
++void getRotMatrix(double* out, MAT3vec vec, double radians)
++{
++ /* This function contributed by Erich Boleyn (erich@uruk.org) */
++ /* This function used from the Mesa OpenGL code (matrix.c) */
++ double s, c; // mag,
++ double vx, vy, vz, xy, yz, zx, xs, ys, zs, one_c; //, xx, yy, zz
++
++ MAT3identity(out);
++ s = sin(radians);
++ c = cos(radians);
++
++ // mag = getMagnitude();
++
++ vx = vec[0];
++ vy = vec[1];
++ vz = vec[2];
++
++#define M(row,col) out[row*4 + col]
++
++ /*
++ * Arbitrary axis rotation matrix.
++ *
++ * This is composed of 5 matrices, Rz, Ry, T, Ry', Rz', multiplied
++ * like so: Rz * Ry * T * Ry' * Rz'. T is the final rotation
++ * (which is about the X-axis), and the two composite transforms
++ * Ry' * Rz' and Rz * Ry are (respectively) the rotations necessary
++ * from the arbitrary axis to the X-axis then back. They are
++ * all elementary rotations.
++ *
++ * Rz' is a rotation about the Z-axis, to bring the axis vector
++ * into the x-z plane. Then Ry' is applied, rotating about the
++ * Y-axis to bring the axis vector parallel with the X-axis. The
++ * rotation about the X-axis is then performed. Ry and Rz are
++ * simply the respective inverse transforms to bring the arbitrary
++ * axis back to it's original orientation. The first transforms
++ * Rz' and Ry' are considered inverses, since the data from the
++ * arbitrary axis gives you info on how to get to it, not how
++ * to get away from it, and an inverse must be applied.
++ *
++ * The basic calculation used is to recognize that the arbitrary
++ * axis vector (x, y, z), since it is of unit length, actually
++ * represents the sines and cosines of the angles to rotate the
++ * X-axis to the same orientation, with theta being the angle about
++ * Z and phi the angle about Y (in the order described above)
++ * as follows:
++ *
++ * cos ( theta ) = x / sqrt ( 1 - z^2 )
++ * sin ( theta ) = y / sqrt ( 1 - z^2 )
++ *
++ * cos ( phi ) = sqrt ( 1 - z^2 )
++ * sin ( phi ) = z
++ *
++ * Note that cos ( phi ) can further be inserted to the above
++ * formulas:
++ *
++ * cos ( theta ) = x / cos ( phi )
++ * sin ( theta ) = y / cos ( phi )
++ *
++ * ...etc. Because of those relations and the standard trigonometric
++ * relations, it is pssible to reduce the transforms down to what
++ * is used below. It may be that any primary axis chosen will give the
++ * same results (modulo a sign convention) using thie method.
++ *
++ * Particularly nice is to notice that all divisions that might
++ * have caused trouble when parallel to certain planes or
++ * axis go away with care paid to reducing the expressions.
++ * After checking, it does perform correctly under all cases, since
++ * in all the cases of division where the denominator would have
++ * been zero, the numerator would have been zero as well, giving
++ * the expected result.
++ */
++
++ one_c = 1.0F - c;
++
++ // xx = vx * vx;
++ // yy = vy * vy;
++ // zz = vz * vz;
++
++ // xy = vx * vy;
++ // yz = vy * vz;
++ // zx = vz * vx;
++
++
++ M(0,0) = (one_c * vx * vx) + c;
++ xs = vx * s;
++ yz = vy * vz * one_c;
++ M(1,2) = yz + xs;
++ M(2,1) = yz - xs;
++
++ M(1,1) = (one_c * vy * vy) + c;
++ ys = vy * s;
++ zx = vz * vx * one_c;
++ M(0,2) = zx - ys;
++ M(2,0) = zx + ys;
++
++ M(2,2) = (one_c * vz *vz) + c;
++ zs = vz * s;
++ xy = vx * vy * one_c;
++ M(0,1) = xy + zs;
++ M(1,0) = xy - zs;
++
++ // M(0,0) = (one_c * xx) + c;
++ // M(1,0) = (one_c * xy) - zs;
++ // M(2,0) = (one_c * zx) + ys;
++
++ // M(0,1) = (one_c * xy) + zs;
++ // M(1,1) = (one_c * yy) + c;
++ // M(2,1) = (one_c * yz) - xs;
++
++ // M(0,2) = (one_c * zx) - ys;
++ // M(1,2) = (one_c * yz) + xs;
++ // M(2,2) = (one_c * zz) + c;
++
++#undef M
++}
++
++
++// Update the view parameters
++void FGView::UpdateViewMath( FGInterface *f ) {
++ Point3D p;
++ MAT3vec vec, forward, v0, minus_z;
++ MAT3mat R, TMP, UP, LOCAL, VIEW;
++ double ntmp;
++
++ if ( update_fov ) {
++ // printf("Updating fov\n");
++ UpdateFOV( current_options );
++ update_fov = false;
++ }
++
++ scenery.center = scenery.next_center;
++
++#if !defined(FG_VIEW_INLINE_OPTIMIZATIONS)
++ // printf("scenery center = %.2f %.2f %.2f\n", scenery.center.x,
++ // scenery.center.y, scenery.center.z);
++
++ // calculate the cartesion coords of the current lat/lon/0 elev
++ p = Point3D( f->get_Longitude(),
++ f->get_Lat_geocentric(),
++ f->get_Sea_level_radius() * FEET_TO_METER );
++
++ cur_zero_elev = fgPolarToCart3d(p) - scenery.center;
++
++ // calculate view position in current FG view coordinate system
++ // p.lon & p.lat are already defined earlier, p.radius was set to
++ // the sea level radius, so now we add in our altitude.
++ if ( f->get_Altitude() * FEET_TO_METER >
++ (scenery.cur_elev + 0.5 * METER_TO_FEET) ) {
++ p.setz( p.radius() + f->get_Altitude() * FEET_TO_METER );
++ } else {
++ p.setz( p.radius() + scenery.cur_elev + 0.5 * METER_TO_FEET );
++ }
++
++ abs_view_pos = fgPolarToCart3d(p);
++
++#else // FG_VIEW_INLINE_OPTIMIZATIONS
++
++ double tmp_radius = f->get_Sea_level_radius() * FEET_TO_METER;
++ double tmp = f->get_cos_lat_geocentric() * tmp_radius;
++
++ cur_zero_elev.setx(f->get_cos_longitude()*tmp - scenery.center.x());
++ cur_zero_elev.sety(f->get_sin_longitude()*tmp - scenery.center.y());
++ cur_zero_elev.setz(f->get_sin_lat_geocentric()*tmp_radius - scenery.center.z());
++
++ // calculate view position in current FG view coordinate system
++ // p.lon & p.lat are already defined earlier, p.radius was set to
++ // the sea level radius, so now we add in our altitude.
++ if ( f->get_Altitude() * FEET_TO_METER >
++ (scenery.cur_elev + 0.5 * METER_TO_FEET) ) {
++ tmp_radius += f->get_Altitude() * FEET_TO_METER;
++ } else {
++ tmp_radius += scenery.cur_elev + 0.5 * METER_TO_FEET ;
++ }
++ tmp = f->get_cos_lat_geocentric() * tmp_radius;
++ abs_view_pos.setx(f->get_cos_longitude()*tmp);
++ abs_view_pos.sety(f->get_sin_longitude()*tmp);
++ abs_view_pos.setz(f->get_sin_lat_geocentric()*tmp_radius);
++
++#endif // FG_VIEW_INLINE_OPTIMIZATIONS
++
++ view_pos = abs_view_pos - scenery.center;
++
++ FG_LOG( FG_VIEW, FG_DEBUG, "Polar view pos = " << p );
++ FG_LOG( FG_VIEW, FG_DEBUG, "Absolute view pos = " << abs_view_pos );
++ FG_LOG( FG_VIEW, FG_DEBUG, "Relative view pos = " << view_pos );
++
++ // Derive the LOCAL aircraft rotation matrix (roll, pitch, yaw)
++ // from FG_T_local_to_body[3][3]
++
++ if ( use_larcsim_local_to_body ) {
++
++ // Question: Why is the LaRCsim matrix arranged so differently
++ // than the one we need???
++
++ // Answer (I think): The LaRCsim matrix is generated in a
++ // different reference frame than we've set up for our world
++
++ LOCAL[0][0] = f->get_T_local_to_body_33();
++ LOCAL[0][1] = -f->get_T_local_to_body_32();
++ LOCAL[0][2] = -f->get_T_local_to_body_31();
++ LOCAL[0][3] = 0.0;
++ LOCAL[1][0] = -f->get_T_local_to_body_23();
++ LOCAL[1][1] = f->get_T_local_to_body_22();
++ LOCAL[1][2] = f->get_T_local_to_body_21();
++ LOCAL[1][3] = 0.0;
++ LOCAL[2][0] = -f->get_T_local_to_body_13();
++ LOCAL[2][1] = f->get_T_local_to_body_12();
++ LOCAL[2][2] = f->get_T_local_to_body_11();
++ LOCAL[2][3] = 0.0;
++ LOCAL[3][0] = LOCAL[3][1] = LOCAL[3][2] = LOCAL[3][3] = 0.0;
++ LOCAL[3][3] = 1.0;
++
++ // printf("LaRCsim LOCAL matrix\n");
++ // MAT3print(LOCAL, stdout);
++
++ } else {
++
++ // code to calculate LOCAL matrix calculated from Phi, Theta, and
++ // Psi (roll, pitch, yaw) in case we aren't running LaRCsim as our
++ // flight model
++
++ MAT3_SET_VEC(vec, 0.0, 0.0, 1.0);
++ MAT3rotate(R, vec, f->get_Phi());
++ /* printf("Roll matrix\n"); */
++ /* MAT3print(R, stdout); */
++
++ MAT3_SET_VEC(vec, 0.0, 1.0, 0.0);
++ /* MAT3mult_vec(vec, vec, R); */
++ MAT3rotate(TMP, vec, f->get_Theta());
++ /* printf("Pitch matrix\n"); */
++ /* MAT3print(TMP, stdout); */
++ MAT3mult(R, R, TMP);
++
++ MAT3_SET_VEC(vec, 1.0, 0.0, 0.0);
++ /* MAT3mult_vec(vec, vec, R); */
++ /* MAT3rotate(TMP, vec, FG_Psi - FG_PI_2); */
++ MAT3rotate(TMP, vec, -f->get_Psi());
++ /* printf("Yaw matrix\n");
++ MAT3print(TMP, stdout); */
++ MAT3mult(LOCAL, R, TMP);
++ // printf("FG derived LOCAL matrix\n");
++ // MAT3print(LOCAL, stdout);
++
++ } // if ( use_larcsim_local_to_body )
++
++#if !defined(FG_VIEW_INLINE_OPTIMIZATIONS)
++
++ // Derive the local UP transformation matrix based on *geodetic*
++ // coordinates
++ MAT3_SET_VEC(vec, 0.0, 0.0, 1.0);
++ MAT3rotate(R, vec, f->get_Longitude()); // R = rotate about Z axis
++ // printf("Longitude matrix\n");
++ // MAT3print(R, stdout);
++
++ MAT3_SET_VEC(vec, 0.0, 1.0, 0.0);
++ MAT3mult_vec(vec, vec, R);
++ MAT3rotate(TMP, vec, -f->get_Latitude()); // TMP = rotate about X axis
++ // printf("Latitude matrix\n");
++ // MAT3print(TMP, stdout);
++
++ MAT3mult(UP, R, TMP);
++ // printf("Local up matrix\n");
++ // MAT3print(UP, stdout);
++
++ MAT3_SET_VEC(local_up, 1.0, 0.0, 0.0);
++ MAT3mult_vec(local_up, local_up, UP);
++
++ // printf( "Local Up = (%.4f, %.4f, %.4f)\n",
++ // local_up[0], local_up[1], local_up[2]);
++
++ // Alternative method to Derive local up vector based on
++ // *geodetic* coordinates
++ // alt_up = fgPolarToCart(FG_Longitude, FG_Latitude, 1.0);
++ // printf( " Alt Up = (%.4f, %.4f, %.4f)\n",
++ // alt_up.x, alt_up.y, alt_up.z);
++
++ // Calculate the VIEW matrix
++ MAT3mult(VIEW, LOCAL, UP);
++ // printf("VIEW matrix\n");
++ // MAT3print(VIEW, stdout);
++
++ // generate the current up, forward, and fwrd-view vectors
++ MAT3_SET_VEC(vec, 1.0, 0.0, 0.0);
++ MAT3mult_vec(view_up, vec, VIEW);
++
++ MAT3_SET_VEC(vec, 0.0, 0.0, 1.0);
++ MAT3mult_vec(forward, vec, VIEW);
++ // printf( "Forward vector is (%.2f,%.2f,%.2f)\n", forward[0], forward[1],
++ // forward[2]);
++
++ MAT3rotate(TMP, view_up, view_offset);
++ MAT3mult_vec(view_forward, forward, TMP);
++
++ // make a vector to the current view position
++ MAT3_SET_VEC(v0, view_pos.x(), view_pos.y(), view_pos.z());
++
++ // Given a vector pointing straight down (-Z), map into onto the
++ // local plane representing "horizontal". This should give us the
++ // local direction for moving "south".
++ MAT3_SET_VEC(minus_z, 0.0, 0.0, -1.0);
++ map_vec_onto_cur_surface_plane(local_up, v0, minus_z, surface_south);
++ MAT3_NORMALIZE_VEC(surface_south, ntmp);
++ // printf( "Surface direction directly south %.2f %.2f %.2f\n",
++ // surface_south[0], surface_south[1], surface_south[2]);
++
++ // now calculate the surface east vector
++ MAT3rotate(TMP, view_up, FG_PI_2);
++ MAT3mult_vec(surface_east, surface_south, TMP);
++ // printf( "Surface direction directly east %.2f %.2f %.2f\n",
++ // surface_east[0], surface_east[1], surface_east[2]);
++ // printf( "Should be close to zero = %.2f\n",
++ // MAT3_DOT_PRODUCT(surface_south, surface_east));
++
++#else // FG_VIEW_INLINE_OPTIMIZATIONS
++
++ // // Build spherical to cartesian transform matrix directly
++ double cos_lat = f->get_cos_latitude(); // cos(-f->get_Latitude());
++ double sin_lat = -f->get_sin_latitude(); // sin(-f->get_Latitude());
++ double cos_lon = f->get_cos_longitude(); //cos(f->get_Longitude());
++ double sin_lon = f->get_sin_longitude(); //sin(f->get_Longitude());
++
++ double *mat = (double *)UP;
++
++ mat[0] = cos_lat*cos_lon;
++ mat[1] = cos_lat*sin_lon;
++ mat[2] = -sin_lat;
++ mat[3] = 0.0;
++ mat[4] = -sin_lon;
++ mat[5] = cos_lon;
++ mat[6] = 0.0;
++ mat[7] = 0.0;
++ mat[8] = sin_lat*cos_lon;
++ mat[9] = sin_lat*sin_lon;
++ mat[10] = cos_lat;
++ mat[11] = mat[12] = mat[13] = mat[14] = 0.0;
++ mat[15] = 1.0;
++
++ MAT3mult(VIEW, LOCAL, UP);
++
++ // THESE COULD JUST BE POINTERS !!!
++ MAT3_SET_VEC(local_up, mat[0], mat[1], mat[2]);
++ MAT3_SET_VEC(view_up, VIEW[0][0], VIEW[0][1], VIEW[0][2]);
++ MAT3_SET_VEC(forward, VIEW[2][0], VIEW[2][1], VIEW[2][2]);
++
++ getRotMatrix((double *)TMP, view_up, view_offset);
++ MAT3mult_vec(view_forward, forward, TMP);
++
++ // make a vector to the current view position
++ MAT3_SET_VEC(v0, view_pos.x(), view_pos.y(), view_pos.z());
++
++ // Given a vector pointing straight down (-Z), map into onto the
++ // local plane representing "horizontal". This should give us the
++ // local direction for moving "south".
++ MAT3_SET_VEC(minus_z, 0.0, 0.0, -1.0);
++ map_vec_onto_cur_surface_plane(local_up, v0, minus_z, surface_south);
++
++ MAT3_NORMALIZE_VEC(surface_south, ntmp);
++ // printf( "Surface direction directly south %.6f %.6f %.6f\n",
++ // surface_south[0], surface_south[1], surface_south[2]);
++
++ // now calculate the surface east vector
++ getRotMatrix((double *)TMP, view_up, FG_PI_2);
++ MAT3mult_vec(surface_east, surface_south, TMP);
++ // printf( "Surface direction directly east %.6f %.6f %.6f\n",
++ // surface_east[0], surface_east[1], surface_east[2]);
++ // printf( "Should be close to zero = %.6f\n",
++ // MAT3_DOT_PRODUCT(surface_south, surface_east));
++#endif // !defined(FG_VIEW_INLINE_OPTIMIZATIONS)
++}
++
++
++// Update the "World to Eye" transformation matrix
++// This is most useful for view frustum culling
++void FGView::UpdateWorldToEye( FGInterface *f ) {
++ MAT3mat R_Phi, R_Theta, R_Psi, R_Lat, R_Lon, T_view;
++ MAT3mat TMP;
++ MAT3hvec vec;
++
++ if ( use_larcsim_local_to_body ) {
++
++ // Question: hey this is even different then LOCAL[][] above??
++ // Answer: yet another coordinate system, this time the
++ // coordinate system in which we do our view frustum culling.
++
++ AIRCRAFT[0][0] = -f->get_T_local_to_body_22();
++ AIRCRAFT[0][1] = -f->get_T_local_to_body_23();
++ AIRCRAFT[0][2] = f->get_T_local_to_body_21();
++ AIRCRAFT[0][3] = 0.0;
++ AIRCRAFT[1][0] = f->get_T_local_to_body_32();
++ AIRCRAFT[1][1] = f->get_T_local_to_body_33();
++ AIRCRAFT[1][2] = -f->get_T_local_to_body_31();
++ AIRCRAFT[1][3] = 0.0;
++ AIRCRAFT[2][0] = f->get_T_local_to_body_12();
++ AIRCRAFT[2][1] = f->get_T_local_to_body_13();
++ AIRCRAFT[2][2] = -f->get_T_local_to_body_11();
++ AIRCRAFT[2][3] = 0.0;
++ AIRCRAFT[3][0] = AIRCRAFT[3][1] = AIRCRAFT[3][2] = AIRCRAFT[3][3] = 0.0;
++ AIRCRAFT[3][3] = 1.0;
++
++ } else {
++
++ // Roll Matrix
++ MAT3_SET_HVEC(vec, 0.0, 0.0, -1.0, 1.0);
++ MAT3rotate(R_Phi, vec, f->get_Phi());
++ // printf("Roll matrix (Phi)\n");
++ // MAT3print(R_Phi, stdout);
++
++ // Pitch Matrix
++ MAT3_SET_HVEC(vec, 1.0, 0.0, 0.0, 1.0);
++ MAT3rotate(R_Theta, vec, f->get_Theta());
++ // printf("\nPitch matrix (Theta)\n");
++ // MAT3print(R_Theta, stdout);
++
++ // Yaw Matrix
++ MAT3_SET_HVEC(vec, 0.0, -1.0, 0.0, 1.0);
++ MAT3rotate(R_Psi, vec, f->get_Psi() + FG_PI /* - view_offset */ );
++ // MAT3rotate(R_Psi, vec, f->get_Psi() + FG_PI - view_offset );
++ // printf("\nYaw matrix (Psi)\n");
++ // MAT3print(R_Psi, stdout);
++
++ // aircraft roll/pitch/yaw
++ MAT3mult(TMP, R_Phi, R_Theta);
++ MAT3mult(AIRCRAFT, TMP, R_Psi);
++
++ } // if ( use_larcsim_local_to_body )
++
++#if !defined(FG_VIEW_INLINE_OPTIMIZATIONS)
++
++ // printf("AIRCRAFT matrix\n");
++ // MAT3print(AIRCRAFT, stdout);
++
++ // View rotation matrix relative to current aircraft orientation
++ MAT3_SET_HVEC(vec, 0.0, -1.0, 0.0, 1.0);
++ MAT3mult_vec(vec, vec, AIRCRAFT);
++ // printf("aircraft up vector = %.2f %.2f %.2f\n",
++ // vec[0], vec[1], vec[2]);
++ MAT3rotate(TMP, vec, -view_offset );
++ MAT3mult(VIEW_OFFSET, AIRCRAFT, TMP);
++ // printf("VIEW_OFFSET matrix\n");
++ // MAT3print(VIEW_OFFSET, stdout);
++
++ // View position in scenery centered coordinates
++ MAT3_SET_HVEC(vec, view_pos.x(), view_pos.y(), view_pos.z(), 1.0);
++ MAT3translate(T_view, vec);
++ // printf("\nTranslation matrix\n");
++ // MAT3print(T_view, stdout);
++
++ // Latitude
++ MAT3_SET_HVEC(vec, 1.0, 0.0, 0.0, 1.0);
++ // R_Lat = rotate about X axis
++ MAT3rotate(R_Lat, vec, f->get_Latitude());
++ // printf("\nLatitude matrix\n");
++ // MAT3print(R_Lat, stdout);
++
++ // Longitude
++ MAT3_SET_HVEC(vec, 0.0, 0.0, 1.0, 1.0);
++ // R_Lon = rotate about Z axis
++ MAT3rotate(R_Lon, vec, f->get_Longitude() - FG_PI_2 );
++ // printf("\nLongitude matrix\n");
++ // MAT3print(R_Lon, stdout);
++
++ // lon/lat
++ MAT3mult(WORLD, R_Lat, R_Lon);
++ // printf("\nworld\n");
++ // MAT3print(WORLD, stdout);
++
++ MAT3mult(EYE_TO_WORLD, VIEW_OFFSET, WORLD);
++ MAT3mult(EYE_TO_WORLD, EYE_TO_WORLD, T_view);
++ // printf("\nEye to world\n");
++ // MAT3print(EYE_TO_WORLD, stdout);
++
++ MAT3invert(WORLD_TO_EYE, EYE_TO_WORLD);
++ // printf("\nWorld to eye\n");
++ // MAT3print(WORLD_TO_EYE, stdout);
++
++ // printf( "\nview_pos = %.2f %.2f %.2f\n",
++ // view_pos.x, view_pos.y, view_pos.z );
++
++ // MAT3_SET_HVEC(eye, 0.0, 0.0, 0.0, 1.0);
++ // MAT3mult_vec(vec, eye, EYE_TO_WORLD);
++ // printf("\neye -> world = %.2f %.2f %.2f\n", vec[0], vec[1], vec[2]);
++
++ // MAT3_SET_HVEC(vec1, view_pos.x, view_pos.y, view_pos.z, 1.0);
++ // MAT3mult_vec(vec, vec1, WORLD_TO_EYE);
++ // printf( "\nabs_view_pos -> eye = %.2f %.2f %.2f\n",
++ // vec[0], vec[1], vec[2]);
++#else // FG_VIEW_INLINE_OPTIMIZATIONS
++
++ MAT3_SET_HVEC(vec, -AIRCRAFT[1][0], -AIRCRAFT[1][1], -AIRCRAFT[1][2], -AIRCRAFT[1][3]);
++ getRotMatrix((double *)TMP, vec, -view_offset );
++ MAT3mult(VIEW_OFFSET, AIRCRAFT, TMP);
++ // MAT3print_formatted(VIEW_OFFSET, stdout, "VIEW_OFFSET matrix:\n",
++ // NULL, "%#8.6f ", "\n");
++
++ // Build spherical to cartesian transform matrix directly
++ double *mat = (double *)WORLD; //T_view; //WORLD;
++ double cos_lat = f->get_cos_latitude(); //cos(f->get_Latitude());
++ double sin_lat = f->get_sin_latitude(); //sin(f->get_Latitude());
++ // using trig identities this:
++ // mat[0] = cos(f->get_Longitude() - FG_PI_2);//cos_lon;
++ // mat[1] = sin(f->get_Longitude() - FG_PI_2);//sin_lon;
++ // becomes this: :-)
++ mat[0] = f->get_sin_longitude(); //cos_lon;
++ mat[1] = -f->get_cos_longitude(); //sin_lon;
++ mat[4] = -cos_lat*mat[1]; //mat[1]=sin_lon;
++ mat[5] = cos_lat*mat[0]; //mat[0]=cos_lon;
++ mat[6] = sin_lat;
++ mat[8] = sin_lat*mat[1]; //mat[1]=sin_lon;
++ mat[9] = -sin_lat*mat[0]; //mat[0]=cos_lon;
++ mat[10] = cos_lat;
++
++ // BUILD EYE_TO_WORLD = AIRCRAFT * WORLD
++ // and WORLD_TO_EYE = Inverse( EYE_TO_WORLD) concurrently
++ // by Transposing the 3x3 rotation sub-matrix
++ WORLD_TO_EYE[0][0] = EYE_TO_WORLD[0][0] =
++ VIEW_OFFSET[0][0]*mat[0] + VIEW_OFFSET[0][1]*mat[4] + VIEW_OFFSET[0][2]*mat[8];
++
++ WORLD_TO_EYE[1][0] = EYE_TO_WORLD[0][1] =
++ VIEW_OFFSET[0][0]*mat[1] + VIEW_OFFSET[0][1]*mat[5] + VIEW_OFFSET[0][2]*mat[9];
++
++ WORLD_TO_EYE[2][0] = EYE_TO_WORLD[0][2] =
++ VIEW_OFFSET[0][1]*mat[6] + VIEW_OFFSET[0][2]*mat[10];
++
++ WORLD_TO_EYE[0][1] = EYE_TO_WORLD[1][0] =
++ VIEW_OFFSET[1][0]*mat[0] + VIEW_OFFSET[1][1]*mat[4] + VIEW_OFFSET[1][2]*mat[8];
++
++ WORLD_TO_EYE[1][1] = EYE_TO_WORLD[1][1] =
++ VIEW_OFFSET[1][0]*mat[1] + VIEW_OFFSET[1][1]*mat[5] + VIEW_OFFSET[1][2]*mat[9];
++
++ WORLD_TO_EYE[2][1] = EYE_TO_WORLD[1][2] =
++ VIEW_OFFSET[1][1]*mat[6] + VIEW_OFFSET[1][2]*mat[10];
++
++ WORLD_TO_EYE[0][2] = EYE_TO_WORLD[2][0] =
++ VIEW_OFFSET[2][0]*mat[0] + VIEW_OFFSET[2][1]*mat[4] + VIEW_OFFSET[2][2]*mat[8];
++
++ WORLD_TO_EYE[1][2] = EYE_TO_WORLD[2][1] =
++ VIEW_OFFSET[2][0]*mat[1] + VIEW_OFFSET[2][1]*mat[5] + VIEW_OFFSET[2][2]*mat[9];
++
++ WORLD_TO_EYE[2][2] = EYE_TO_WORLD[2][2] =
++ VIEW_OFFSET[2][1]*mat[6] + VIEW_OFFSET[2][2]*mat[10];
++
++ // TRANSLATE TO VIEW POSITION
++ EYE_TO_WORLD[3][0] = view_pos.x();
++ EYE_TO_WORLD[3][1] = view_pos.y();
++ EYE_TO_WORLD[3][2] = view_pos.z();
++
++ // FILL 0 ENTRIES
++ WORLD_TO_EYE[0][3] = WORLD_TO_EYE[1][3] = WORLD_TO_EYE[2][3] =
++ EYE_TO_WORLD[0][3] = EYE_TO_WORLD[1][3] = EYE_TO_WORLD[2][3] = 0.0;
++
++ // FILL UNITY ENTRIES
++ WORLD_TO_EYE[3][3] = EYE_TO_WORLD[3][3] = 1.0;
++
++ /* MAKE THE INVERTED TRANSLATIONS */
++ mat = (double *)EYE_TO_WORLD;
++ WORLD_TO_EYE[3][0] = -mat[12]*mat[0]
++ -mat[13]*mat[1]
++ -mat[14]*mat[2];
++
++ WORLD_TO_EYE[3][1] = -mat[12]*mat[4]
++ -mat[13]*mat[5]
++ -mat[14]*mat[6];
++
++ WORLD_TO_EYE[3][2] = -mat[12]*mat[8]
++ -mat[13]*mat[9]
++ -mat[14]*mat[10];
++
++ // MAT3print_formatted(EYE_TO_WORLD, stdout, "EYE_TO_WORLD matrix:\n",
++ // NULL, "%#8.6f ", "\n");
++
++ // MAT3print_formatted(WORLD_TO_EYE, stdout, "WORLD_TO_EYE matrix:\n",
++ // NULL, "%#8.6f ", "\n");
++
++#endif // defined(FG_VIEW_INLINE_OPTIMIZATIONS)
++}
++
++
++#if 0
++// Reject non viewable spheres from current View Frustrum by Curt
++// Olson curt@me.umn.edu and Norman Vine nhv@yahoo.com with 'gentle
++// guidance' from Steve Baker sbaker@link.com
++int
++FGView::SphereClip( const Point3D& cp, const double radius )
++{
++ double x1, y1;
++
++ MAT3vec eye;
++ double *mat;
++ double x, y, z;
++
++ x = cp->x;
++ y = cp->y;
++ z = cp->z;
++
++ mat = (double *)(WORLD_TO_EYE);
++
++ eye[2] = x*mat[2] + y*mat[6] + z*mat[10] + mat[14];
++
++ // Check near and far clip plane
++ if( ( eye[2] > radius ) ||
++ ( eye[2] + radius + current_weather.visibility < 0) )
++ // ( eye[2] + radius + far_plane < 0) )
++ {
++ return 1;
++ }
++
++ // check right and left clip plane (from eye perspective)
++ x1 = radius * fov_x_clip;
++ eye[0] = (x*mat[0] + y*mat[4] + z*mat[8] + mat[12]) * slope_x;
++ if( (eye[2] > -(eye[0]+x1)) || (eye[2] > (eye[0]-x1)) ) {
++ return(1);
++ }
++
++ // check bottom and top clip plane (from eye perspective)
++ y1 = radius * fov_y_clip;
++ eye[1] = (x*mat[1] + y*mat[5] + z*mat[9] + mat[13]) * slope_y;
++ if( (eye[2] > -(eye[1]+y1)) || (eye[2] > (eye[1]-y1)) ) {
++ return 1;
++ }
++
++ return 0;
++}
++#endif
++
++
++// Destructor
++FGView::~FGView( void ) {
++}
++
++
++// $Log$
++// Revision 1.35 1999/04/03 04:21:04 curt
++// Integration of Steve's plib conglomeration.
++// Optimizations (tm) by Norman Vine.
++//
++// Revision 1.34 1999/03/08 21:56:41 curt
++// Added panel changes sent in by Friedemann.
++// Added a splash screen randomization since we have several nice splash screens.
++//
++// Revision 1.33 1999/02/05 21:29:14 curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.32 1999/01/07 20:25:12 curt
++// Updated struct fgGENERAL to class FGGeneral.
++//
++// Revision 1.31 1998/12/11 20:26:28 curt
++// Fixed view frustum culling accuracy bug so we can look out the sides and
++// back without tri-stripes dropping out.
++//
++// Revision 1.30 1998/12/09 18:50:28 curt
++// Converted "class fgVIEW" to "class FGView" and updated to make data
++// members private and make required accessor functions.
++//
++// Revision 1.29 1998/12/05 15:54:24 curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.28 1998/12/03 01:17:20 curt
++// Converted fgFLIGHT to a class.
++//
++// Revision 1.27 1998/11/16 14:00:06 curt
++// Added pow() macro bug work around.
++// Added support for starting FGFS at various resolutions.
++// Added some initial serial port support.
++// Specify default log levels in main().
++//
++// Revision 1.26 1998/11/09 23:39:25 curt
++// Tweaks for the instrument panel.
++//
++// Revision 1.25 1998/11/06 21:18:15 curt
++// Converted to new logstream debugging facility. This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.24 1998/10/18 01:17:19 curt
++// Point3D tweaks.
++//
++// Revision 1.23 1998/10/17 01:34:26 curt
++// C++ ifying ...
++//
++// Revision 1.22 1998/10/16 00:54:03 curt
++// Converted to Point3D class.
++//
++// Revision 1.21 1998/09/17 18:35:33 curt
++// Added F8 to toggle fog and F9 to toggle texturing.
++//
++// Revision 1.20 1998/09/08 15:04:35 curt
++// Optimizations by Norman Vine.
++//
++// Revision 1.19 1998/08/20 20:32:34 curt
++// Reshuffled some of the code in and around views.[ch]xx
++//
++// Revision 1.18 1998/07/24 21:57:02 curt
++// Set near clip plane to 0.5 meters when close to the ground. Also, let the view get a bit closer to the ground before hitting the hard limit.
++//
++// Revision 1.17 1998/07/24 21:39:12 curt
++// Debugging output tweaks.
++// Cast glGetString to (char *) to avoid compiler errors.
++// Optimizations to fgGluLookAt() by Norman Vine.
++//
++// Revision 1.16 1998/07/13 21:01:41 curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.15 1998/07/12 03:14:43 curt
++// Added ground collision detection.
++// Did some serious horsing around to be able to "hug" the ground properly
++// and still be able to take off.
++// Set the near clip plane to 1.0 meters when less than 10 meters above the
++// ground.
++// Did some serious horsing around getting the initial airplane position to be
++// correct based on rendered terrain elevation.
++// Added a little cheat/hack that will prevent the view position from ever
++// dropping below the terrain, even when the flight model doesn't quite
++// put you as high as you'd like.
++//
++// Revision 1.14 1998/07/08 14:45:08 curt
++// polar3d.h renamed to polar3d.hxx
++// vector.h renamed to vector.hxx
++// updated audio support so it waits to create audio classes (and tie up
++// /dev/dsp) until the mpg123 player is finished.
++//
++// Revision 1.13 1998/07/04 00:52:27 curt
++// Add my own version of gluLookAt() (which is nearly identical to the
++// Mesa/glu version.) But, by calculating the Model View matrix our selves
++// we can save this matrix without having to read it back in from the video
++// card. This hopefully allows us to save a few cpu cycles when rendering
++// out the fragments because we can just use glLoadMatrixd() with the
++// precalculated matrix for each tile rather than doing a push(), translate(),
++// pop() for every fragment.
++//
++// Panel status defaults to off for now until it gets a bit more developed.
++//
++// Extract OpenGL driver info on initialization.
++//
++// Revision 1.12 1998/06/03 00:47:15 curt
++// Updated to compile in audio support if OSS available.
++// Updated for new version of Steve's audio library.
++// STL includes don't use .h
++// Small view optimizations.
++//
++// Revision 1.11 1998/05/27 02:24:05 curt
++// View optimizations by Norman Vine.
++//
++// Revision 1.10 1998/05/17 16:59:03 curt
++// First pass at view frustum culling now operational.
++//
++// Revision 1.9 1998/05/16 13:08:37 curt
++// C++ - ified views.[ch]xx
++// Shuffled some additional view parameters into the fgVIEW class.
++// Changed tile-radius to tile-diameter because it is a much better
++// name.
++// Added a WORLD_TO_EYE transformation to views.cxx. This allows us
++// to transform world space to eye space for view frustum culling.
++//
++// Revision 1.8 1998/05/02 01:51:01 curt
++// Updated polartocart conversion routine.
++//
++// Revision 1.7 1998/04/30 12:34:20 curt
++// Added command line rendering options:
++// enable/disable fog/haze
++// specify smooth/flat shading
++// disable sky blending and just use a solid color
++// enable wireframe drawing mode
++//
++// Revision 1.6 1998/04/28 01:20:23 curt
++// Type-ified fgTIME and fgVIEW.
++// Added a command line option to disable textures.
++//
++// Revision 1.5 1998/04/26 05:10:04 curt
++// "struct fgLIGHT" -> "fgLIGHT" because fgLIGHT is typedef'd.
++//
++// Revision 1.4 1998/04/25 22:04:53 curt
++// Use already calculated LaRCsim values to create the roll/pitch/yaw
++// transformation matrix (we call it LOCAL)
++//
++// Revision 1.3 1998/04/25 20:24:02 curt
++// Cleaned up initialization sequence to eliminate interdependencies
++// between sun position, lighting, and view position. This creates a
++// valid single pass initialization path.
++//
++// Revision 1.2 1998/04/24 00:49:22 curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Trying out some different option parsing code.
++// Some code reorganization.
++//
++// Revision 1.1 1998/04/22 13:25:45 curt
++// C++ - ifing the code.
++// Starting a bit of reorganization of lighting code.
++//
++// Revision 1.16 1998/04/18 04:11:29 curt
++// Moved fg_debug to it's own library, added zlib support.
++//
++// Revision 1.15 1998/02/20 00:16:24 curt
++// Thursday's tweaks.
++//
++// Revision 1.14 1998/02/09 15:07:50 curt
++// Minor tweaks.
++//
++// Revision 1.13 1998/02/07 15:29:45 curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.12 1998/01/29 00:50:28 curt
++// Added a view record field for absolute x, y, z position.
++//
++// Revision 1.11 1998/01/27 00:47:58 curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.10 1998/01/19 19:27:09 curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.9 1998/01/13 00:23:09 curt
++// Initial changes to support loading and management of scenery tiles. Note,
++// there's still a fair amount of work left to be done.
++//
++// Revision 1.8 1997/12/30 22:22:33 curt
++// Further integration of event manager.
++//
++// Revision 1.7 1997/12/30 20:47:45 curt
++// Integrated new event manager with subsystem initializations.
++//
++// Revision 1.6 1997/12/22 04:14:32 curt
++// Aligned sky with sun so dusk/dawn effects can be correct relative to the sun.
++//
++// Revision 1.5 1997/12/18 04:07:02 curt
++// Worked on properly translating and positioning the sky dome.
++//
++// Revision 1.4 1997/12/17 23:13:36 curt
++// Began working on rendering a sky.
++//
++// Revision 1.3 1997/12/15 23:54:50 curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.2 1997/12/10 22:37:48 curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.1 1997/08/27 21:31:17 curt
++// Initial revision.
++//
--- /dev/null
--- /dev/null
++// views.hxx -- data structures and routines for managing and view parameters.
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#ifndef _VIEWS_HXX
++#define _VIEWS_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++
++#include <FDM/flight.hxx>
++#include <Math/mat3.h>
++#include <Math/point3d.hxx>
++#include <Time/fg_time.hxx>
++#include <Time/light.hxx>
++
++#include "options.hxx"
++
++
++// used in views.cxx and tilemgr.cxx
++#define USE_FAST_FOV_CLIP
++
++
++// Define a structure containing view information
++class FGView {
++
++public:
++
++ // the current offset from forward for viewing
++ double view_offset;
++
++ // the goal view offset for viewing (used for smooth view changes)
++ double goal_view_offset;
++
++ // flag forcing update of fov related stuff
++ bool update_fov;
++
++ // fov of view is specified in the y direction, win_ratio is used to
++ // calculate the fov in the X direction = width/height
++ double win_ratio;
++
++ // width & height of window
++ int winWidth, winHeight;
++
++ // sin and cos of (fov / 2) in Y axis
++ double sin_fov_y, cos_fov_y;
++ double sinlon, coslon;
++
++ // slope of view frustum edge in eye space Y axis
++ double slope_y;
++
++ // sin and cos of (fov / 2) in X axis
++ double sin_fov_x, cos_fov_x;
++
++ // slope of view frustum edge in eye space X axis
++ double slope_x;
++
++#if defined( USE_FAST_FOV_CLIP )
++ double fov_x_clip, fov_y_clip;
++#endif // USE_FAST_FOV_CLIP
++
++ // View frustum cull ratio (% of tiles culled ... used for
++ // reporting purposes)
++ double vfc_ratio;
++
++ // Number of triangles rendered;
++ int tris_rendered;
++ int tris_culled;
++
++ // absolute view position
++ Point3D abs_view_pos;
++
++ // view position translated to scenery.center
++ Point3D view_pos;
++
++ // cartesion coordinates of current lon/lat if at sea level
++ // translated to scenery.center*/
++ Point3D cur_zero_elev;
++
++ // vector in cartesian coordinates from current position to the
++ // postion on the earth's surface the sun is directly over
++ MAT3vec to_sun;
++
++ // surface direction to go to head towards sun
++ MAT3vec surface_to_sun;
++
++ // vector in cartesian coordinates from current position to the
++ // postion on the earth's surface the moon is directly over
++ MAT3vec to_moon;
++
++ // surface direction to go to head towards moon
++ MAT3vec surface_to_moon;
++
++ // surface vector heading south
++ MAT3vec surface_south;
++
++ // surface vector heading east (used to unambiguously align sky
++ // with sun)
++ MAT3vec surface_east;
++
++ // local up vector (normal to the plane tangent to the earth's
++ // surface at the spot we are directly above
++ MAT3vec local_up;
++
++ // up vector for the view (usually point straight up through the
++ // top of the aircraft
++ MAT3vec view_up;
++
++ // the vector pointing straight out the nose of the aircraft
++ MAT3vec view_forward;
++
++ // Transformation matrix for eye coordinates to aircraft coordinates
++ MAT3mat AIRCRAFT;
++
++ // Transformation matrix for the view direction offset relative to
++ // the AIRCRAFT matrix
++ MAT3mat VIEW_OFFSET;
++
++ // Transformation matrix for aircraft coordinates to world
++ // coordinates
++ MAT3mat WORLD;
++
++ // Combined transformation from eye coordinates to world coordinates
++ MAT3mat EYE_TO_WORLD;
++
++ // Inverse of EYE_TO_WORLD which is a transformation from world
++ // coordinates to eye coordinates
++ MAT3mat WORLD_TO_EYE;
++
++ // Current model view matrix;
++ GLdouble MODEL_VIEW[16];
++
++public:
++
++ // Constructor
++ FGView( void );
++
++ // Destructor
++ ~FGView( void );
++
++ // Initialize a view class
++ void Init( void );
++
++ // Basically, this is a modified version of the Mesa gluLookAt()
++ // function that's been modified slightly so we can capture the
++ // result (and use it later) otherwise this all gets calculated in
++ // OpenGL land and we don't have access to the results.
++ void LookAt( GLdouble eyex, GLdouble eyey, GLdouble eyez,
++ GLdouble centerx, GLdouble centery, GLdouble centerz,
++ GLdouble upx, GLdouble upy, GLdouble upz );
++
++ // Update the view volume, position, and orientation
++ void UpdateViewParams( void );
++
++ // Flag to request that UpdateFOV() be called next time
++ // UpdateViewMath() is run.
++ inline void force_update_fov_math() { update_fov = true; }
++
++ // Update the view parameters
++ void UpdateViewMath( FGInterface *f );
++
++ // Update the "World to Eye" transformation matrix
++ void UpdateWorldToEye( FGInterface *f );
++
++ // Update the field of view coefficients
++ void UpdateFOV( const fgOPTIONS& o );
++
++ // accessor functions
++ inline double get_view_offset() const { return view_offset; }
++ inline void set_view_offset( double a ) { view_offset = a; }
++ inline void inc_view_offset( double amt ) { view_offset += amt; }
++ inline double get_goal_view_offset() const { return goal_view_offset; }
++ inline void set_goal_view_offset( double a) { goal_view_offset = a; }
++ inline double get_win_ratio() const { return win_ratio; }
++ inline void set_win_ratio( double r ) { win_ratio = r; }
++ inline int get_winWidth() const { return winWidth; }
++ inline void set_winWidth( int w ) { winWidth = w; }
++ inline int get_winHeight() const { return winHeight; }
++ inline void set_winHeight( int h ) { winHeight = h; }
++ inline double get_slope_y() const { return slope_y; }
++ inline double get_slope_x() const { return slope_x; }
++#if defined( USE_FAST_FOV_CLIP )
++ inline double get_fov_x_clip() const { return fov_x_clip; }
++ inline double get_fov_y_clip() const { return fov_y_clip; }
++#endif // USE_FAST_FOV_CLIP
++ inline double get_vfc_ratio() const { return vfc_ratio; }
++ inline void set_vfc_ratio(double r) { vfc_ratio = r; }
++ inline int get_tris_rendered() const { return tris_rendered; }
++ inline void set_tris_rendered( int tris) { tris_rendered = tris; }
++ inline int get_tris_culled() const { return tris_culled; }
++ inline void set_tris_culled( int tris) { tris_culled = tris; }
++ inline Point3D get_abs_view_pos() const { return abs_view_pos; }
++ inline Point3D get_view_pos() const { return view_pos; }
++ inline Point3D get_cur_zero_elev() const { return cur_zero_elev; }
++ inline double *get_to_sun() { return to_sun; }
++ inline void set_to_sun( double x, double y, double z) {
++ to_sun[0] = x;
++ to_sun[1] = y;
++ to_sun[2] = z;
++ }
++ inline double *get_surface_to_sun() { return surface_to_sun; }
++ inline void set_surface_to_sun( double x, double y, double z) {
++ surface_to_sun[0] = x;
++ surface_to_sun[1] = y;
++ surface_to_sun[2] = z;
++ }
++ inline double *get_to_moon() { return to_moon; }
++ inline void set_to_moon( double x, double y, double z) {
++ to_moon[0] = x;
++ to_moon[1] = y;
++ to_moon[2] = z;
++ }
++ inline double *get_surface_to_moon() { return surface_to_moon; }
++ inline void set_surface_to_moon( double x, double y, double z) {
++ surface_to_moon[0] = x;
++ surface_to_moon[1] = y;
++ surface_to_moon[2] = z;
++ }
++ inline double *get_surface_south() { return surface_south; }
++ inline double *get_surface_east() { return surface_east; }
++ inline double *get_local_up() { return local_up; }
++ inline const MAT3mat *get_WORLD_TO_EYE() const { return &WORLD_TO_EYE; }
++ inline GLdouble *get_MODEL_VIEW() { return MODEL_VIEW; }
++};
++
++
++extern FGView current_view;
++
++
++#endif // _VIEWS_HXX
++
++
++// $Log$
++// Revision 1.23 1999/04/03 04:21:06 curt
++// Integration of Steve's plib conglomeration.
++// Optimizations (tm) by Norman Vine.
++//
++// Revision 1.22 1999/03/22 02:08:15 curt
++// Changes contributed by Durk Talsma:
++//
++// Here's a few changes I made to fg-0.58 this weekend. Included are the
++// following features:
++// - Sun and moon have a halo
++// - The moon has a light vector, moon_angle, etc. etc. so that we can have
++// some moonlight during the night.
++// - Lot's of small changes tweakes, including some stuff Norman Vine sent
++// me earlier.
++//
++// Revision 1.21 1999/02/05 21:29:15 curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.20 1999/02/02 20:13:38 curt
++// MSVC++ portability changes by Bernie Bright:
++//
++// Lib/Serial/serial.[ch]xx: Initial Windows support - incomplete.
++// Simulator/Astro/stars.cxx: typo? included <stdio> instead of <cstdio>
++// Simulator/Cockpit/hud.cxx: Added Standard headers
++// Simulator/Cockpit/panel.cxx: Redefinition of default parameter
++// Simulator/Flight/flight.cxx: Replaced cout with FG_LOG. Deleted <stdio.h>
++// Simulator/Main/fg_init.cxx:
++// Simulator/Main/GLUTmain.cxx:
++// Simulator/Main/options.hxx: Shuffled <fg_serial.hxx> dependency
++// Simulator/Objects/material.hxx:
++// Simulator/Time/timestamp.hxx: VC++ friend kludge
++// Simulator/Scenery/tile.[ch]xx: Fixed using std::X declarations
++// Simulator/Main/views.hxx: Added a constant
++//
++// Revision 1.19 1999/02/01 21:33:36 curt
++// Renamed FlightGear/Simulator/Flight to FlightGear/Simulator/FDM since
++// Jon accepted my offer to do this and thought it was a good idea.
++//
++// Revision 1.18 1998/12/11 20:26:30 curt
++// Fixed view frustum culling accuracy bug so we can look out the sides and
++// back without tri-stripes dropping out.
++//
++// Revision 1.17 1998/12/09 18:50:29 curt
++// Converted "class fgVIEW" to "class FGView" and updated to make data
++// members private and make required accessor functions.
++//
++// Revision 1.16 1998/12/05 15:54:25 curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.15 1998/10/16 23:27:56 curt
++// C++-ifying.
++//
++// Revision 1.14 1998/10/16 00:54:04 curt
++// Converted to Point3D class.
++//
++// Revision 1.13 1998/09/08 15:04:36 curt
++// Optimizations by Norman Vine.
++//
++// Revision 1.12 1998/08/24 20:11:15 curt
++// Added i/I to toggle full vs. minimal HUD.
++// Added a --hud-tris vs --hud-culled option.
++// Moved options accessor funtions to options.hxx.
++//
++// Revision 1.11 1998/08/20 20:32:35 curt
++// Reshuffled some of the code in and around views.[ch]xx
++//
++// Revision 1.10 1998/07/08 14:45:09 curt
++// polar3d.h renamed to polar3d.hxx
++// vector.h renamed to vector.hxx
++// updated audio support so it waits to create audio classes (and tie up
++// /dev/dsp) until the mpg123 player is finished.
++//
++// Revision 1.9 1998/07/04 00:52:27 curt
++// Add my own version of gluLookAt() (which is nearly identical to the
++// Mesa/glu version.) But, by calculating the Model View matrix our selves
++// we can save this matrix without having to read it back in from the video
++// card. This hopefully allows us to save a few cpu cycles when rendering
++// out the fragments because we can just use glLoadMatrixd() with the
++// precalculated matrix for each tile rather than doing a push(), translate(),
++// pop() for every fragment.
++//
++// Panel status defaults to off for now until it gets a bit more developed.
++//
++// Extract OpenGL driver info on initialization.
++//
++// Revision 1.8 1998/05/27 02:24:06 curt
++// View optimizations by Norman Vine.
++//
++// Revision 1.7 1998/05/17 16:59:04 curt
++// First pass at view frustum culling now operational.
++//
++// Revision 1.6 1998/05/16 13:08:37 curt
++// C++ - ified views.[ch]xx
++// Shuffled some additional view parameters into the fgVIEW class.
++// Changed tile-radius to tile-diameter because it is a much better
++// name.
++// Added a WORLD_TO_EYE transformation to views.cxx. This allows us
++// to transform world space to eye space for view frustum culling.
++//
++// Revision 1.5 1998/05/02 01:51:02 curt
++// Updated polartocart conversion routine.
++//
++// Revision 1.4 1998/04/28 01:20:24 curt
++// Type-ified fgTIME and fgVIEW.
++// Added a command line option to disable textures.
++//
++// Revision 1.3 1998/04/25 22:06:31 curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.2 1998/04/24 00:49:22 curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Trying out some different option parsing code.
++// Some code reorganization.
++//
++// Revision 1.1 1998/04/22 13:25:46 curt
++// C++ - ifing the code.
++// Starting a bit of reorganization of lighting code.
++//
++// Revision 1.11 1998/04/21 17:02:42 curt
++// Prepairing for C++ integration.
++//
++// Revision 1.10 1998/02/07 15:29:45 curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.9 1998/01/29 00:50:29 curt
++// Added a view record field for absolute x, y, z position.
++//
++// Revision 1.8 1998/01/27 00:47:58 curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.7 1998/01/22 02:59:38 curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.6 1998/01/19 19:27:10 curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.5 1997/12/22 04:14:32 curt
++// Aligned sky with sun so dusk/dawn effects can be correct relative to the sun.
++//
++// Revision 1.4 1997/12/17 23:13:36 curt
++// Began working on rendering a sky.
++//
++// Revision 1.3 1997/12/15 23:54:51 curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.2 1997/12/10 22:37:48 curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.1 1997/08/27 21:31:18 curt
++// Initial revision.
++//
--- /dev/null
--- /dev/null
++noinst_LIBRARIES = libObjects.a
++
++libObjects_a_SOURCES = \
++ fragment.cxx fragment.hxx \
++ material.cxx material.hxx \
++ obj.cxx obj.hxx \
++ texload.c texload.h
++
++INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib -I$(top_builddir)/Simulator
--- /dev/null
--- /dev/null
++// fragment.cxx -- routines to handle "atomic" display objects
++//
++// Written by Curtis Olson, started August 1998.
++//
++// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#include <Include/fg_constants.h>
++#include <Math/mat3.h>
++#include <Math/point3d.hxx>
++#include <Scenery/tile.hxx>
++
++#include "fragment.hxx"
++
++
++template <class T>
++inline const int FG_SIGN(const T& x) {
++ return x < T(0) ? -1 : 1;
++}
++
++template <class T>
++inline const T& FG_MIN(const T& a, const T& b) {
++ return b < a ? b : a;
++}
++
++template <class T>
++inline const T& FG_MAX(const T& a, const T& b) {
++ return a < b ? b : a;
++}
++
++// return the minimum of the three values
++template <class T>
++inline const T& fg_min3( const T& a, const T& b, const T& c)
++{
++ return (a > b ? FG_MIN (b, c) : FG_MIN (a, c));
++}
++
++
++// return the maximum of the three values
++template <class T>
++inline const T& fg_max3 (const T& a, const T& b, const T& c)
++{
++ return (a < b ? FG_MAX (b, c) : FG_MAX (a, c));
++}
++
++// Add a face to the face list
++// Copy constructor
++fgFRAGMENT::fgFRAGMENT ( const fgFRAGMENT & rhs ) :
++ center ( rhs.center ),
++ bounding_radius( rhs.bounding_radius ),
++ material_ptr ( rhs.material_ptr ),
++ tile_ptr ( rhs.tile_ptr ),
++ display_list ( rhs.display_list ),
++ faces ( rhs.faces )
++{
++}
++
++fgFRAGMENT & fgFRAGMENT::operator = ( const fgFRAGMENT & rhs )
++{
++ if(!(this == &rhs )) {
++ center = rhs.center;
++ bounding_radius = rhs.bounding_radius;
++ material_ptr = rhs.material_ptr;
++ tile_ptr = rhs.tile_ptr;
++ // display_list = rhs.display_list;
++ faces = rhs.faces;
++ }
++ return *this;
++}
++
++
++// test if line intesects with this fragment. p0 and p1 are the two
++// line end points of the line. If side_flag is true, check to see
++// that end points are on opposite sides of face. Returns 1 if it
++// intersection found, 0 otherwise. If it intesects, result is the
++// point of intersection
++
++int fgFRAGMENT::intersect( const Point3D& end0,
++ const Point3D& end1,
++ int side_flag,
++ Point3D& result) const
++{
++ fgTILE *t;
++ MAT3vec v1, v2, n, center;
++ double p1[3], p2[3], p3[3];
++ double x, y, z; // temporary holding spot for result
++ double a, b, c, d;
++ double x0, y0, z0, x1, y1, z1, a1, b1, c1;
++ double t1, t2, t3;
++ double xmin, xmax, ymin, ymax, zmin, zmax;
++ double dx, dy, dz, min_dim, x2, y2, x3, y3, rx, ry;
++ int side1, side2;
++
++ // find the associated tile
++ t = tile_ptr;
++
++ // printf("Intersecting\n");
++
++ // traverse the face list for this fragment
++ const_iterator last = faces.end();
++ for ( const_iterator current = faces.begin(); current != last; ++current )
++ {
++ // printf(".");
++
++ // get face vertex coordinates
++ center[0] = t->center.x();
++ center[1] = t->center.y();
++ center[2] = t->center.z();
++
++ MAT3_ADD_VEC(p1, t->nodes[(*current).n1], center);
++ MAT3_ADD_VEC(p2, t->nodes[(*current).n2], center);
++ MAT3_ADD_VEC(p3, t->nodes[(*current).n3], center);
++
++ // printf("point 1 = %.2f %.2f %.2f\n", p1[0], p1[1], p1[2]);
++ // printf("point 2 = %.2f %.2f %.2f\n", p2[0], p2[1], p2[2]);
++ // printf("point 3 = %.2f %.2f %.2f\n", p3[0], p3[1], p3[2]);
++
++ // calculate two edge vectors, and the face normal
++ MAT3_SUB_VEC(v1, p2, p1);
++ MAT3_SUB_VEC(v2, p3, p1);
++ MAT3cross_product(n, v1, v2);
++
++ // calculate the plane coefficients for the plane defined by
++ // this face. If n is the normal vector, n = (a, b, c) and p1
++ // is a point on the plane, p1 = (x0, y0, z0), then the
++ // equation of the line is a(x-x0) + b(y-y0) + c(z-z0) = 0
++ a = n[0];
++ b = n[1];
++ c = n[2];
++ d = a * p1[0] + b * p1[1] + c * p1[2];
++ // printf("a, b, c, d = %.2f %.2f %.2f %.2f\n", a, b, c, d);
++
++ // printf("p1(d) = %.2f\n", a * p1[0] + b * p1[1] + c * p1[2]);
++ // printf("p2(d) = %.2f\n", a * p2[0] + b * p2[1] + c * p2[2]);
++ // printf("p3(d) = %.2f\n", a * p3[0] + b * p3[1] + c * p3[2]);
++
++ // calculate the line coefficients for the specified line
++ x0 = end0.x(); x1 = end1.x();
++ y0 = end0.y(); y1 = end1.y();
++ z0 = end0.z(); z1 = end1.z();
++
++ if ( fabs(x1 - x0) > FG_EPSILON ) {
++ a1 = 1.0 / (x1 - x0);
++ } else {
++ // we got a big divide by zero problem here
++ a1 = 0.0;
++ }
++ b1 = y1 - y0;
++ c1 = z1 - z0;
++
++ // intersect the specified line with this plane
++ t1 = b * b1 * a1;
++ t2 = c * c1 * a1;
++
++ // printf("a = %.2f t1 = %.2f t2 = %.2f\n", a, t1, t2);
++
++ if ( fabs(a + t1 + t2) > FG_EPSILON ) {
++ x = (t1*x0 - b*y0 + t2*x0 - c*z0 + d) / (a + t1 + t2);
++ t3 = a1 * (x - x0);
++ y = b1 * t3 + y0;
++ z = c1 * t3 + z0;
++ // printf("result(d) = %.2f\n", a * x + b * y + c * z);
++ } else {
++ // no intersection point
++ continue;
++ }
++
++ if ( side_flag ) {
++ // check to see if end0 and end1 are on opposite sides of
++ // plane
++ if ( (x - x0) > FG_EPSILON ) {
++ t1 = x;
++ t2 = x0;
++ t3 = x1;
++ } else if ( (y - y0) > FG_EPSILON ) {
++ t1 = y;
++ t2 = y0;
++ t3 = y1;
++ } else if ( (z - z0) > FG_EPSILON ) {
++ t1 = z;
++ t2 = z0;
++ t3 = z1;
++ } else {
++ // everything is too close together to tell the difference
++ // so the current intersection point should work as good
++ // as any
++ result = Point3D(x, y, z);
++ return(1);
++ }
++ side1 = FG_SIGN (t1 - t2);
++ side2 = FG_SIGN (t1 - t3);
++ if ( side1 == side2 ) {
++ // same side, punt
++ continue;
++ }
++ }
++
++ // check to see if intersection point is in the bounding
++ // cube of the face
++#ifdef XTRA_DEBUG_STUFF
++ xmin = fg_min3 (p1[0], p2[0], p3[0]);
++ xmax = fg_max3 (p1[0], p2[0], p3[0]);
++ ymin = fg_min3 (p1[1], p2[1], p3[1]);
++ ymax = fg_max3 (p1[1], p2[1], p3[1]);
++ zmin = fg_min3 (p1[2], p2[2], p3[2]);
++ zmax = fg_max3 (p1[2], p2[2], p3[2]);
++ printf("bounding cube = %.2f,%.2f,%.2f %.2f,%.2f,%.2f\n",
++ xmin, ymin, zmin, xmax, ymax, zmax);
++#endif
++ // punt if outside bouding cube
++ if ( x < (xmin = fg_min3 (p1[0], p2[0], p3[0])) ) {
++ continue;
++ } else if ( x > (xmax = fg_max3 (p1[0], p2[0], p3[0])) ) {
++ continue;
++ } else if ( y < (ymin = fg_min3 (p1[1], p2[1], p3[1])) ) {
++ continue;
++ } else if ( y > (ymax = fg_max3 (p1[1], p2[1], p3[1])) ) {
++ continue;
++ } else if ( z < (zmin = fg_min3 (p1[2], p2[2], p3[2])) ) {
++ continue;
++ } else if ( z > (zmax = fg_max3 (p1[2], p2[2], p3[2])) ) {
++ continue;
++ }
++
++ // (finally) check to see if the intersection point is
++ // actually inside this face
++
++ //first, drop the smallest dimension so we only have to work
++ //in 2d.
++ dx = xmax - xmin;
++ dy = ymax - ymin;
++ dz = zmax - zmin;
++ min_dim = fg_min3 (dx, dy, dz);
++ if ( fabs(min_dim - dx) <= FG_EPSILON ) {
++ // x is the smallest dimension
++ x1 = p1[1];
++ y1 = p1[2];
++ x2 = p2[1];
++ y2 = p2[2];
++ x3 = p3[1];
++ y3 = p3[2];
++ rx = y;
++ ry = z;
++ } else if ( fabs(min_dim - dy) <= FG_EPSILON ) {
++ // y is the smallest dimension
++ x1 = p1[0];
++ y1 = p1[2];
++ x2 = p2[0];
++ y2 = p2[2];
++ x3 = p3[0];
++ y3 = p3[2];
++ rx = x;
++ ry = z;
++ } else if ( fabs(min_dim - dz) <= FG_EPSILON ) {
++ // z is the smallest dimension
++ x1 = p1[0];
++ y1 = p1[1];
++ x2 = p2[0];
++ y2 = p2[1];
++ x3 = p3[0];
++ y3 = p3[1];
++ rx = x;
++ ry = y;
++ } else {
++ // all dimensions are really small so lets call it close
++ // enough and return a successful match
++ result = Point3D(x, y, z);
++ return(1);
++ }
++
++ // check if intersection point is on the same side of p1 <-> p2 as p3
++ t1 = (y1 - y2) / (x1 - x2);
++ side1 = FG_SIGN (t1 * ((x3) - x2) + y2 - (y3));
++ side2 = FG_SIGN (t1 * ((rx) - x2) + y2 - (ry));
++ if ( side1 != side2 ) {
++ // printf("failed side 1 check\n");
++ continue;
++ }
++
++ // check if intersection point is on correct side of p2 <-> p3 as p1
++ t1 = (y2 - y3) / (x2 - x3);
++ side1 = FG_SIGN (t1 * ((x1) - x3) + y3 - (y1));
++ side2 = FG_SIGN (t1 * ((rx) - x3) + y3 - (ry));
++ if ( side1 != side2 ) {
++ // printf("failed side 2 check\n");
++ continue;
++ }
++
++ // check if intersection point is on correct side of p1 <-> p3 as p2
++ t1 = (y1 - y3) / (x1 - x3);
++ side1 = FG_SIGN (t1 * ((x2) - x3) + y3 - (y2));
++ side2 = FG_SIGN (t1 * ((rx) - x3) + y3 - (ry));
++ if ( side1 != side2 ) {
++ // printf("failed side 3 check\n");
++ continue;
++ }
++
++ // printf( "intersection point = %.2f %.2f %.2f\n", x, y, z);
++ result = Point3D(x, y, z);
++ return(1);
++ }
++
++ // printf("\n");
++
++ return(0);
++}
++
++// $Log$
++// Revision 1.7 1999/02/26 22:09:56 curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.6 1998/10/18 01:17:20 curt
++// Point3D tweaks.
++//
++// Revision 1.5 1998/10/16 00:54:37 curt
++// Converted to Point3D class.
++//
++// Revision 1.4 1998/09/15 01:35:03 curt
++// cleaned up my fragment.num_faces hack :-) to use the STL (no need in
++// duplicating work.)
++// Tweaked fgTileMgrRender() do not calc tile matrix unless necessary.
++// removed some unneeded stuff from fgTileMgrCurElev()
++//
++// Revision 1.3 1998/09/08 21:40:42 curt
++// Updates from Bernie Bright.
++//
++// Revision 1.2 1998/09/01 19:03:07 curt
++// Changes contributed by Bernie Bright <bbright@c031.aone.net.au>
++// - The new classes in libmisc.tgz define a stream interface into zlib.
++// I've put these in a new directory, Lib/Misc. Feel free to rename it
++// to something more appropriate. However you'll have to change the
++// include directives in all the other files. Additionally you'll have
++// add the library to Lib/Makefile.am and Simulator/Main/Makefile.am.
++//
++// The StopWatch class in Lib/Misc requires a HAVE_GETRUSAGE autoconf
++// test so I've included the required changes in config.tgz.
++//
++// There are a fair few changes to Simulator/Objects as I've moved
++// things around. Loading tiles is quicker but thats not where the delay
++// is. Tile loading takes a few tenths of a second per file on a P200
++// but it seems to be the post-processing that leads to a noticeable
++// blip in framerate. I suppose its time to start profiling to see where
++// the delays are.
++//
++// I've included a brief description of each archives contents.
++//
++// Lib/Misc/
++// zfstream.cxx
++// zfstream.hxx
++// C++ stream interface into zlib.
++// Taken from zlib-1.1.3/contrib/iostream/.
++// Minor mods for STL compatibility.
++// There's no copyright associated with these so I assume they're
++// covered by zlib's.
++//
++// fgstream.cxx
++// fgstream.hxx
++// FlightGear input stream using gz_ifstream. Tries to open the
++// given filename. If that fails then filename is examined and a
++// ".gz" suffix is removed or appended and that file is opened.
++//
++// stopwatch.hxx
++// A simple timer for benchmarking. Not used in production code.
++// Taken from the Blitz++ project. Covered by GPL.
++//
++// strutils.cxx
++// strutils.hxx
++// Some simple string manipulation routines.
++//
++// Simulator/Airports/
++// Load airports database using fgstream.
++// Changed fgAIRPORTS to use set<> instead of map<>.
++// Added bool fgAIRPORTS::search() as a neater way doing the lookup.
++// Returns true if found.
++//
++// Simulator/Astro/
++// Modified fgStarsInit() to load stars database using fgstream.
++//
++// Simulator/Objects/
++// Modified fgObjLoad() to use fgstream.
++// Modified fgMATERIAL_MGR::load_lib() to use fgstream.
++// Many changes to fgMATERIAL.
++// Some changes to fgFRAGMENT but I forget what!
++//
++// Revision 1.1 1998/08/25 16:51:23 curt
++// Moved from ../Scenery
++//
++//
++
--- /dev/null
--- /dev/null
++// fragment.hxx -- routines to handle "atomic" display objects
++//
++// Written by Curtis Olson, started August 1998.
++//
++// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#ifndef _FRAGMENT_HXX
++#define _FRAGMENT_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#include <Include/compiler.h>
++
++#include <vector>
++
++#include <Include/fg_constants.h>
++#include <Math/mat3.h>
++#include <Math/point3d.hxx>
++
++FG_USING_STD(vector);
++
++
++struct fgFACE {
++ int n1, n2, n3;
++
++ fgFACE( int a = 0, int b =0, int c =0 )
++ : n1(a), n2(b), n3(c) {}
++
++ fgFACE( const fgFACE & image )
++ : n1(image.n1), n2(image.n2), n3(image.n3) {}
++
++ fgFACE& operator= ( const fgFACE & image ) {
++ n1 = image.n1; n2 = image.n2; n3 = image.n3; return *this;
++ }
++
++ ~fgFACE() {}
++};
++
++inline bool
++operator== ( const fgFACE& lhs, const fgFACE& rhs )
++{
++ return (lhs.n1 == rhs.n1) && (lhs.n2 == rhs.n2) && (lhs.n3 == rhs.n3);
++}
++
++// Forward declarations
++class fgTILE;
++class fgMATERIAL;
++
++// Object fragment data class
++class fgFRAGMENT {
++
++private:
++
++public:
++ // culling data for this object fragment (fine grain culling)
++ Point3D center;
++ double bounding_radius;
++
++ // variable offset data for this object fragment for this frame
++ // fgCartesianPoint3d tile_offset;
++
++ // saved transformation matrix for this fragment (used by renderer)
++ // GLfloat matrix[16];
++
++ // tile_ptr & material_ptr are set so that when we traverse the
++ // list of fragments we can quickly reference back the tile or
++ // material property this fragment is assigned to.
++
++ // material property pointer
++ fgMATERIAL *material_ptr;
++
++ // tile pointer
++ fgTILE *tile_ptr;
++
++ // OpenGL display list for fragment data
++ GLint display_list;
++
++ // face list (this indexes into the master tile vertex list)
++ typedef vector < fgFACE > container;
++ typedef container::iterator iterator;
++ typedef container::const_iterator const_iterator;
++
++ container faces;
++
++public:
++
++ // number of faces in this fragment
++ int num_faces() {
++ return faces.size();
++ }
++
++ // Add a face to the face list
++ void add_face(int n1, int n2, int n3) {
++ faces.push_back( fgFACE(n1,n2,n3) );
++ }
++
++ // test if line intesects with this fragment. p0 and p1 are the
++ // two line end points of the line. If side_flag is true, check
++ // to see that end points are on opposite sides of face. Returns
++ // 1 if it intersection found, 0 otherwise. If it intesects,
++ // result is the point of intersection
++ int intersect( const Point3D& end0,
++ const Point3D& end1,
++ int side_flag,
++ Point3D& result) const;
++
++ // Constructors
++ fgFRAGMENT () { /*faces.reserve(512);*/}
++ fgFRAGMENT ( const fgFRAGMENT &image );
++
++ // Destructor
++ ~fgFRAGMENT() { faces.erase( faces.begin(), faces.end() ); }
++
++ // operators
++ fgFRAGMENT & operator = ( const fgFRAGMENT & rhs );
++
++ bool operator < ( const fgFRAGMENT & rhs ) const {
++ // This is completely arbitrary. It satisfies RW's STL implementation
++ return bounding_radius < rhs.bounding_radius;
++ }
++
++ void init() {
++ faces.erase( faces.begin(), faces.end() );
++ }
++
++ int deleteDisplayList() {
++ xglDeleteLists( display_list, 1 ); return 0;
++ }
++
++ friend bool operator== ( const fgFRAGMENT & lhs, const fgFRAGMENT & rhs );
++};
++
++inline bool
++operator == ( const fgFRAGMENT & lhs, const fgFRAGMENT & rhs ) {
++ return lhs.center == rhs.center;
++}
++
++
++#endif // _FRAGMENT_HXX
++
++
++// $Log$
++// Revision 1.12 1999/04/05 02:14:21 curt
++// Moved max node per tile definition to fg_constants.h
++//
++// Revision 1.11 1999/03/25 19:02:53 curt
++// Removed an unneeded include.
++//
++// Revision 1.10 1999/03/15 17:59:12 curt
++// MSVC++ portability tweaks contributed by Bernie Bright.
++// Un-nested struct fgFace.
++// Made fgFragment::deleteDisplayList() a non-const member.
++//
++// Revision 1.9 1999/03/02 01:03:23 curt
++// Tweaks for building with native SGI compilers.
++//
++// Revision 1.8 1999/02/26 22:09:57 curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.7 1998/11/02 18:29:00 curt
++// Portability changes for the Borland compiler.
++//
++// Revision 1.6 1998/10/16 00:54:38 curt
++// Converted to Point3D class.
++//
++// Revision 1.5 1998/09/15 01:35:04 curt
++// cleaned up my fragment.num_faces hack :-) to use the STL (no need in
++// duplicating work.)
++// Tweaked fgTileMgrRender() do not calc tile matrix unless necessary.
++// removed some unneeded stuff from fgTileMgrCurElev()
++//
++// Revision 1.4 1998/09/10 19:07:09 curt
++// /Simulator/Objects/fragment.hxx
++// Nested fgFACE inside fgFRAGMENT since its not used anywhere else.
++//
++// ./Simulator/Objects/material.cxx
++// ./Simulator/Objects/material.hxx
++// Made fgMATERIAL and fgMATERIAL_MGR bona fide classes with private
++// data members - that should keep the rabble happy :)
++//
++// ./Simulator/Scenery/tilemgr.cxx
++// In viewable() delay evaluation of eye[0] and eye[1] in until they're
++// actually needed.
++// Change to fgTileMgrRender() to call fgMATERIAL_MGR::render_fragments()
++// method.
++//
++// ./Include/fg_stl_config.h
++// ./Include/auto_ptr.hxx
++// Added support for g++ 2.7.
++// Further changes to other files are forthcoming.
++//
++// Brief summary of changes required for g++ 2.7.
++// operator->() not supported by iterators: use (*i).x instead of i->x
++// default template arguments not supported,
++// <functional> doesn't have mem_fun_ref() needed by callbacks.
++// some std include files have different names.
++// template member functions not supported.
++//
++// Revision 1.3 1998/09/08 21:40:44 curt
++// Updates from Bernie Bright.
++//
++// Revision 1.2 1998/09/01 19:03:08 curt
++// Changes contributed by Bernie Bright <bbright@c031.aone.net.au>
++// - The new classes in libmisc.tgz define a stream interface into zlib.
++// I've put these in a new directory, Lib/Misc. Feel free to rename it
++// to something more appropriate. However you'll have to change the
++// include directives in all the other files. Additionally you'll have
++// add the library to Lib/Makefile.am and Simulator/Main/Makefile.am.
++//
++// The StopWatch class in Lib/Misc requires a HAVE_GETRUSAGE autoconf
++// test so I've included the required changes in config.tgz.
++//
++// There are a fair few changes to Simulator/Objects as I've moved
++// things around. Loading tiles is quicker but thats not where the delay
++// is. Tile loading takes a few tenths of a second per file on a P200
++// but it seems to be the post-processing that leads to a noticeable
++// blip in framerate. I suppose its time to start profiling to see where
++// the delays are.
++//
++// I've included a brief description of each archives contents.
++//
++// Lib/Misc/
++// zfstream.cxx
++// zfstream.hxx
++// C++ stream interface into zlib.
++// Taken from zlib-1.1.3/contrib/iostream/.
++// Minor mods for STL compatibility.
++// There's no copyright associated with these so I assume they're
++// covered by zlib's.
++//
++// fgstream.cxx
++// fgstream.hxx
++// FlightGear input stream using gz_ifstream. Tries to open the
++// given filename. If that fails then filename is examined and a
++// ".gz" suffix is removed or appended and that file is opened.
++//
++// stopwatch.hxx
++// A simple timer for benchmarking. Not used in production code.
++// Taken from the Blitz++ project. Covered by GPL.
++//
++// strutils.cxx
++// strutils.hxx
++// Some simple string manipulation routines.
++//
++// Simulator/Airports/
++// Load airports database using fgstream.
++// Changed fgAIRPORTS to use set<> instead of map<>.
++// Added bool fgAIRPORTS::search() as a neater way doing the lookup.
++// Returns true if found.
++//
++// Simulator/Astro/
++// Modified fgStarsInit() to load stars database using fgstream.
++//
++// Simulator/Objects/
++// Modified fgObjLoad() to use fgstream.
++// Modified fgMATERIAL_MGR::load_lib() to use fgstream.
++// Many changes to fgMATERIAL.
++// Some changes to fgFRAGMENT but I forget what!
++//
++// Revision 1.1 1998/08/25 16:51:23 curt
++// Moved from ../Scenery
++//
++//
--- /dev/null
--- /dev/null
++// material.cxx -- class to handle material properties
++//
++// Written by Curtis Olson, started May 1998.
++//
++// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#include <Include/compiler.h>
++
++#include <string.h>
++#include STL_STRING
++
++#include <Debug/logstream.hxx>
++#include <Misc/fgstream.hxx>
++#include <Main/options.hxx>
++#include <Main/views.hxx>
++#include <Scenery/tile.hxx>
++
++#include "material.hxx"
++#include "fragment.hxx"
++#include "texload.h"
++
++FG_USING_STD(string);
++
++
++// global material management class
++fgMATERIAL_MGR material_mgr;
++
++
++// Constructor
++fgMATERIAL::fgMATERIAL ( void )
++ : texture_name(""),
++ alpha(0)
++ // , list_size(0)
++{
++ ambient[0] = ambient[1] = ambient[2] = ambient[3] = 0.0;
++ diffuse[0] = diffuse[1] = diffuse[2] = diffuse[3] = 0.0;
++ specular[0] = specular[1] = specular[2] = specular[3] = 0.0;
++ emissive[0] = emissive[1] = emissive[2] = emissive[3] = 0.0;
++}
++
++/*
++int
++fgMATERIAL::append_sort_list( fgFRAGMENT *object )
++{
++ if ( list_size < FG_MAX_MATERIAL_FRAGS ) {
++ list[ list_size++ ] = object;
++ return 1;
++ } else {
++ return 0;
++ }
++}
++*/
++
++istream&
++operator >> ( istream& in, fgMATERIAL& m )
++{
++ string token;
++
++ for (;;) {
++ in >> token;
++ if ( token == "texture" )
++ {
++ in >> token >> m.texture_name;
++ }
++ else if ( token == "ambient" )
++ {
++ in >> token >> m.ambient[0] >> m.ambient[1]
++ >> m.ambient[2] >> m.ambient[3];
++ }
++ else if ( token == "diffuse" )
++ {
++ in >> token >> m.diffuse[0] >> m.diffuse[1]
++ >> m.diffuse[2] >> m.diffuse[3];
++ }
++ else if ( token == "specular" )
++ {
++ in >> token >> m.specular[0] >> m.specular[1]
++ >> m.specular[2] >> m.specular[3];
++ }
++ else if ( token == "emissive" )
++ {
++ in >> token >> m.emissive[0] >> m.emissive[1]
++ >> m.emissive[2] >> m.emissive[3];
++ }
++ else if ( token == "alpha" )
++ {
++ in >> token >> token;
++ if ( token == "yes" )
++ m.alpha = 1;
++ else if ( token == "no" )
++ m.alpha = 0;
++ else
++ {
++ FG_LOG( FG_TERRAIN, FG_INFO, "Bad alpha value " << token );
++ }
++ }
++ else if ( token[0] == '}' )
++ {
++ break;
++ }
++ }
++
++ return in;
++}
++
++void
++fgMATERIAL::load_texture()
++{
++ GLubyte *texbuf;
++ int width, height;
++
++ // create the texture object and bind it
++#ifdef GL_VERSION_1_1
++ xglGenTextures(1, &texture_id );
++ xglBindTexture(GL_TEXTURE_2D, texture_id );
++#elif GL_EXT_texture_object
++ xglGenTexturesEXT(1, &texture_id );
++ xglBindTextureEXT(GL_TEXTURE_2D, texture_id );
++#else
++# error port me
++#endif
++
++ // set the texture parameters for this texture
++ xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ) ;
++ xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ) ;
++ xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
++ GL_LINEAR );
++ // xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
++ // GL_NEAREST_MIPMAP_NEAREST );
++ xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
++ /* GL_LINEAR */
++ /* GL_NEAREST_MIPMAP_LINEAR */
++ GL_LINEAR_MIPMAP_LINEAR ) ;
++
++ /* load in the texture data */
++ string tpath = current_options.get_fg_root() + "/Textures/" +
++ texture_name + ".rgb";
++ string fg_tpath = tpath + ".gz";
++
++ if ( alpha == 0 ) {
++ // load rgb texture
++
++ // Try uncompressed
++ if ( (texbuf =
++ read_rgb_texture(tpath.c_str(), &width, &height)) ==
++ NULL )
++ {
++ // Try compressed
++ if ( (texbuf =
++ read_rgb_texture(fg_tpath.c_str(), &width, &height))
++ == NULL )
++ {
++ FG_LOG( FG_GENERAL, FG_ALERT,
++ "Error in loading texture " << tpath );
++ exit(-1);
++ }
++ }
++
++ /* xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,
++ GL_RGB, GL_UNSIGNED_BYTE, texbuf); */
++
++ gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGB, width, height,
++ GL_RGB, GL_UNSIGNED_BYTE, texbuf );
++ } else if ( alpha == 1 ) {
++ // load rgba (alpha) texture
++
++ // Try uncompressed
++ if ( (texbuf =
++ read_alpha_texture(tpath.c_str(), &width, &height))
++ == NULL )
++ {
++ // Try compressed
++ if ((texbuf =
++ read_alpha_texture(fg_tpath.c_str(), &width, &height))
++ == NULL )
++ {
++ FG_LOG( FG_GENERAL, FG_ALERT,
++ "Error in loading texture " << tpath );
++ exit(-1);
++ }
++ }
++
++ xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
++ GL_RGBA, GL_UNSIGNED_BYTE, texbuf);
++ }
++}
++
++
++// Destructor
++fgMATERIAL::~fgMATERIAL ( void ) {
++}
++
++
++// Constructor
++fgMATERIAL_MGR::fgMATERIAL_MGR ( void ) {
++ textures_loaded = false;
++}
++
++
++void
++fgMATERIAL::render_fragments()
++{
++ int tris_rendered = current_view.get_tris_rendered();
++
++ // cout << "rendering " + texture_name + " = " << list_size << "\n";
++
++ if ( empty() )
++ return;
++
++ if ( current_options.get_textures() )
++ {
++#ifdef GL_VERSION_1_1
++ xglBindTexture(GL_TEXTURE_2D, texture_id);
++#elif GL_EXT_texture_object
++ xglBindTextureEXT(GL_TEXTURE_2D, texture_id);
++#else
++# error port me
++#endif
++ } else {
++ xglMaterialfv (GL_FRONT, GL_AMBIENT, ambient);
++ xglMaterialfv (GL_FRONT, GL_DIFFUSE, diffuse);
++ }
++
++ fgTILE* last_tile_ptr = NULL;
++ frag_list_iterator current = list.begin();
++ frag_list_iterator last = list.end();
++
++ for ( ; current != last; ++current ) {
++ fgFRAGMENT* frag_ptr = *current;
++ tris_rendered += frag_ptr->num_faces();
++ if ( frag_ptr->tile_ptr != last_tile_ptr )
++ {
++ // new tile, new translate
++ last_tile_ptr = frag_ptr->tile_ptr;
++ xglLoadMatrixd( frag_ptr->tile_ptr->model_view );
++ }
++
++ // Woohoo!!! We finally get to draw something!
++ // printf(" display_list = %d\n", frag_ptr->display_list);
++ xglCallList( frag_ptr->display_list );
++ }
++
++ current_view.set_tris_rendered( tris_rendered );
++}
++
++
++// Load a library of material properties
++int
++fgMATERIAL_MGR::load_lib ( void )
++{
++ string material_name;
++
++ // build the path name to the material db
++ string mpath = current_options.get_fg_root() + "/materials";
++ fg_gzifstream in( mpath );
++ if ( ! in ) {
++ FG_LOG( FG_GENERAL, FG_ALERT, "Cannot open file: " << mpath );
++ exit(-1);
++ }
++
++ while ( ! in.eof() ) {
++ // printf("%s", line);
++
++ // strip leading white space and comments
++ in >> skipcomment;
++
++ // set to zero to prevent its value accidently being '{'
++ // after a failed >> operation.
++ char token = 0;
++
++ in >> material_name >> token;
++
++ if ( token == '{' ) {
++ FG_LOG( FG_TERRAIN, FG_INFO,
++ " Loading material " << material_name );
++ fgMATERIAL m;
++ in >> m;
++
++ if ( current_options.get_textures() ) {
++ m.load_texture();
++ }
++
++ material_mgr.material_map[material_name] = m;
++ }
++ }
++
++ if ( current_options.get_textures() ) {
++ textures_loaded = true;
++ }
++
++ return(1);
++}
++
++
++// Initialize the transient list of fragments for each material property
++void
++fgMATERIAL_MGR::init_transient_material_lists( void )
++{
++ iterator last = end();
++ for ( iterator it = begin(); it != last; ++it )
++ {
++ (*it).second.init_sort_list();
++ }
++}
++
++
++bool
++fgMATERIAL_MGR::find( const string& material, fgMATERIAL*& mtl_ptr )
++{
++ iterator it = material_map.find( material );
++ if ( it != end() )
++ {
++ mtl_ptr = &((*it).second);
++ return true;
++ }
++
++ return false;
++}
++
++
++// Destructor
++fgMATERIAL_MGR::~fgMATERIAL_MGR ( void ) {
++}
++
++
++void
++fgMATERIAL_MGR::render_fragments()
++{
++ current_view.set_tris_rendered( 0 );
++
++ iterator last = end();
++ for ( iterator current = begin(); current != last; ++current )
++ (*current).second.render_fragments();
++}
++
++
++// $Log$
++// Revision 1.14 1999/03/02 01:03:24 curt
++// Tweaks for building with native SGI compilers.
++//
++// Revision 1.13 1999/02/26 22:09:58 curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.12 1998/12/09 18:50:30 curt
++// Converted "class fgVIEW" to "class FGView" and updated to make data
++// members private and make required accessor functions.
++//
++// Revision 1.11 1998/11/07 19:07:12 curt
++// Enable release builds using the --without-logging option to the configure
++// script. Also a couple log message cleanups, plus some C to C++ comment
++// conversion.
++//
++// Revision 1.10 1998/11/06 21:18:17 curt
++// Converted to new logstream debugging facility. This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.9 1998/11/06 14:47:05 curt
++// Changes to track Bernie's updates to fgstream.
++//
++// Revision 1.8 1998/10/12 23:49:17 curt
++// Changes from NHV to make the code more dynamic with fewer hard coded limits.
++//
++// Revision 1.7 1998/09/17 18:35:52 curt
++// Tweaks and optimizations by Norman Vine.
++//
++// Revision 1.6 1998/09/15 01:35:05 curt
++// cleaned up my fragment.num_faces hack :-) to use the STL (no need in
++// duplicating work.)
++// Tweaked fgTileMgrRender() do not calc tile matrix unless necessary.
++// removed some unneeded stuff from fgTileMgrCurElev()
++//
++// Revision 1.5 1998/09/10 19:07:11 curt
++// /Simulator/Objects/fragment.hxx
++// Nested fgFACE inside fgFRAGMENT since its not used anywhere else.
++//
++// ./Simulator/Objects/material.cxx
++// ./Simulator/Objects/material.hxx
++// Made fgMATERIAL and fgMATERIAL_MGR bona fide classes with private
++// data members - that should keep the rabble happy :)
++//
++// ./Simulator/Scenery/tilemgr.cxx
++// In viewable() delay evaluation of eye[0] and eye[1] in until they're
++// actually needed.
++// Change to fgTileMgrRender() to call fgMATERIAL_MGR::render_fragments()
++// method.
++//
++// ./Include/fg_stl_config.h
++// ./Include/auto_ptr.hxx
++// Added support for g++ 2.7.
++// Further changes to other files are forthcoming.
++//
++// Brief summary of changes required for g++ 2.7.
++// operator->() not supported by iterators: use (*i).x instead of i->x
++// default template arguments not supported,
++// <functional> doesn't have mem_fun_ref() needed by callbacks.
++// some std include files have different names.
++// template member functions not supported.
++//
++// Revision 1.4 1998/09/01 19:03:08 curt
++// Changes contributed by Bernie Bright <bbright@c031.aone.net.au>
++// - The new classes in libmisc.tgz define a stream interface into zlib.
++// I've put these in a new directory, Lib/Misc. Feel free to rename it
++// to something more appropriate. However you'll have to change the
++// include directives in all the other files. Additionally you'll have
++// add the library to Lib/Makefile.am and Simulator/Main/Makefile.am.
++//
++// The StopWatch class in Lib/Misc requires a HAVE_GETRUSAGE autoconf
++// test so I've included the required changes in config.tgz.
++//
++// There are a fair few changes to Simulator/Objects as I've moved
++// things around. Loading tiles is quicker but thats not where the delay
++// is. Tile loading takes a few tenths of a second per file on a P200
++// but it seems to be the post-processing that leads to a noticeable
++// blip in framerate. I suppose its time to start profiling to see where
++// the delays are.
++//
++// I've included a brief description of each archives contents.
++//
++// Lib/Misc/
++// zfstream.cxx
++// zfstream.hxx
++// C++ stream interface into zlib.
++// Taken from zlib-1.1.3/contrib/iostream/.
++// Minor mods for STL compatibility.
++// There's no copyright associated with these so I assume they're
++// covered by zlib's.
++//
++// fgstream.cxx
++// fgstream.hxx
++// FlightGear input stream using gz_ifstream. Tries to open the
++// given filename. If that fails then filename is examined and a
++// ".gz" suffix is removed or appended and that file is opened.
++//
++// stopwatch.hxx
++// A simple timer for benchmarking. Not used in production code.
++// Taken from the Blitz++ project. Covered by GPL.
++//
++// strutils.cxx
++// strutils.hxx
++// Some simple string manipulation routines.
++//
++// Simulator/Airports/
++// Load airports database using fgstream.
++// Changed fgAIRPORTS to use set<> instead of map<>.
++// Added bool fgAIRPORTS::search() as a neater way doing the lookup.
++// Returns true if found.
++//
++// Simulator/Astro/
++// Modified fgStarsInit() to load stars database using fgstream.
++//
++// Simulator/Objects/
++// Modified fgObjLoad() to use fgstream.
++// Modified fgMATERIAL_MGR::load_lib() to use fgstream.
++// Many changes to fgMATERIAL.
++// Some changes to fgFRAGMENT but I forget what!
++//
++// Revision 1.3 1998/08/27 17:02:09 curt
++// Contributions from Bernie Bright <bbright@c031.aone.net.au>
++// - use strings for fg_root and airport_id and added methods to return
++// them as strings,
++// - inlined all access methods,
++// - made the parsing functions private methods,
++// - deleted some unused functions.
++// - propogated some of these changes out a bit further.
++//
++// Revision 1.2 1998/08/25 20:53:33 curt
++// Shuffled $FG_ROOT file layout.
++//
++// Revision 1.1 1998/08/25 16:51:24 curt
++// Moved from ../Scenery
++//
++// Revision 1.13 1998/08/24 20:11:39 curt
++// Tweaks ...
++//
++// Revision 1.12 1998/08/12 21:41:27 curt
++// Need to negate the test for textures so that textures aren't loaded when
++// they are disabled rather than visa versa ... :-)
++//
++// Revision 1.11 1998/08/12 21:13:03 curt
++// material.cxx: don't load textures if they are disabled
++// obj.cxx: optimizations from Norman Vine
++// tile.cxx: minor tweaks
++// tile.hxx: addition of num_faces
++// tilemgr.cxx: minor tweaks
++//
++// Revision 1.10 1998/07/24 21:42:06 curt
++// material.cxx: whups, double method declaration with no definition.
++// obj.cxx: tweaks to avoid errors in SGI's CC.
++// tile.cxx: optimizations by Norman Vine.
++// tilemgr.cxx: optimizations by Norman Vine.
++//
++// Revision 1.9 1998/07/13 21:01:57 curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.8 1998/07/08 14:47:20 curt
++// Fix GL_MODULATE vs. GL_DECAL problem introduced by splash screen.
++// polare3d.h renamed to polar3d.hxx
++// fg{Cartesian,Polar}Point3d consolodated.
++// Added some initial support for calculating local current ground elevation.
++//
++// Revision 1.7 1998/07/04 00:54:28 curt
++// Added automatic mipmap generation.
++//
++// When rendering fragments, use saved model view matrix from associated tile
++// rather than recalculating it with push() translate() pop().
++//
++// Revision 1.6 1998/06/27 16:54:59 curt
++// Check for GL_VERSION_1_1 or GL_EXT_texture_object to decide whether to use
++// "EXT" versions of texture management routines.
++//
++// Revision 1.5 1998/06/17 21:36:39 curt
++// Load and manage multiple textures defined in the Materials library.
++// Boost max material fagments for each material property to 800.
++// Multiple texture support when rendering.
++//
++// Revision 1.4 1998/06/12 00:58:04 curt
++// Build only static libraries.
++// Declare memmove/memset for Sloaris.
++//
++// Revision 1.3 1998/06/05 22:39:53 curt
++// Working on sorting by, and rendering by material properties.
++//
++// Revision 1.2 1998/06/01 17:56:20 curt
++// Incremental additions to material.cxx (not fully functional)
++// Tweaked vfc_ratio math to avoid divide by zero.
++//
++// Revision 1.1 1998/05/30 01:56:45 curt
++// Added material.cxx material.hxx
++//
--- /dev/null
--- /dev/null
++// material.hxx -- class to handle material properties
++//
++// Written by Curtis Olson, started May 1998.
++//
++// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#ifndef _MATERIAL_HXX
++#define _MATERIAL_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#include <string> // Standard C++ string library
++#include <map> // STL associative "array"
++#include <vector> // STL "array"
++
++#include "Include/compiler.h"
++FG_USING_STD(string);
++FG_USING_STD(map);
++FG_USING_STD(vector);
++FG_USING_STD(less);
++
++// forward decl.
++class fgFRAGMENT;
++
++
++// convenience types
++typedef vector < fgFRAGMENT * > frag_list_type;
++typedef frag_list_type::iterator frag_list_iterator;
++typedef frag_list_type::const_iterator frag_list_const_iterator;
++
++
++// #define FG_MAX_MATERIAL_FRAGS 800
++
++// MSVC++ 6.0 kuldge - Need forward declaration of friends.
++class fgMATERIAL;
++istream& operator >> ( istream& in, fgMATERIAL& m );
++
++// Material property class
++class fgMATERIAL {
++
++private:
++ // OpenGL texture name
++ GLuint texture_id;
++
++ // file name of texture
++ string texture_name;
++
++ // alpha texture?
++ int alpha;
++
++ // material properties
++ GLfloat ambient[4], diffuse[4], specular[4], emissive[4];
++ GLint texture_ptr;
++
++ // transient list of objects with this material type (used for sorting
++ // by material to reduce GL state changes when rendering the scene
++ frag_list_type list;
++ // size_t list_size;
++
++public:
++
++ // Constructor
++ fgMATERIAL ( void );
++
++ int size() const { return list.size(); }
++ bool empty() const { return list.size() == 0; }
++
++ // Sorting routines
++ void init_sort_list( void ) {
++ list.erase( list.begin(), list.end() );
++ }
++
++ bool append_sort_list( fgFRAGMENT *object ) {
++ list.push_back( object );
++ return true;
++ }
++
++ void render_fragments();
++
++ void load_texture();
++
++ // Destructor
++ ~fgMATERIAL ( void );
++
++ friend istream& operator >> ( istream& in, fgMATERIAL& m );
++};
++
++
++// Material management class
++class fgMATERIAL_MGR {
++
++public:
++
++ // associative array of materials
++ typedef map < string, fgMATERIAL, less<string> > container;
++ typedef container::iterator iterator;
++ typedef container::const_iterator const_iterator;
++
++ iterator begin() { return material_map.begin(); }
++ const_iterator begin() const { return material_map.begin(); }
++
++ iterator end() { return material_map.end(); }
++ const_iterator end() const { return material_map.end(); }
++
++ // Constructor
++ fgMATERIAL_MGR ( void );
++
++ // Load a library of material properties
++ int load_lib ( void );
++
++ bool get_textures_loaded() { return textures_loaded; }
++
++ // Initialize the transient list of fragments for each material property
++ void init_transient_material_lists( void );
++
++ bool find( const string& material, fgMATERIAL*& mtl_ptr );
++
++ void render_fragments();
++
++ // Destructor
++ ~fgMATERIAL_MGR ( void );
++
++private:
++
++ // Have textures been loaded
++ bool textures_loaded;
++
++ container material_map;
++};
++
++
++// global material management class
++extern fgMATERIAL_MGR material_mgr;
++
++
++#endif // _MATERIAL_HXX
++
++
++// $Log$
++// Revision 1.6 1999/02/02 20:13:39 curt
++// MSVC++ portability changes by Bernie Bright:
++//
++// Lib/Serial/serial.[ch]xx: Initial Windows support - incomplete.
++// Simulator/Astro/stars.cxx: typo? included <stdio> instead of <cstdio>
++// Simulator/Cockpit/hud.cxx: Added Standard headers
++// Simulator/Cockpit/panel.cxx: Redefinition of default parameter
++// Simulator/Flight/flight.cxx: Replaced cout with FG_LOG. Deleted <stdio.h>
++// Simulator/Main/fg_init.cxx:
++// Simulator/Main/GLUTmain.cxx:
++// Simulator/Main/options.hxx: Shuffled <fg_serial.hxx> dependency
++// Simulator/Objects/material.hxx:
++// Simulator/Time/timestamp.hxx: VC++ friend kludge
++// Simulator/Scenery/tile.[ch]xx: Fixed using std::X declarations
++// Simulator/Main/views.hxx: Added a constant
++//
++// Revision 1.5 1998/10/12 23:49:18 curt
++// Changes from NHV to make the code more dynamic with fewer hard coded limits.
++//
++// Revision 1.4 1998/09/17 18:35:53 curt
++// Tweaks and optimizations by Norman Vine.
++//
++// Revision 1.3 1998/09/10 19:07:12 curt
++// /Simulator/Objects/fragment.hxx
++// Nested fgFACE inside fgFRAGMENT since its not used anywhere else.
++//
++// ./Simulator/Objects/material.cxx
++// ./Simulator/Objects/material.hxx
++// Made fgMATERIAL and fgMATERIAL_MGR bona fide classes with private
++// data members - that should keep the rabble happy :)
++//
++// ./Simulator/Scenery/tilemgr.cxx
++// In viewable() delay evaluation of eye[0] and eye[1] in until they're
++// actually needed.
++// Change to fgTileMgrRender() to call fgMATERIAL_MGR::render_fragments()
++// method.
++//
++// ./Include/fg_stl_config.h
++// ./Include/auto_ptr.hxx
++// Added support for g++ 2.7.
++// Further changes to other files are forthcoming.
++//
++// Brief summary of changes required for g++ 2.7.
++// operator->() not supported by iterators: use (*i).x instead of i->x
++// default template arguments not supported,
++// <functional> doesn't have mem_fun_ref() needed by callbacks.
++// some std include files have different names.
++// template member functions not supported.
++//
++// Revision 1.2 1998/09/01 19:03:09 curt
++// Changes contributed by Bernie Bright <bbright@c031.aone.net.au>
++// - The new classes in libmisc.tgz define a stream interface into zlib.
++// I've put these in a new directory, Lib/Misc. Feel free to rename it
++// to something more appropriate. However you'll have to change the
++// include directives in all the other files. Additionally you'll have
++// add the library to Lib/Makefile.am and Simulator/Main/Makefile.am.
++//
++// The StopWatch class in Lib/Misc requires a HAVE_GETRUSAGE autoconf
++// test so I've included the required changes in config.tgz.
++//
++// There are a fair few changes to Simulator/Objects as I've moved
++// things around. Loading tiles is quicker but thats not where the delay
++// is. Tile loading takes a few tenths of a second per file on a P200
++// but it seems to be the post-processing that leads to a noticeable
++// blip in framerate. I suppose its time to start profiling to see where
++// the delays are.
++//
++// I've included a brief description of each archives contents.
++//
++// Lib/Misc/
++// zfstream.cxx
++// zfstream.hxx
++// C++ stream interface into zlib.
++// Taken from zlib-1.1.3/contrib/iostream/.
++// Minor mods for STL compatibility.
++// There's no copyright associated with these so I assume they're
++// covered by zlib's.
++//
++// fgstream.cxx
++// fgstream.hxx
++// FlightGear input stream using gz_ifstream. Tries to open the
++// given filename. If that fails then filename is examined and a
++// ".gz" suffix is removed or appended and that file is opened.
++//
++// stopwatch.hxx
++// A simple timer for benchmarking. Not used in production code.
++// Taken from the Blitz++ project. Covered by GPL.
++//
++// strutils.cxx
++// strutils.hxx
++// Some simple string manipulation routines.
++//
++// Simulator/Airports/
++// Load airports database using fgstream.
++// Changed fgAIRPORTS to use set<> instead of map<>.
++// Added bool fgAIRPORTS::search() as a neater way doing the lookup.
++// Returns true if found.
++//
++// Simulator/Astro/
++// Modified fgStarsInit() to load stars database using fgstream.
++//
++// Simulator/Objects/
++// Modified fgObjLoad() to use fgstream.
++// Modified fgMATERIAL_MGR::load_lib() to use fgstream.
++// Many changes to fgMATERIAL.
++// Some changes to fgFRAGMENT but I forget what!
++//
++// Revision 1.1 1998/08/25 16:51:24 curt
++// Moved from ../Scenery
++//
++// Revision 1.10 1998/07/24 21:42:06 curt
++// material.cxx: whups, double method declaration with no definition.
++// obj.cxx: tweaks to avoid errors in SGI's CC.
++// tile.cxx: optimizations by Norman Vine.
++// tilemgr.cxx: optimizations by Norman Vine.
++//
++// Revision 1.9 1998/07/06 21:34:33 curt
++// Added using namespace std for compilers that support this.
++//
++// Revision 1.8 1998/06/17 21:36:39 curt
++// Load and manage multiple textures defined in the Materials library.
++// Boost max material fagments for each material property to 800.
++// Multiple texture support when rendering.
++//
++// Revision 1.7 1998/06/12 00:58:04 curt
++// Build only static libraries.
++// Declare memmove/memset for Sloaris.
++//
++// Revision 1.6 1998/06/06 01:09:31 curt
++// I goofed on the log message in the last commit ... now fixed.
++//
++// Revision 1.5 1998/06/06 01:07:17 curt
++// Increased per material fragment list size from 100 to 400.
++// Now correctly draw viewable fragments in per material order.
++//
++// Revision 1.4 1998/06/05 22:39:53 curt
++// Working on sorting by, and rendering by material properties.
++//
++// Revision 1.3 1998/06/03 00:47:50 curt
++// No .h for STL includes.
++// Minor view culling optimizations.
++//
++// Revision 1.2 1998/06/01 17:56:20 curt
++// Incremental additions to material.cxx (not fully functional)
++// Tweaked vfc_ratio math to avoid divide by zero.
++//
++// Revision 1.1 1998/05/30 01:56:45 curt
++// Added material.cxx material.hxx
++//
--- /dev/null
--- /dev/null
++// obj.cxx -- routines to handle "sorta" WaveFront .obj format files.
++//
++// Written by Curtis Olson, started October 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$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++
++#include <stdio.h>
++#include <string.h>
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++// #if defined ( __sun__ )
++// extern "C" void *memmove(void *, const void *, size_t);
++// extern "C" void *memset(void *, int, size_t);
++// #endif
++
++#include <Include/compiler.h>
++
++#include STL_STRING
++#include <map> // STL
++#include <ctype.h> // isdigit()
++
++#include <Debug/logstream.hxx>
++#include <Misc/fgstream.hxx>
++#include <Include/fg_constants.h>
++#include <Main/options.hxx>
++#include <Math/mat3.h>
++#include <Math/fg_random.h>
++#include <Math/point3d.hxx>
++#include <Math/polar3d.hxx>
++#include <Misc/stopwatch.hxx>
++#include <Scenery/tile.hxx>
++
++#include "material.hxx"
++#include "obj.hxx"
++
++FG_USING_STD(string);
++
++
++static double normals[MAX_NODES][3];
++
++
++// given three points defining a triangle, calculate the normal
++static void calc_normal(double p1[3], double p2[3],
++ double p3[3], double normal[3])
++{
++ double v1[3], v2[3];
++ double temp;
++
++ v1[0] = p2[0] - p1[0]; v1[1] = p2[1] - p1[1]; v1[2] = p2[2] - p1[2];
++ v2[0] = p3[0] - p1[0]; v2[1] = p3[1] - p1[1]; v2[2] = p3[2] - p1[2];
++
++ MAT3cross_product(normal, v1, v2);
++ MAT3_NORMALIZE_VEC(normal,temp);
++
++ // fgPrintf( FG_TERRAIN, FG_DEBUG, " Normal = %.2f %.2f %.2f\n",
++ // normal[0], normal[1], normal[2]);
++}
++
++
++#define FG_TEX_CONSTANT 69.0
++
++
++// Calculate texture coordinates for a given point.
++static Point3D calc_tex_coords(double *node, const Point3D& ref) {
++ Point3D cp;
++ Point3D pp;
++ // double tmplon, tmplat;
++
++ // cout << "-> " << node[0] << " " << node[1] << " " << node[2] << endl;
++ // cout << "-> " << ref.x() << " " << ref.y() << " " << ref.z() << endl;
++
++ cp = Point3D( node[0] + ref.x(),
++ node[1] + ref.y(),
++ node[2] + ref.z() );
++
++ pp = fgCartToPolar3d(cp);
++
++ // tmplon = pp.lon() * RAD_TO_DEG;
++ // tmplat = pp.lat() * RAD_TO_DEG;
++ // cout << tmplon << " " << tmplat << endl;
++
++ pp.setx( fmod(RAD_TO_DEG * FG_TEX_CONSTANT * pp.x(), 11.0) );
++ pp.sety( fmod(RAD_TO_DEG * FG_TEX_CONSTANT * pp.y(), 11.0) );
++
++ if ( pp.x() < 0.0 ) {
++ pp.setx( pp.x() + 11.0 );
++ }
++
++ if ( pp.y() < 0.0 ) {
++ pp.sety( pp.y() + 11.0 );
++ }
++
++ // cout << pp << endl;
++
++ return(pp);
++}
++
++
++// Load a .obj file and build the GL fragment list
++int fgObjLoad( const string& path, fgTILE *t) {
++ fgFRAGMENT fragment;
++ Point3D pp;
++ double approx_normal[3], normal[3] /*, scale = 0.0 */;
++ // double x, y, z, xmax, xmin, ymax, ymin, zmax, zmin;
++ // GLfloat sgenparams[] = { 1.0, 0.0, 0.0, 0.0 };
++ GLint display_list = 0;
++ int shading;
++ int in_fragment = 0, in_faces = 0, vncount;
++ int n1 = 0, n2 = 0, n3 = 0, n4 = 0;
++ int last1 = 0, last2 = 0, odd = 0;
++ double (*nodes)[3];
++ Point3D center;
++
++ // printf("loading %s\n", path.c_str() );
++
++ // Attempt to open "path.gz" or "path"
++ fg_gzifstream in( path );
++ if ( ! in ) {
++ FG_LOG( FG_TERRAIN, FG_ALERT, "Cannot open file: " << path );
++ return 0;
++ }
++
++ shading = current_options.get_shading();
++
++ in_fragment = 0;
++ t->ncount = 0;
++ vncount = 0;
++ t->bounding_radius = 0.0;
++ nodes = t->nodes;
++ center = t->center;
++
++ StopWatch stopwatch;
++ stopwatch.start();
++
++ // ignore initial comments and blank lines. (priming the pump)
++ // in >> skipcomment;
++ string line;
++
++ while ( ! in.eof() ) {
++ string token;
++ char c;
++
++ in >> skipws;
++
++ if ( in.get( c ) && c == '#' ) {
++ // process a comment line
++
++ // getline( in, line );
++ // cout << "comment = " << line << endl;
++
++ in >> token;
++
++ if ( token == "gbs" ) {
++ // reference point (center offset)
++ in >> t->center >> t->bounding_radius;
++ center = t->center;
++ // cout << "center = " << center
++ // << " radius = " << t->bounding_radius << endl;
++ } else if ( token == "bs" ) {
++ // reference point (center offset)
++ in >> fragment.center;
++ in >> fragment.bounding_radius;
++
++ // cout << "center = " << fragment.center
++ // << " radius = " << fragment.bounding_radius << endl;
++ } else if ( token == "usemtl" ) {
++ // material property specification
++
++ // series of individual triangles
++ if ( in_faces ) {
++ xglEnd();
++ }
++
++ // this also signals the start of a new fragment
++ if ( in_fragment ) {
++ // close out the previous structure and start the next
++ xglEndList();
++ // printf("xglEnd(); xglEndList();\n");
++
++ // update fragment
++ fragment.display_list = display_list;
++
++ // push this fragment onto the tile's object list
++ t->fragment_list.push_back(fragment);
++ } else {
++ in_fragment = 1;
++ }
++
++ // printf("start of fragment (usemtl)\n");
++
++ display_list = xglGenLists(1);
++ xglNewList(display_list, GL_COMPILE);
++ // printf("xglGenLists(); xglNewList();\n");
++ in_faces = 0;
++
++ // reset the existing face list
++ // printf("cleaning a fragment with %d faces\n",
++ // fragment.faces.size());
++ fragment.init();
++
++ // scan the material line
++ string material;
++ in >> material;
++ fragment.tile_ptr = t;
++
++ // find this material in the properties list
++ if ( ! material_mgr.find( material, fragment.material_ptr )) {
++ FG_LOG( FG_TERRAIN, FG_ALERT,
++ "Ack! unknown usemtl name = " << material
++ << " in " << path );
++ }
++
++ // initialize the fragment transformation matrix
++ /*
++ for ( i = 0; i < 16; i++ ) {
++ fragment.matrix[i] = 0.0;
++ }
++ fragment.matrix[0] = fragment.matrix[5] =
++ fragment.matrix[10] = fragment.matrix[15] = 1.0;
++ */
++ } else {
++ // unknown comment, just gobble the input untill the
++ // end of line
++
++ in >> skipeol;
++ }
++ } else {
++ in.putback( c );
++
++ in >> token;
++
++ // cout << "token = " << token << endl;
++
++ if ( token == "vn" ) {
++ // vertex normal
++ if ( vncount < MAX_NODES ) {
++ in >> normals[vncount][0]
++ >> normals[vncount][1]
++ >> normals[vncount][2];
++ vncount++;
++ } else {
++ FG_LOG( FG_TERRAIN, FG_ALERT,
++ "Read too many vertex normals ... dying :-(" );
++ exit(-1);
++ }
++ } else if ( token == "v" ) {
++ // node (vertex)
++ if ( t->ncount < MAX_NODES ) {
++ in >> t->nodes[t->ncount][0]
++ >> t->nodes[t->ncount][1]
++ >> t->nodes[t->ncount][2];
++ t->ncount++;
++ } else {
++ FG_LOG( FG_TERRAIN, FG_ALERT,
++ "Read too many nodes ... dying :-(");
++ exit(-1);
++ }
++ } else if ( token == "t" ) {
++ // start a new triangle strip
++
++ n1 = n2 = n3 = n4 = 0;
++
++ // fgPrintf( FG_TERRAIN, FG_DEBUG,
++ // " new tri strip = %s", line);
++ in >> n1 >> n2 >> n3;
++ fragment.add_face(n1, n2, n3);
++
++ // fgPrintf( FG_TERRAIN, FG_DEBUG, "(t) = ");
++
++ xglBegin(GL_TRIANGLE_STRIP);
++ // printf("xglBegin(tristrip) %d %d %d\n", n1, n2, n3);
++
++ odd = 1;
++ // scale = 1.0;
++
++ if ( shading ) {
++ // Shading model is "GL_SMOOTH" so use precalculated
++ // (averaged) normals
++ // MAT3_SCALE_VEC(normal, normals[n1], scale);
++ xglNormal3dv(normal);
++ pp = calc_tex_coords(nodes[n1], center);
++ xglTexCoord2f(pp.lon(), pp.lat());
++ xglVertex3dv(nodes[n1]);
++
++ // MAT3_SCALE_VEC(normal, normals[n2], scale);
++ xglNormal3dv(normal);
++ pp = calc_tex_coords(nodes[n2], center);
++ xglTexCoord2f(pp.lon(), pp.lat());
++ xglVertex3dv(nodes[n2]);
++
++ // MAT3_SCALE_VEC(normal, normals[n3], scale);
++ xglNormal3dv(normal);
++ pp = calc_tex_coords(nodes[n3], center);
++ xglTexCoord2f(pp.lon(), pp.lat());
++ xglVertex3dv(nodes[n3]);
++ } else {
++ // Shading model is "GL_FLAT" so calculate per face
++ // normals on the fly.
++ if ( odd ) {
++ calc_normal(nodes[n1], nodes[n2],
++ nodes[n3], approx_normal);
++ } else {
++ calc_normal(nodes[n2], nodes[n1],
++ nodes[n3], approx_normal);
++ }
++ // MAT3_SCALE_VEC(normal, approx_normal, scale);
++ xglNormal3dv(normal);
++
++ pp = calc_tex_coords(nodes[n1], center);
++ xglTexCoord2f(pp.lon(), pp.lat());
++ xglVertex3dv(nodes[n1]);
++
++ pp = calc_tex_coords(nodes[n2], center);
++ xglTexCoord2f(pp.lon(), pp.lat());
++ xglVertex3dv(nodes[n2]);
++
++ pp = calc_tex_coords(nodes[n3], center);
++ xglTexCoord2f(pp.lon(), pp.lat());
++ xglVertex3dv(nodes[n3]);
++ }
++ // printf("some normals, texcoords, and vertices\n");
++
++ odd = 1 - odd;
++ last1 = n2;
++ last2 = n3;
++
++ // There can be three or four values
++ char c;
++ while ( in.get(c) ) {
++ if ( c == '\n' ) {
++ break; // only the one
++ }
++ if ( isdigit(c) ){
++ in.putback(c);
++ in >> n4;
++ break;
++ }
++ }
++
++ if ( n4 > 0 ) {
++ fragment.add_face(n3, n2, n4);
++
++ if ( shading ) {
++ // Shading model is "GL_SMOOTH"
++ // MAT3_SCALE_VEC(normal, normals[n4], scale);
++ } else {
++ // Shading model is "GL_FLAT"
++ calc_normal(nodes[n3], nodes[n2], nodes[n4],
++ approx_normal);
++ // MAT3_SCALE_VEC(normal, approx_normal, scale);
++ }
++ xglNormal3dv(normal);
++ pp = calc_tex_coords(nodes[n4], center);
++ xglTexCoord2f(pp.lon(), pp.lat());
++ xglVertex3dv(nodes[n4]);
++
++ odd = 1 - odd;
++ last1 = n3;
++ last2 = n4;
++ // printf("a normal, texcoord, and vertex (4th)\n");
++ }
++ } else if ( token == "tf" ) {
++ // triangle fan
++ // fgPrintf( FG_TERRAIN, FG_DEBUG, "new fan");
++
++ xglBegin(GL_TRIANGLE_FAN);
++
++ in >> n1;
++ xglNormal3dv(normals[n1]);
++ pp = calc_tex_coords(nodes[n1], center);
++ xglTexCoord2f(pp.lon(), pp.lat());
++ xglVertex3dv(nodes[n1]);
++
++ in >> n2;
++ xglNormal3dv(normals[n2]);
++ pp = calc_tex_coords(nodes[n2], center);
++ xglTexCoord2f(pp.lon(), pp.lat());
++ xglVertex3dv(nodes[n2]);
++
++ // read all subsequent numbers until next thing isn't a number
++ while ( true ) {
++ in >> skipws;
++
++ char c;
++ in.get(c);
++ in.putback(c);
++ if ( ! isdigit(c) || in.eof() ) {
++ break;
++ }
++
++ in >> n3;
++ // cout << " triangle = "
++ // << n1 << "," << n2 << "," << n3
++ // << endl;
++ xglNormal3dv(normals[n3]);
++ pp = calc_tex_coords(nodes[n3], center);
++ xglTexCoord2f(pp.lon(), pp.lat());
++ xglVertex3dv(nodes[n3]);
++
++ fragment.add_face(n1, n2, n3);
++ n2 = n3;
++ }
++
++ xglEnd();
++ } else if ( token == "f" ) {
++ // unoptimized face
++
++ if ( !in_faces ) {
++ xglBegin(GL_TRIANGLES);
++ // printf("xglBegin(triangles)\n");
++ in_faces = 1;
++ }
++
++ // fgPrintf( FG_TERRAIN, FG_DEBUG, "new triangle = %s", line);*/
++ in >> n1 >> n2 >> n3;
++ fragment.add_face(n1, n2, n3);
++
++ // xglNormal3d(normals[n1][0], normals[n1][1], normals[n1][2]);
++ xglNormal3dv(normals[n1]);
++ pp = calc_tex_coords(nodes[n1], center);
++ xglTexCoord2f(pp.lon(), pp.lat());
++ xglVertex3dv(nodes[n1]);
++
++ xglNormal3dv(normals[n2]);
++ pp = calc_tex_coords(nodes[n2], center);
++ xglTexCoord2f(pp.lon(), pp.lat());
++ xglVertex3dv(nodes[n2]);
++
++ xglNormal3dv(normals[n3]);
++ pp = calc_tex_coords(nodes[n3], center);
++ xglTexCoord2f(pp.lon(), pp.lat());
++ xglVertex3dv(nodes[n3]);
++ // printf("some normals, texcoords, and vertices (tris)\n");
++ } else if ( token == "q" ) {
++ // continue a triangle strip
++ n1 = n2 = 0;
++
++ // fgPrintf( FG_TERRAIN, FG_DEBUG, "continued tri strip = %s ",
++ // line);
++ in >> n1;
++
++ // There can be one or two values
++ char c;
++ while ( in.get(c) ) {
++ if ( c == '\n' ) {
++ break; // only the one
++ }
++
++ if ( isdigit(c) ) {
++ in.putback(c);
++ in >> n2;
++ break;
++ }
++ }
++ // fgPrintf( FG_TERRAIN, FG_DEBUG, "read %d %d\n", n1, n2);
++
++ if ( odd ) {
++ fragment.add_face(last1, last2, n1);
++ } else {
++ fragment.add_face(last2, last1, n1);
++ }
++
++ if ( shading ) {
++ // Shading model is "GL_SMOOTH"
++ // MAT3_SCALE_VEC(normal, normals[n1], scale);
++ } else {
++ // Shading model is "GL_FLAT"
++ if ( odd ) {
++ calc_normal(nodes[last1], nodes[last2], nodes[n1],
++ approx_normal);
++ } else {
++ calc_normal(nodes[last2], nodes[last1], nodes[n1],
++ approx_normal);
++ }
++ // MAT3_SCALE_VEC(normal, approx_normal, scale);
++ }
++ xglNormal3dv(normal);
++
++ pp = calc_tex_coords(nodes[n1], center);
++ xglTexCoord2f(pp.lon(), pp.lat());
++ xglVertex3dv(nodes[n1]);
++ // printf("a normal, texcoord, and vertex (4th)\n");
++
++ odd = 1 - odd;
++ last1 = last2;
++ last2 = n1;
++
++ if ( n2 > 0 ) {
++ // fgPrintf( FG_TERRAIN, FG_DEBUG, " (cont)\n");
++
++ if ( odd ) {
++ fragment.add_face(last1, last2, n2);
++ } else {
++ fragment.add_face(last2, last1, n2);
++ }
++
++ if ( shading ) {
++ // Shading model is "GL_SMOOTH"
++ // MAT3_SCALE_VEC(normal, normals[n2], scale);
++ } else {
++ // Shading model is "GL_FLAT"
++ if ( odd ) {
++ calc_normal(nodes[last1], nodes[last2],
++ nodes[n2], approx_normal);
++ } else {
++ calc_normal(nodes[last2], nodes[last1],
++ nodes[n2], approx_normal);
++ }
++ // MAT3_SCALE_VEC(normal, approx_normal, scale);
++ }
++ xglNormal3dv(normal);
++
++ pp = calc_tex_coords(nodes[n2], center);
++ xglTexCoord2f(pp.lon(), pp.lat());
++ xglVertex3dv(nodes[n2]);
++ // printf("a normal, texcoord, and vertex (4th)\n");
++
++ odd = 1 -odd;
++ last1 = last2;
++ last2 = n2;
++ }
++ } else {
++ FG_LOG( FG_TERRAIN, FG_WARN, "Unknown token in "
++ << path << " = " << token );
++ }
++
++ // eat white space before start of while loop so if we are
++ // done with useful input it is noticed before hand.
++ in >> skipws;
++ }
++ }
++
++ if ( in_fragment ) {
++ // close out the previous structure and start the next
++ xglEnd();
++ xglEndList();
++ // printf("xglEnd(); xglEndList();\n");
++
++ // update fragment
++ fragment.display_list = display_list;
++
++ // push this fragment onto the tile's object list
++ t->fragment_list.push_back(fragment);
++ }
++
++#if 0
++ // Draw normal vectors (for visually verifying normals)
++ xglBegin(GL_LINES);
++ xglColor3f(0.0, 0.0, 0.0);
++ for ( i = 0; i < t->ncount; i++ ) {
++ xglVertex3d(t->nodes[i][0],
++ t->nodes[i][1] ,
++ t->nodes[i][2]);
++ xglVertex3d(t->nodes[i][0] + 500*normals[i][0],
++ t->nodes[i][1] + 500*normals[i][1],
++ t->nodes[i][2] + 500*normals[i][2]);
++ }
++ xglEnd();
++#endif
++
++ stopwatch.stop();
++ FG_LOG( FG_TERRAIN, FG_INFO,
++ "Loaded " << path << " in "
++ << stopwatch.elapsedSeconds() << " seconds" );
++
++ return 1;
++}
++
++
++// $Log$
++// Revision 1.15 1999/03/31 13:25:58 curt
++// Removed some debugging output.
++//
++// Revision 1.14 1999/03/30 23:48:24 curt
++// modifications to obj loader to handle tri fans.
++//
++// Revision 1.13 1999/03/27 05:36:03 curt
++// Alas, I have made non-backwardsly compatible changes to the scenery file
++// format. Thus I have had to make the corresponding changes here in the
++// file loader.
++// Things that do not correspond the the .obj format are placed in comments.
++//
++// Revision 1.12 1999/03/02 01:03:25 curt
++// Tweaks for building with native SGI compilers.
++//
++// Revision 1.11 1999/02/26 22:09:59 curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.10 1998/11/06 21:18:18 curt
++// Converted to new logstream debugging facility. This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.9 1998/11/06 14:47:06 curt
++// Changes to track Bernie's updates to fgstream.
++//
++// Revision 1.8 1998/10/20 18:33:55 curt
++// Tweaked texture coordinates, but we still have some problems. :-(
++//
++// Revision 1.7 1998/10/20 15:48:44 curt
++// Removed an extraneous output message.
++//
++// Revision 1.6 1998/10/18 01:17:21 curt
++// Point3D tweaks.
++//
++// Revision 1.5 1998/10/16 00:54:39 curt
++// Converted to Point3D class.
++//
++// Revision 1.4 1998/09/15 01:35:07 curt
++// cleaned up my fragment.num_faces hack :-) to use the STL (no need in
++// duplicating work.)
++// Tweaked fgTileMgrRender() do not calc tile matrix unless necessary.
++// removed some unneeded stuff from fgTileMgrCurElev()
++//
++// Revision 1.3 1998/09/03 21:27:03 curt
++// Fixed a serious bug caused by not-quite-correct comment/white space eating
++// which resulted in mismatched glBegin() glEnd() pairs, incorrect display lists,
++// and ugly display artifacts.
++//
++// Revision 1.2 1998/09/01 19:03:09 curt
++// Changes contributed by Bernie Bright <bbright@c031.aone.net.au>
++// - The new classes in libmisc.tgz define a stream interface into zlib.
++// I've put these in a new directory, Lib/Misc. Feel free to rename it
++// to something more appropriate. However you'll have to change the
++// include directives in all the other files. Additionally you'll have
++// add the library to Lib/Makefile.am and Simulator/Main/Makefile.am.
++//
++// The StopWatch class in Lib/Misc requires a HAVE_GETRUSAGE autoconf
++// test so I've included the required changes in config.tgz.
++//
++// There are a fair few changes to Simulator/Objects as I've moved
++// things around. Loading tiles is quicker but thats not where the delay
++// is. Tile loading takes a few tenths of a second per file on a P200
++// but it seems to be the post-processing that leads to a noticeable
++// blip in framerate. I suppose its time to start profiling to see where
++// the delays are.
++//
++// I've included a brief description of each archives contents.
++//
++// Lib/Misc/
++// zfstream.cxx
++// zfstream.hxx
++// C++ stream interface into zlib.
++// Taken from zlib-1.1.3/contrib/iostream/.
++// Minor mods for STL compatibility.
++// There's no copyright associated with these so I assume they're
++// covered by zlib's.
++//
++// fgstream.cxx
++// fgstream.hxx
++// FlightGear input stream using gz_ifstream. Tries to open the
++// given filename. If that fails then filename is examined and a
++// ".gz" suffix is removed or appended and that file is opened.
++//
++// stopwatch.hxx
++// A simple timer for benchmarking. Not used in production code.
++// Taken from the Blitz++ project. Covered by GPL.
++//
++// strutils.cxx
++// strutils.hxx
++// Some simple string manipulation routines.
++//
++// Simulator/Airports/
++// Load airports database using fgstream.
++// Changed fgAIRPORTS to use set<> instead of map<>.
++// Added bool fgAIRPORTS::search() as a neater way doing the lookup.
++// Returns true if found.
++//
++// Simulator/Astro/
++// Modified fgStarsInit() to load stars database using fgstream.
++//
++// Simulator/Objects/
++// Modified fgObjLoad() to use fgstream.
++// Modified fgMATERIAL_MGR::load_lib() to use fgstream.
++// Many changes to fgMATERIAL.
++// Some changes to fgFRAGMENT but I forget what!
++//
++// Revision 1.1 1998/08/25 16:51:25 curt
++// Moved from ../Scenery
++//
++// Revision 1.23 1998/08/20 15:16:43 curt
++// obj.cxx: use more explicit parenthases.
++// texload.[ch]: use const in function definitions where appropriate.
++//
++// Revision 1.22 1998/08/20 15:12:03 curt
++// Used a forward declaration of classes fgTILE and fgMATERIAL to eliminate
++// the need for "void" pointers and casts.
++// Quick hack to count the number of scenery polygons that are being drawn.
++//
++// Revision 1.21 1998/08/12 21:13:04 curt
++// material.cxx: don't load textures if they are disabled
++// obj.cxx: optimizations from Norman Vine
++// tile.cxx: minor tweaks
++// tile.hxx: addition of num_faces
++// tilemgr.cxx: minor tweaks
++//
++// Revision 1.20 1998/07/24 21:42:07 curt
++// material.cxx: whups, double method declaration with no definition.
++// obj.cxx: tweaks to avoid errors in SGI's CC.
++// tile.cxx: optimizations by Norman Vine.
++// tilemgr.cxx: optimizations by Norman Vine.
++//
++// Revision 1.19 1998/07/13 21:01:58 curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.18 1998/07/12 03:18:27 curt
++// Added ground collision detection. This involved:
++// - saving the entire vertex list for each tile with the tile records.
++// - saving the face list for each fragment with the fragment records.
++// - code to intersect the current vertical line with the proper face in
++// an efficient manner as possible.
++// Fixed a bug where the tiles weren't being shifted to "near" (0,0,0)
++//
++// Revision 1.17 1998/07/08 14:47:21 curt
++// Fix GL_MODULATE vs. GL_DECAL problem introduced by splash screen.
++// polare3d.h renamed to polar3d.hxx
++// fg{Cartesian,Polar}Point3d consolodated.
++// Added some initial support for calculating local current ground elevation.
++//
++// Revision 1.16 1998/07/06 21:34:33 curt
++// Added using namespace std for compilers that support this.
++//
++// Revision 1.15 1998/07/04 00:54:28 curt
++// Added automatic mipmap generation.
++//
++// When rendering fragments, use saved model view matrix from associated tile
++// rather than recalculating it with push() translate() pop().
++//
++// Revision 1.14 1998/06/17 21:36:40 curt
++// Load and manage multiple textures defined in the Materials library.
++// Boost max material fagments for each material property to 800.
++// Multiple texture support when rendering.
++//
++// Revision 1.13 1998/06/12 00:58:05 curt
++// Build only static libraries.
++// Declare memmove/memset for Sloaris.
++//
++// Revision 1.12 1998/06/08 17:57:54 curt
++// Working first pass at material proporty sorting.
++//
++// Revision 1.11 1998/06/06 01:09:31 curt
++// I goofed on the log message in the last commit ... now fixed.
++//
++// Revision 1.10 1998/06/06 01:07:17 curt
++// Increased per material fragment list size from 100 to 400.
++// Now correctly draw viewable fragments in per material order.
++//
++// Revision 1.9 1998/06/05 22:39:54 curt
++// Working on sorting by, and rendering by material properties.
++//
++// Revision 1.8 1998/06/05 18:19:18 curt
++// Recognize file, file.gz, and file.obj as scenery object files.
++//
++// Revision 1.7 1998/05/24 02:49:09 curt
++// Implimented fragment level view frustum culling.
++//
++// Revision 1.6 1998/05/23 14:09:20 curt
++// Added tile.cxx and tile.hxx.
++// Working on rewriting the tile management system so a tile is just a list
++// fragments, and the fragment record contains the display list for that
++// fragment.
++//
++// Revision 1.5 1998/05/20 20:53:53 curt
++// Moved global ref point and radius (bounding sphere info, and offset) to
++// data file rather than calculating it on the fly.
++// Fixed polygon winding problem in scenery generation stage rather than
++// compensating for it on the fly.
++// Made a fgTILECACHE class.
++//
++// Revision 1.4 1998/05/16 13:09:57 curt
++// Beginning to add support for view frustum culling.
++// Added some temporary code to calculate bouding radius, until the
++// scenery generation tools and scenery can be updated.
++//
++// Revision 1.3 1998/05/03 00:48:01 curt
++// Updated texture coordinate fmod() parameter.
++//
++// Revision 1.2 1998/05/02 01:52:14 curt
++// Playing around with texture coordinates.
++//
++// Revision 1.1 1998/04/30 12:35:28 curt
++// Added a command line rendering option specify smooth/flat shading.
++//
++// Revision 1.35 1998/04/28 21:43:26 curt
++// Wrapped zlib calls up so we can conditionally comment out zlib support.
++//
++// Revision 1.34 1998/04/28 01:21:42 curt
++// Tweaked texture parameter calculations to keep the number smaller. This
++// avoids the "swimming" problem.
++// Type-ified fgTIME and fgVIEW.
++//
++// Revision 1.33 1998/04/27 15:58:15 curt
++// Screwing around with texture coordinate generation ... still needs work.
++//
++// Revision 1.32 1998/04/27 03:30:13 curt
++// Minor transformation adjustments to try to keep scenery tiles closer to
++// (0, 0, 0) GLfloats run out of precision at the distances we need to model
++// the earth, but we can do a bunch of pre-transformations using double math
++// and then cast to GLfloat once everything is close in where we have less
++// precision problems.
++//
++// Revision 1.31 1998/04/25 15:09:57 curt
++// Changed "r" to "rb" in gzopen() options. This fixes bad behavior in win32.
++//
++// Revision 1.30 1998/04/24 14:21:08 curt
++// Added "file.obj.gz" support.
++//
++// Revision 1.29 1998/04/24 00:51:07 curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Tweaked the scenery file extentions to be "file.obj" (uncompressed)
++// or "file.obz" (compressed.)
++//
++// Revision 1.28 1998/04/22 13:22:44 curt
++// C++ - ifing the code a bit.
++//
++// Revision 1.27 1998/04/18 04:13:17 curt
++// Added zlib on the fly decompression support for loading scenery objects.
++//
++// Revision 1.26 1998/04/03 22:11:36 curt
++// Converting to Gnu autoconf system.
++//
++// Revision 1.25 1998/03/14 00:30:50 curt
++// Beginning initial terrain texturing experiments.
++//
++// Revision 1.24 1998/02/09 21:30:18 curt
++// Fixed a nagging problem with terrain tiles not "quite" matching up perfectly.
++//
++// Revision 1.23 1998/02/09 15:07:52 curt
++// Minor tweaks.
++//
++// Revision 1.22 1998/02/01 03:39:54 curt
++// Minor tweaks.
++//
++// Revision 1.21 1998/01/31 00:43:25 curt
++// Added MetroWorks patches from Carmen Volpe.
++//
++// Revision 1.20 1998/01/29 00:51:39 curt
++// First pass at tile cache, dynamic tile loading and tile unloading now works.
++//
++// Revision 1.19 1998/01/27 03:26:42 curt
++// Playing with new fgPrintf command.
++//
++// Revision 1.18 1998/01/19 19:27:16 curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.17 1998/01/13 00:23:10 curt
++// Initial changes to support loading and management of scenery tiles. Note,
++// there's still a fair amount of work left to be done.
++//
++// Revision 1.16 1997/12/30 23:09:40 curt
++// Worked on winding problem without luck, so back to calling glFrontFace()
++// 3 times for each scenery area.
++//
++// Revision 1.15 1997/12/30 20:47:51 curt
++// Integrated new event manager with subsystem initializations.
++//
++// Revision 1.14 1997/12/30 01:38:46 curt
++// Switched back to per vertex normals and smooth shading for terrain.
++//
++// Revision 1.13 1997/12/18 23:32:36 curt
++// First stab at sky dome actually starting to look reasonable. :-)
++//
++// Revision 1.12 1997/12/17 23:13:47 curt
++// Began working on rendering the sky.
++//
++// Revision 1.11 1997/12/15 23:55:01 curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.10 1997/12/12 21:41:28 curt
++// More light/material property tweaking ... still a ways off.
++//
++// Revision 1.9 1997/12/12 19:52:57 curt
++// Working on lightling and material properties.
++//
++// Revision 1.8 1997/12/10 01:19:51 curt
++// Tweaks for verion 0.15 release.
++//
++// Revision 1.7 1997/12/08 22:51:17 curt
++// Enhanced to handle ccw and cw tri-stripe winding. This is a temporary
++// admission of defeat. I will eventually go back and get all the stripes
++// wound the same way (ccw).
++//
++// Revision 1.6 1997/11/25 19:25:35 curt
++// Changes to integrate Durk's moon/sun code updates + clean up.
++//
++// Revision 1.5 1997/11/15 18:16:39 curt
++// minor tweaks.
++//
++// Revision 1.4 1997/11/14 00:26:49 curt
++// Transform scenery coordinates earlier in pipeline when scenery is being
++// created, not when it is being loaded. Precalculate normals for each node
++// as average of the normals of each containing polygon so Garoude shading is
++// now supportable.
++//
++// Revision 1.3 1997/10/31 04:49:12 curt
++// Tweaking vertex orders.
++//
++// Revision 1.2 1997/10/30 12:38:45 curt
++// Working on new scenery subsystem.
++//
++// Revision 1.1 1997/10/28 21:14:54 curt
++// Initial revision.
++
++
--- /dev/null
--- /dev/null
++// obj.hxx -- routines to handle WaveFront .obj-ish format files.
++//
++// Written by Curtis Olson, started October 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$
++// (Log is kept at end of this file)
++
++
++#ifndef _OBJ_HXX
++#define _OBJ_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++
++#include <GL/glut.h>
++
++#include <string>
++
++#include <Scenery/tile.hxx>
++
++
++// Load a .obj file and build the GL fragment list
++int fgObjLoad(const string& path, fgTILE *tile);
++
++
++#endif // _OBJ_HXX
++
++
++// $Log$
++// Revision 1.3 1998/10/16 00:54:41 curt
++// Converted to Point3D class.
++//
++// Revision 1.2 1998/09/01 19:03:10 curt
++// Changes contributed by Bernie Bright <bbright@c031.aone.net.au>
++// - The new classes in libmisc.tgz define a stream interface into zlib.
++// I've put these in a new directory, Lib/Misc. Feel free to rename it
++// to something more appropriate. However you'll have to change the
++// include directives in all the other files. Additionally you'll have
++// add the library to Lib/Makefile.am and Simulator/Main/Makefile.am.
++//
++// The StopWatch class in Lib/Misc requires a HAVE_GETRUSAGE autoconf
++// test so I've included the required changes in config.tgz.
++//
++// There are a fair few changes to Simulator/Objects as I've moved
++// things around. Loading tiles is quicker but thats not where the delay
++// is. Tile loading takes a few tenths of a second per file on a P200
++// but it seems to be the post-processing that leads to a noticeable
++// blip in framerate. I suppose its time to start profiling to see where
++// the delays are.
++//
++// I've included a brief description of each archives contents.
++//
++// Lib/Misc/
++// zfstream.cxx
++// zfstream.hxx
++// C++ stream interface into zlib.
++// Taken from zlib-1.1.3/contrib/iostream/.
++// Minor mods for STL compatibility.
++// There's no copyright associated with these so I assume they're
++// covered by zlib's.
++//
++// fgstream.cxx
++// fgstream.hxx
++// FlightGear input stream using gz_ifstream. Tries to open the
++// given filename. If that fails then filename is examined and a
++// ".gz" suffix is removed or appended and that file is opened.
++//
++// stopwatch.hxx
++// A simple timer for benchmarking. Not used in production code.
++// Taken from the Blitz++ project. Covered by GPL.
++//
++// strutils.cxx
++// strutils.hxx
++// Some simple string manipulation routines.
++//
++// Simulator/Airports/
++// Load airports database using fgstream.
++// Changed fgAIRPORTS to use set<> instead of map<>.
++// Added bool fgAIRPORTS::search() as a neater way doing the lookup.
++// Returns true if found.
++//
++// Simulator/Astro/
++// Modified fgStarsInit() to load stars database using fgstream.
++//
++// Simulator/Objects/
++// Modified fgObjLoad() to use fgstream.
++// Modified fgMATERIAL_MGR::load_lib() to use fgstream.
++// Many changes to fgMATERIAL.
++// Some changes to fgFRAGMENT but I forget what!
++//
++// Revision 1.1 1998/08/25 16:51:26 curt
++// Moved from ../Scenery
++//
++// Revision 1.4 1998/05/24 02:49:10 curt
++// Implimented fragment level view frustum culling.
++//
++// Revision 1.3 1998/05/23 14:09:21 curt
++// Added tile.cxx and tile.hxx.
++// Working on rewriting the tile management system so a tile is just a list
++// fragments, and the fragment record contains the display list for that
++// fragment.
++//
++// Revision 1.2 1998/05/02 01:52:15 curt
++// Playing around with texture coordinates.
++//
++// Revision 1.1 1998/04/30 12:35:29 curt
++// Added a command line rendering option specify smooth/flat shading.
++//
++// Revision 1.11 1998/04/25 22:06:31 curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.10 1998/04/24 00:51:07 curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Tweaked the scenery file extentions to be "file.obj" (uncompressed)
++// or "file.obz" (compressed.)
++//
++// Revision 1.9 1998/04/22 13:22:45 curt
++// C++ - ifing the code a bit.
++//
++// Revision 1.8 1998/04/21 17:02:43 curt
++// Prepairing for C++ integration.
++//
++// Revision 1.7 1998/04/03 22:11:37 curt
++// Converting to Gnu autoconf system.
++//
++// Revision 1.6 1998/01/31 00:43:25 curt
++// Added MetroWorks patches from Carmen Volpe.
++//
++// Revision 1.5 1998/01/27 00:48:03 curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.4 1998/01/22 02:59:41 curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.3 1998/01/19 19:27:17 curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.2 1998/01/13 00:23:10 curt
++// Initial changes to support loading and management of scenery tiles. Note,
++// there's still a fair amount of work left to be done.
++//
++// Revision 1.1 1997/10/28 21:14:55 curt
++// Initial revision.
++
--- /dev/null
--- /dev/null
++
++/* texture.c - by David Blythe, SGI */
++
++/* texload is a simplistic routine for reading an SGI .rgb image file. */
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++
++#include <Include/fg_zlib.h>
++
++#include "texload.h"
++
++typedef struct _ImageRec {
++ unsigned short imagic;
++ unsigned short type;
++ unsigned short dim;
++ unsigned short xsize, ysize, zsize;
++ unsigned int min, max;
++ unsigned int wasteBytes;
++ char name[80];
++ unsigned long colorMap;
++ fgFile file;
++ unsigned char *tmp;
++ unsigned long rleEnd;
++ unsigned int *rowStart;
++ int *rowSize;
++} ImageRec;
++
++void
++rgbtorgb(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *l,int n) {
++ while(n--) {
++ l[0] = r[0];
++ l[1] = g[0];
++ l[2] = b[0];
++ l += 3; r++; g++; b++;
++ }
++}
++
++static void
++ConvertShort(unsigned short *array, unsigned int length) {
++ unsigned short b1, b2;
++ unsigned char *ptr;
++
++ ptr = (unsigned char *)array;
++ while (length--) {
++ b1 = *ptr++;
++ b2 = *ptr++;
++ *array++ = (b1 << 8) | (b2);
++ }
++}
++
++static void
++ConvertUint(unsigned *array, unsigned int length) {
++ unsigned int b1, b2, b3, b4;
++ unsigned char *ptr;
++
++ ptr = (unsigned char *)array;
++ while (length--) {
++ b1 = *ptr++;
++ b2 = *ptr++;
++ b3 = *ptr++;
++ b4 = *ptr++;
++ *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
++ }
++}
++
++static ImageRec *ImageOpen(const char *fileName)
++{
++ union {
++ int testWord;
++ char testByte[4];
++ } endianTest;
++
++ ImageRec *image;
++ int swapFlag;
++ int x;
++
++ endianTest.testWord = 1;
++ if (endianTest.testByte[0] == 1) {
++ swapFlag = 1;
++ } else {
++ swapFlag = 0;
++ }
++
++ image = (ImageRec *)malloc(sizeof(ImageRec));
++ if (image == NULL) {
++ fprintf(stderr, "Out of memory!\n");
++ exit(1);
++ }
++ if ((image->file = fgopen(fileName, "rb")) == NULL) {
++ return NULL;
++ }
++
++ // fread(image, 1, 12, image->file);
++ fgread(image->file, image, 12);
++
++ if (swapFlag) {
++ ConvertShort(&image->imagic, 6);
++ }
++
++ image->tmp = (unsigned char *)malloc(image->xsize*256);
++ if (image->tmp == NULL) {
++ fprintf(stderr, "\nOut of memory!\n");
++ exit(1);
++ }
++
++ if ((image->type & 0xFF00) == 0x0100) {
++ x = image->ysize * image->zsize * (int) sizeof(unsigned);
++ image->rowStart = (unsigned *)malloc(x);
++ image->rowSize = (int *)malloc(x);
++ if (image->rowStart == NULL || image->rowSize == NULL) {
++ fprintf(stderr, "\nOut of memory!\n");
++ exit(1);
++ }
++ image->rleEnd = 512 + (2 * x);
++ fgseek(image->file, 512, SEEK_SET);
++ // fread(image->rowStart, 1, x, image->file);
++ fgread(image->file, image->rowStart, x);
++ // fread(image->rowSize, 1, x, image->file);
++ fgread(image->file, image->rowSize, x);
++ if (swapFlag) {
++ ConvertUint(image->rowStart, x/(int) sizeof(unsigned));
++ ConvertUint((unsigned *)image->rowSize, x/(int) sizeof(int));
++ }
++ }
++ return image;
++}
++
++static void
++ImageClose(ImageRec *image) {
++ fgclose(image->file);
++ free(image->tmp);
++ free(image);
++}
++
++static void
++ImageGetRow(ImageRec *image, unsigned char *buf, int y, int z) {
++ unsigned char *iPtr, *oPtr, pixel;
++ int count;
++
++ if ((image->type & 0xFF00) == 0x0100) {
++ fgseek(image->file, (long) image->rowStart[y+z*image->ysize], SEEK_SET);
++ // fread(image->tmp, 1, (unsigned int)image->rowSize[y+z*image->ysize],
++ // image->file);
++ fgread(image->file, image->tmp,
++ (unsigned int)image->rowSize[y+z*image->ysize]);
++
++ iPtr = image->tmp;
++ oPtr = buf;
++ for (;;) {
++ pixel = *iPtr++;
++ count = (int)(pixel & 0x7F);
++ if (!count) {
++ return;
++ }
++ if (pixel & 0x80) {
++ while (count--) {
++ *oPtr++ = *iPtr++;
++ }
++ } else {
++ pixel = *iPtr++;
++ while (count--) {
++ *oPtr++ = pixel;
++ }
++ }
++ }
++ } else {
++ fgseek(image->file, 512+(y*image->xsize)+(z*image->xsize*image->ysize),
++ SEEK_SET);
++ // fread(buf, 1, image->xsize, image->file);
++ fgread(image->file, buf, image->xsize);
++ }
++}
++
++GLubyte *
++read_alpha_texture(const char *name, int *width, int *height)
++{
++ unsigned char *base, *lptr;
++ ImageRec *image;
++ int y;
++
++ image = ImageOpen(name);
++ if(!image) {
++ return NULL;
++ }
++
++ (*width)=image->xsize;
++ (*height)=image->ysize;
++
++ printf("image->zsize = %d\n", image->zsize);
++
++ if (image->zsize != 1) {
++ ImageClose(image);
++ return NULL;
++ }
++
++ base = (unsigned char *)malloc(image->xsize*image->ysize*sizeof(unsigned char));
++ lptr = base;
++ for(y=0; y<image->ysize; y++) {
++ ImageGetRow(image,lptr,y,0);
++ lptr += image->xsize;
++ }
++ ImageClose(image);
++
++ return (unsigned char *) base;
++}
++
++GLubyte *
++read_rgb_texture(const char *name, int *width, int *height)
++{
++ unsigned char *base, *ptr;
++ unsigned char *rbuf, *gbuf, *bbuf, *abuf;
++ ImageRec *image;
++ int y;
++
++ image = ImageOpen(name);
++
++ if(!image)
++ return NULL;
++ (*width)=image->xsize;
++ (*height)=image->ysize;
++ if (image->zsize != 3 && image->zsize != 4) {
++ ImageClose(image);
++ return NULL;
++ }
++
++ base = (unsigned char*)malloc(image->xsize*image->ysize*sizeof(unsigned int)*3);
++ rbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
++ gbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
++ bbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
++ abuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
++ if(!base || !rbuf || !gbuf || !bbuf || !abuf) {
++ if (base) free(base);
++ if (rbuf) free(rbuf);
++ if (gbuf) free(gbuf);
++ if (bbuf) free(bbuf);
++ if (abuf) free(abuf);
++ return NULL;
++ }
++ ptr = base;
++ for(y=0; y<image->ysize; y++) {
++ if(image->zsize == 4) {
++ ImageGetRow(image,rbuf,y,0);
++ ImageGetRow(image,gbuf,y,1);
++ ImageGetRow(image,bbuf,y,2);
++ ImageGetRow(image,abuf,y,3); /* Discard. */
++ rgbtorgb(rbuf,gbuf,bbuf,ptr,image->xsize);
++ ptr += (image->xsize * 3);
++ } else {
++ ImageGetRow(image,rbuf,y,0);
++ ImageGetRow(image,gbuf,y,1);
++ ImageGetRow(image,bbuf,y,2);
++ rgbtorgb(rbuf,gbuf,bbuf,ptr,image->xsize);
++ ptr += (image->xsize * 3);
++ }
++ }
++ ImageClose(image);
++ free(rbuf);
++ free(gbuf);
++ free(bbuf);
++ free(abuf);
++
++ return (GLubyte *) base;
++}
--- /dev/null
--- /dev/null
++
++/* Copyright (c) Mark J. Kilgard, 1997. */
++
++/* This program is freely distributable without licensing fees
++ and is provided without guarantee or warrantee expressed or
++ implied. This program is -not- in the public domain. */
++
++
++#ifndef _TEXLOAD_H
++#define _TEXLOAD_H
++
++
++#include <GL/glut.h>
++
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++
++extern GLubyte *read_alpha_texture(const char *name, int *width, int *height);
++extern GLubyte * read_rgb_texture(const char *name, int *width, int *height);
++
++
++#ifdef __cplusplus
++}
++#endif
++
++
++#endif /* _TEXLOAD_H */
--- /dev/null
--- /dev/null
++noinst_LIBRARIES = libScenery.a
++
++libScenery_a_SOURCES = \
++ scenery.cxx scenery.hxx \
++ tile.cxx tile.hxx \
++ tilecache.cxx tilecache.hxx \
++ tilemgr.cxx tilemgr.hxx
++
++INCLUDES += \
++ -I$(top_builddir) \
++ -I$(top_builddir)/Lib \
++ -I$(top_builddir)/Simulator
--- /dev/null
--- /dev/null
++// scenery.cxx -- data structures and routines for managing scenery.
++//
++// Written by Curtis Olson, started May 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$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#include <stdio.h>
++#include <string.h>
++
++#include <Debug/logstream.hxx>
++#include <Main/options.hxx>
++
++// #include "obj.hxx"
++#include "scenery.hxx"
++// #include "texload.h"
++
++
++// Temporary hack until we get a better texture management system running
++GLint area_texture;
++
++
++// Shared structure to hold current scenery parameters
++struct fgSCENERY scenery;
++
++
++// Initialize the Scenery Management system
++int fgSceneryInit( void ) {
++ fgOPTIONS *o;
++ // char path[1024], fgpath[1024];
++ // GLubyte *texbuf;
++ // int width, height;
++
++ o = ¤t_options;
++
++ FG_LOG( FG_TERRAIN, FG_INFO, "Initializing scenery subsystem" );
++
++ scenery.cur_elev = -9999;
++
++ return(1);
++}
++
++
++// Tell the scenery manager where we are so it can load the proper data, and
++// build the proper structures.
++void fgSceneryUpdate(double lon, double lat, double elev) {
++ // does nothing;
++}
++
++
++// Render out the current scene
++void fgSceneryRender( void ) {
++}
++
++
++// $Log$
++// Revision 1.10 1998/11/06 21:18:20 curt
++// Converted to new logstream debugging facility. This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.9 1998/10/16 23:27:57 curt
++// C++-ifying.
++//
++// Revision 1.8 1998/08/25 16:52:40 curt
++// material.cxx material.hxx obj.cxx obj.hxx texload.c texload.h moved to
++// ../Objects
++//
++// Revision 1.7 1998/07/13 21:01:59 curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.6 1998/07/12 03:18:27 curt
++// Added ground collision detection. This involved:
++// - saving the entire vertex list for each tile with the tile records.
++// - saving the face list for each fragment with the fragment records.
++// - code to intersect the current vertical line with the proper face in
++// an efficient manner as possible.
++// Fixed a bug where the tiles weren't being shifted to "near" (0,0,0)
++//
++// Revision 1.5 1998/06/17 21:36:41 curt
++// Load and manage multiple textures defined in the Materials library.
++// Boost max material fagments for each material property to 800.
++// Multiple texture support when rendering.
++//
++// Revision 1.4 1998/05/13 18:26:40 curt
++// Root path info moved to fgOPTIONS.
++//
++// Revision 1.3 1998/05/07 23:15:20 curt
++// Fixed a glTexImage2D() usage bug where width and height were mis-swapped.
++// Added support for --tile-radius=n option.
++//
++// Revision 1.2 1998/05/02 01:52:16 curt
++// Playing around with texture coordinates.
++//
++// Revision 1.1 1998/04/30 12:35:30 curt
++// Added a command line rendering option specify smooth/flat shading.
++//
++// Revision 1.42 1998/04/28 21:43:27 curt
++// Wrapped zlib calls up so we can conditionally comment out zlib support.
++//
++// Revision 1.41 1998/04/24 00:51:08 curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Tweaked the scenery file extentions to be "file.obj" (uncompressed)
++// or "file.obz" (compressed.)
++//
++// Revision 1.40 1998/04/18 04:14:06 curt
++// Moved fg_debug.c to it's own library.
++//
++// Revision 1.39 1998/04/08 23:30:07 curt
++// Adopted Gnu automake/autoconf system.
++//
++// Revision 1.38 1998/04/03 22:11:37 curt
++// Converting to Gnu autoconf system.
++//
++// Revision 1.37 1998/03/23 21:23:05 curt
++// Debugging output tweaks.
++//
++// Revision 1.36 1998/03/14 00:30:50 curt
++// Beginning initial terrain texturing experiments.
++//
++// Revision 1.35 1998/01/31 00:43:26 curt
++// Added MetroWorks patches from Carmen Volpe.
++//
++// Revision 1.34 1998/01/27 03:26:43 curt
++// Playing with new fgPrintf command.
++//
++// Revision 1.33 1998/01/19 19:27:17 curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.32 1998/01/19 18:40:37 curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.31 1998/01/13 00:23:11 curt
++// Initial changes to support loading and management of scenery tiles. Note,
++// there's still a fair amount of work left to be done.
++//
++// Revision 1.30 1998/01/07 03:22:29 curt
++// Moved astro stuff to .../Src/Astro/
++//
++// Revision 1.29 1997/12/30 20:47:52 curt
++// Integrated new event manager with subsystem initializations.
++//
++// Revision 1.28 1997/12/15 23:55:02 curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.27 1997/12/12 21:41:30 curt
++// More light/material property tweaking ... still a ways off.
++//
++// Revision 1.26 1997/12/12 19:52:58 curt
++// Working on lightling and material properties.
++//
++// Revision 1.25 1997/12/10 22:37:51 curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.24 1997/12/08 22:51:18 curt
++// Enhanced to handle ccw and cw tri-stripe winding. This is a temporary
++// admission of defeat. I will eventually go back and get all the stripes
++// wound the same way (ccw).
++//
++// Revision 1.23 1997/11/25 19:25:37 curt
++// Changes to integrate Durk's moon/sun code updates + clean up.
++//
++// Revision 1.22 1997/10/28 21:00:22 curt
++// Changing to new terrain format.
++//
++// Revision 1.21 1997/10/25 03:24:24 curt
++// Incorporated sun, moon, and star positioning code contributed by Durk Talsma.
++//
++// Revision 1.20 1997/10/25 03:18:27 curt
++// Incorporated sun, moon, and planet position and rendering code contributed
++// by Durk Talsma.
++//
++// Revision 1.19 1997/09/05 14:17:30 curt
++// More tweaking with stars.
++//
++// Revision 1.18 1997/09/05 01:35:59 curt
++// Working on getting stars right.
++//
++// Revision 1.17 1997/08/29 17:55:27 curt
++// Worked on properly aligning the stars.
++//
++// Revision 1.16 1997/08/27 21:32:29 curt
++// Restructured view calculation code. Added stars.
++//
++// Revision 1.15 1997/08/27 03:30:32 curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.14 1997/08/25 20:27:24 curt
++// Merged in initial HUD and Joystick code.
++//
++// Revision 1.13 1997/08/22 21:34:41 curt
++// Doing a bit of reorganizing and house cleaning.
++//
++// Revision 1.12 1997/08/19 23:55:08 curt
++// Worked on better simulating real lighting.
++//
++// Revision 1.11 1997/08/13 20:24:22 curt
++// Changed default detail level.
++//
++// Revision 1.10 1997/08/06 00:24:30 curt
++// Working on correct real time sun lighting.
++//
++// Revision 1.9 1997/08/04 17:08:11 curt
++// Testing cvs on IRIX 6.x
++//
++// Revision 1.8 1997/07/18 23:41:27 curt
++// Tweaks for building with Cygnus Win32 compiler.
++//
++// Revision 1.7 1997/07/16 20:04:52 curt
++// Minor tweaks to aid Win32 port.
++//
++// Revision 1.6 1997/07/14 16:26:05 curt
++// Testing/playing -- placed objects randomly across the entire terrain.
++//
++// Revision 1.5 1997/07/11 03:23:19 curt
++// Solved some scenery display/orientation problems. Still have a positioning
++// (or transformation?) problem.
++//
++// Revision 1.4 1997/07/11 01:30:03 curt
++// More tweaking of terrian floor.
++//
++// Revision 1.3 1997/06/29 21:16:50 curt
++// More twiddling with the Scenery Management system.
++//
++// Revision 1.2 1997/06/27 20:03:37 curt
++// Working on Makefile structure.
++//
++// Revision 1.1 1997/06/27 02:26:30 curt
++// Initial revision.
++//
--- /dev/null
--- /dev/null
++// scenery.hxx -- data structures and routines for managing scenery.
++//
++// Written by Curtis Olson, started May 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$
++// (Log is kept at end of this file)
++
++
++#ifndef _SCENERY_HXX
++#define _SCENERY_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++
++#include <Math/point3d.hxx>
++
++
++// Define a structure containing global scenery parameters
++struct fgSCENERY {
++ // center of current scenery chunk
++ Point3D center;
++
++ // next center of current scenery chunk
++ Point3D next_center;
++
++ // angle of sun relative to current local horizontal
++ double sun_angle;
++
++ // elevation of terrain at our current lat/lon (based on the
++ // actual drawn polygons)
++ double cur_elev;
++};
++
++extern struct fgSCENERY scenery;
++
++
++// Initialize the Scenery Management system
++int fgSceneryInit( void );
++
++
++// Tell the scenery manager where we are so it can load the proper
++// data, and build the proper structures.
++void fgSceneryUpdate(double lon, double lat, double elev);
++
++
++// Render out the current scene
++void fgSceneryRender( void );
++
++
++#endif // _SCENERY_HXX
++
++
++// $Log$
++// Revision 1.6 1998/10/16 23:27:59 curt
++// C++-ifying.
++//
++// Revision 1.5 1998/10/16 00:55:44 curt
++// Converted to Point3D class.
++//
++// Revision 1.4 1998/07/12 03:18:28 curt
++// Added ground collision detection. This involved:
++// - saving the entire vertex list for each tile with the tile records.
++// - saving the face list for each fragment with the fragment records.
++// - code to intersect the current vertical line with the proper face in
++// an efficient manner as possible.
++// Fixed a bug where the tiles weren't being shifted to "near" (0,0,0)
++//
++// Revision 1.3 1998/07/08 14:47:22 curt
++// Fix GL_MODULATE vs. GL_DECAL problem introduced by splash screen.
++// polare3d.h renamed to polar3d.hxx
++// fg{Cartesian,Polar}Point3d consolodated.
++// Added some initial support for calculating local current ground elevation.
++//
++// Revision 1.2 1998/05/02 01:52:16 curt
++// Playing around with texture coordinates.
++//
++// Revision 1.1 1998/04/30 12:35:31 curt
++// Added a command line rendering option specify smooth/flat shading.
++//
++// Revision 1.21 1998/04/25 22:06:31 curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.20 1998/04/22 13:22:45 curt
++// C++ - ifing the code a bit.
++//
++// Revision 1.19 1998/04/21 17:02:43 curt
++// Prepairing for C++ integration.
++//
++// Revision 1.18 1998/03/14 00:30:51 curt
++// Beginning initial terrain texturing experiments.
++//
++// Revision 1.17 1998/02/20 00:16:24 curt
++// Thursday's tweaks.
++//
++// Revision 1.16 1998/01/27 00:48:03 curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.15 1998/01/22 02:59:41 curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.14 1998/01/19 19:27:17 curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.13 1998/01/19 18:40:38 curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.12 1997/12/15 23:55:03 curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.11 1997/12/10 22:37:52 curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.10 1997/09/04 02:17:37 curt
++// Shufflin' stuff.
++//
++// Revision 1.9 1997/08/27 03:30:33 curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.8 1997/08/06 00:24:30 curt
++// Working on correct real time sun lighting.
++//
++// Revision 1.7 1997/07/23 21:52:27 curt
++// Put comments around the text after an #endif for increased portability.
++//
++// Revision 1.6 1997/07/11 01:30:03 curt
++// More tweaking of terrian floor.
++//
++// Revision 1.5 1997/06/26 22:14:57 curt
++// Beginning work on a scenery management system.
++//
++// Revision 1.4 1997/06/21 17:57:21 curt
++// directory shuffling ...
++//
++// Revision 1.2 1997/05/23 15:40:43 curt
++// Added GNU copyright headers.
++//
++// Revision 1.1 1997/05/16 16:07:07 curt
++// Initial revision.
++//
++
--- /dev/null
--- /dev/null
++// tile.cxx -- routines to handle a scenery tile
++//
++// Written by Curtis Olson, started May 1998.
++//
++// Copyright (C) 1998 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$
++// (Log is kept at end of this file)
++
++
++#include <Include/compiler.h>
++
++#include STL_FUNCTIONAL
++#include STL_ALGORITHM
++
++#include <Debug/logstream.hxx>
++#include <Scenery/tile.hxx>
++#include "Bucket/newbucket.hxx"
++
++#include "tile.hxx"
++
++FG_USING_STD(for_each);
++FG_USING_STD(mem_fun_ref);
++
++
++// Constructor
++fgTILE::fgTILE ( void )
++ : nodes(new double[MAX_NODES][3]),
++ ncount(0),
++ used(false)
++{
++}
++
++
++// Destructor
++fgTILE::~fgTILE ( void ) {
++// free(nodes);
++ delete[] nodes;
++}
++
++// Step through the fragment list, deleting the display list, then
++// the fragment, until the list is empty.
++void
++fgTILE::release_fragments()
++{
++ FG_LOG( FG_TERRAIN, FG_DEBUG,
++ "FREEING TILE = (" << tile_bucket << ")" );
++ for_each( begin(), end(),
++ mem_fun_ref( &fgFRAGMENT::deleteDisplayList ));
++ fragment_list.erase( begin(), end() );
++ used = false;
++}
++
++
++// $Log$
++// Revision 1.16 1999/03/25 19:03:24 curt
++// Converted to use new bucket routines.
++//
++// Revision 1.15 1999/03/02 01:03:29 curt
++// Tweaks for building with native SGI compilers.
++//
++// Revision 1.14 1999/02/02 20:13:40 curt
++// MSVC++ portability changes by Bernie Bright:
++//
++// Lib/Serial/serial.[ch]xx: Initial Windows support - incomplete.
++// Simulator/Astro/stars.cxx: typo? included <stdio> instead of <cstdio>
++// Simulator/Cockpit/hud.cxx: Added Standard headers
++// Simulator/Cockpit/panel.cxx: Redefinition of default parameter
++// Simulator/Flight/flight.cxx: Replaced cout with FG_LOG. Deleted <stdio.h>
++// Simulator/Main/fg_init.cxx:
++// Simulator/Main/GLUTmain.cxx:
++// Simulator/Main/options.hxx: Shuffled <fg_serial.hxx> dependency
++// Simulator/Objects/material.hxx:
++// Simulator/Time/timestamp.hxx: VC++ friend kludge
++// Simulator/Scenery/tile.[ch]xx: Fixed using std::X declarations
++// Simulator/Main/views.hxx: Added a constant
++//
++// Revision 1.13 1998/11/09 23:40:46 curt
++// Bernie Bright <bbright@c031.aone.net.au> writes:
++// I've made some changes to the Scenery handling. Basically just tidy ups.
++// The main difference is in tile.[ch]xx where I've changed list<fgFRAGMENT> to
++// vector<fgFRAGMENT>. Studying our usage patterns this seems reasonable.
++// Lists are good if you need to insert/delete elements randomly but we
++// don't do that. All access seems to be sequential. Two additional
++// benefits are smaller memory usage - each list element requires pointers
++// to the next and previous elements, and faster access - vector iterators
++// are smaller and faster than list iterators. This should also help
++// Charlie Hotchkiss' problem when compiling with Borland and STLport.
++//
++// ./Lib/Bucket/bucketutils.hxx
++// Convenience functions for fgBUCKET.
++//
++// ./Simulator/Scenery/tile.cxx
++// ./Simulator/Scenery/tile.hxx
++// Changed fragment list to a vector.
++// Added some convenience member functions.
++//
++// ./Simulator/Scenery/tilecache.cxx
++// ./Simulator/Scenery/tilecache.hxx
++// use const fgBUCKET& instead of fgBUCKET* where appropriate.
++//
++// ./Simulator/Scenery/tilemgr.cxx
++// ./Simulator/Scenery/tilemgr.hxx
++// uses all the new convenience functions.
++//
++// Revision 1.12 1998/10/16 00:55:45 curt
++// Converted to Point3D class.
++//
++// Revision 1.11 1998/09/02 14:37:08 curt
++// Use erase() instead of while ( size() ) pop_front();
++//
++// Revision 1.10 1998/08/25 16:52:42 curt
++// material.cxx material.hxx obj.cxx obj.hxx texload.c texload.h moved to
++// ../Objects
++//
++// Revision 1.9 1998/08/24 20:11:39 curt
++// Tweaks ...
++//
++// Revision 1.8 1998/08/22 14:49:58 curt
++// Attempting to iron out seg faults and crashes.
++// Did some shuffling to fix a initialization order problem between view
++// position, scenery elevation.
++//
++// Revision 1.7 1998/08/20 15:12:05 curt
++// Used a forward declaration of classes fgTILE and fgMATERIAL to eliminate
++// the need for "void" pointers and casts.
++// Quick hack to count the number of scenery polygons that are being drawn.
++//
++// Revision 1.6 1998/08/12 21:13:05 curt
++// material.cxx: don't load textures if they are disabled
++// obj.cxx: optimizations from Norman Vine
++// tile.cxx: minor tweaks
++// tile.hxx: addition of num_faces
++// tilemgr.cxx: minor tweaks
++//
++// Revision 1.5 1998/07/24 21:42:08 curt
++// material.cxx: whups, double method declaration with no definition.
++// obj.cxx: tweaks to avoid errors in SGI's CC.
++// tile.cxx: optimizations by Norman Vine.
++// tilemgr.cxx: optimizations by Norman Vine.
++//
++// Revision 1.4 1998/07/22 21:41:42 curt
++// Add basic fgFACE methods contributed by Charlie Hotchkiss.
++// intersect optimization from Norman Vine.
++//
++// Revision 1.3 1998/07/16 17:34:24 curt
++// Ground collision detection optimizations contributed by Norman Vine.
++//
++// Revision 1.2 1998/07/12 03:18:28 curt
++// Added ground collision detection. This involved:
++// - saving the entire vertex list for each tile with the tile records.
++// - saving the face list for each fragment with the fragment records.
++// - code to intersect the current vertical line with the proper face in
++// an efficient manner as possible.
++// Fixed a bug where the tiles weren't being shifted to "near" (0,0,0)
++//
++// Revision 1.1 1998/05/23 14:09:21 curt
++// Added tile.cxx and tile.hxx.
++// Working on rewriting the tile management system so a tile is just a list
++// fragments, and the fragment record contains the display list for that fragment.
++//
--- /dev/null
--- /dev/null
++// tile.hxx -- routines to handle a scenery tile
++//
++// Written by Curtis Olson, started May 1998.
++//
++// Copyright (C) 1998 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$
++// (Log is kept at end of this file)
++
++
++#ifndef _TILE_HXX
++#define _TILE_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#include <Include/compiler.h>
++
++#include <vector>
++#include STL_STRING
++
++#include <Bucket/newbucket.hxx>
++#include <Math/mat3.h>
++#include <Math/point3d.hxx>
++#include <Objects/fragment.hxx>
++
++#ifdef FG_HAVE_NATIVE_SGI_COMPILERS
++#include <strings.h>
++#endif
++
++FG_USING_STD(string);
++FG_USING_STD(vector);
++
++
++// Scenery tile class
++class fgTILE {
++
++public:
++
++ typedef vector < fgFRAGMENT > container;
++ typedef container::iterator FragmentIterator;
++ typedef container::const_iterator FragmentConstIterator;
++
++public:
++ // node list (the per fragment face lists reference this node list)
++ double (*nodes)[3];
++ int ncount;
++
++ // culling data for whole tile (course grain culling)
++ Point3D center;
++ double bounding_radius;
++ Point3D offset;
++ GLdouble model_view[16];
++
++ // this tile's official location in the world
++ FGBucket tile_bucket;
++
++ // the tile cache will mark here if the tile is being used
++ bool used;
++
++ container fragment_list;
++
++public:
++
++ FragmentIterator begin() { return fragment_list.begin(); }
++ FragmentConstIterator begin() const { return fragment_list.begin(); }
++
++ FragmentIterator end() { return fragment_list.end(); }
++ FragmentConstIterator end() const { return fragment_list.end(); }
++
++ void add_fragment( fgFRAGMENT& frag ) {
++ frag.tile_ptr = this;
++ fragment_list.push_back( frag );
++ }
++
++ //
++ size_t num_fragments() const {
++ return fragment_list.size();
++ }
++
++ // Step through the fragment list, deleting the display list, then
++ // the fragment, until the list is empty.
++ void release_fragments();
++
++// int ObjLoad( const string& path, const fgBUCKET& p );
++
++ // Constructor
++ fgTILE ( void );
++
++ // Destructor
++ ~fgTILE ( void );
++
++ // Calculate this tile's offset
++ void SetOffset( const Point3D& off)
++ {
++ offset = center - off;
++ }
++
++
++ // Calculate the model_view transformation matrix for this tile
++ inline void
++ UpdateViewMatrix(GLdouble *MODEL_VIEW)
++ {
++
++#if defined( USE_MEM ) || defined( WIN32 )
++ memcpy( model_view, MODEL_VIEW, 16*sizeof(GLdouble) );
++#else
++ bcopy( MODEL_VIEW, model_view, 16*sizeof(GLdouble) );
++#endif
++
++ // This is equivalent to doing a glTranslatef(x, y, z);
++ model_view[12] += (model_view[0]*offset.x() +
++ model_view[4]*offset.y() +
++ model_view[8]*offset.z());
++ model_view[13] += (model_view[1]*offset.x() +
++ model_view[5]*offset.y() +
++ model_view[9]*offset.z());
++ model_view[14] += (model_view[2]*offset.x() +
++ model_view[6]*offset.y() +
++ model_view[10]*offset.z() );
++ // m[15] += (m[3]*x + m[7]*y + m[11]*z);
++ // m[3] m7[] m[11] are 0.0 see LookAt() in views.cxx
++ // so m[15] is unchanged
++ }
++
++private:
++
++ // not defined
++ fgTILE( const fgTILE& );
++ fgTILE& operator = ( const fgTILE& );
++};
++
++
++#endif // _TILE_HXX
++
++
++// $Log$
++// Revision 1.26 1999/03/25 19:03:25 curt
++// Converted to use new bucket routines.
++//
++// Revision 1.25 1999/03/02 01:03:30 curt
++// Tweaks for building with native SGI compilers.
++//
++// Revision 1.24 1999/02/26 22:10:02 curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.23 1999/02/02 20:13:41 curt
++// MSVC++ portability changes by Bernie Bright:
++//
++// Lib/Serial/serial.[ch]xx: Initial Windows support - incomplete.
++// Simulator/Astro/stars.cxx: typo? included <stdio> instead of <cstdio>
++// Simulator/Cockpit/hud.cxx: Added Standard headers
++// Simulator/Cockpit/panel.cxx: Redefinition of default parameter
++// Simulator/Flight/flight.cxx: Replaced cout with FG_LOG. Deleted <stdio.h>
++// Simulator/Main/fg_init.cxx:
++// Simulator/Main/GLUTmain.cxx:
++// Simulator/Main/options.hxx: Shuffled <fg_serial.hxx> dependency
++// Simulator/Objects/material.hxx:
++// Simulator/Time/timestamp.hxx: VC++ friend kludge
++// Simulator/Scenery/tile.[ch]xx: Fixed using std::X declarations
++// Simulator/Main/views.hxx: Added a constant
++//
++// Revision 1.22 1998/12/03 01:18:16 curt
++// Converted fgFLIGHT to a class.
++// Tweaks for Sun Portability.
++// Tweaked current terrain elevation code as per NHV.
++//
++// Revision 1.21 1998/11/09 23:40:47 curt
++// Bernie Bright <bbright@c031.aone.net.au> writes:
++// I've made some changes to the Scenery handling. Basically just tidy ups.
++// The main difference is in tile.[ch]xx where I've changed list<fgFRAGMENT> to
++// vector<fgFRAGMENT>. Studying our usage patterns this seems reasonable.
++// Lists are good if you need to insert/delete elements randomly but we
++// don't do that. All access seems to be sequential. Two additional
++// benefits are smaller memory usage - each list element requires pointers
++// to the next and previous elements, and faster access - vector iterators
++// are smaller and faster than list iterators. This should also help
++// Charlie Hotchkiss' problem when compiling with Borland and STLport.
++//
++// ./Lib/Bucket/bucketutils.hxx
++// Convenience functions for fgBUCKET.
++//
++// ./Simulator/Scenery/tile.cxx
++// ./Simulator/Scenery/tile.hxx
++// Changed fragment list to a vector.
++// Added some convenience member functions.
++//
++// ./Simulator/Scenery/tilecache.cxx
++// ./Simulator/Scenery/tilecache.hxx
++// use const fgBUCKET& instead of fgBUCKET* where appropriate.
++//
++// ./Simulator/Scenery/tilemgr.cxx
++// ./Simulator/Scenery/tilemgr.hxx
++// uses all the new convenience functions.
++//
++// Revision 1.20 1998/10/16 00:55:46 curt
++// Converted to Point3D class.
++//
++// Revision 1.19 1998/09/17 18:36:17 curt
++// Tweaks and optimizations by Norman Vine.
++//
++// Revision 1.18 1998/08/25 16:52:42 curt
++// material.cxx material.hxx obj.cxx obj.hxx texload.c texload.h moved to
++// ../Objects
++//
++// Revision 1.17 1998/08/22 14:49:58 curt
++// Attempting to iron out seg faults and crashes.
++// Did some shuffling to fix a initialization order problem between view
++// position, scenery elevation.
++//
++// Revision 1.16 1998/08/22 02:01:34 curt
++// increased fragment list size.
++//
++// Revision 1.15 1998/08/20 15:12:06 curt
++// Used a forward declaration of classes fgTILE and fgMATERIAL to eliminate
++// the need for "void" pointers and casts.
++// Quick hack to count the number of scenery polygons that are being drawn.
++//
++// Revision 1.14 1998/08/12 21:13:06 curt
++// material.cxx: don't load textures if they are disabled
++// obj.cxx: optimizations from Norman Vine
++// tile.cxx: minor tweaks
++// tile.hxx: addition of num_faces
++// tilemgr.cxx: minor tweaks
++//
++// Revision 1.13 1998/07/24 21:42:08 curt
++// material.cxx: whups, double method declaration with no definition.
++// obj.cxx: tweaks to avoid errors in SGI's CC.
++// tile.cxx: optimizations by Norman Vine.
++// tilemgr.cxx: optimizations by Norman Vine.
++//
++// Revision 1.12 1998/07/22 21:41:42 curt
++// Add basic fgFACE methods contributed by Charlie Hotchkiss.
++// intersect optimization from Norman Vine.
++//
++// Revision 1.11 1998/07/12 03:18:28 curt
++// Added ground collision detection. This involved:
++// - saving the entire vertex list for each tile with the tile records.
++// - saving the face list for each fragment with the fragment records.
++// - code to intersect the current vertical line with the proper face in
++// an efficient manner as possible.
++// Fixed a bug where the tiles weren't being shifted to "near" (0,0,0)
++//
++// Revision 1.10 1998/07/08 14:47:22 curt
++// Fix GL_MODULATE vs. GL_DECAL problem introduced by splash screen.
++// polare3d.h renamed to polar3d.hxx
++// fg{Cartesian,Polar}Point3d consolodated.
++// Added some initial support for calculating local current ground elevation.
++//
++// Revision 1.9 1998/07/06 21:34:34 curt
++// Added using namespace std for compilers that support this.
++//
++// Revision 1.8 1998/07/04 00:54:30 curt
++// Added automatic mipmap generation.
++//
++// When rendering fragments, use saved model view matrix from associated tile
++// rather than recalculating it with push() translate() pop().
++//
++// Revision 1.7 1998/06/12 00:58:05 curt
++// Build only static libraries.
++// Declare memmove/memset for Sloaris.
++//
++// Revision 1.6 1998/06/08 17:57:54 curt
++// Working first pass at material proporty sorting.
++//
++// Revision 1.5 1998/06/06 01:09:32 curt
++// I goofed on the log message in the last commit ... now fixed.
++//
++// Revision 1.4 1998/06/06 01:07:18 curt
++// Increased per material fragment list size from 100 to 400.
++// Now correctly draw viewable fragments in per material order.
++//
++// Revision 1.3 1998/06/05 22:39:54 curt
++// Working on sorting by, and rendering by material properties.
++//
++// Revision 1.2 1998/06/03 00:47:50 curt
++// No .h for STL includes.
++// Minor view culling optimizations.
++//
++// Revision 1.1 1998/05/23 14:09:21 curt
++// Added tile.cxx and tile.hxx.
++// Working on rewriting the tile management system so a tile is just a list
++// fragments, and the fragment record contains the display list for that fragment.
++//
--- /dev/null
--- /dev/null
++// tilecache.cxx -- routines to handle scenery tile caching
++//
++// Written by Curtis Olson, started January 1998.
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#include <Debug/logstream.hxx>
++#include <Airports/genapt.hxx>
++// #include <Bucket/bucketutils.hxx>
++#include <Main/options.hxx>
++#include <Main/views.hxx>
++#include <Objects/obj.hxx>
++
++#include "tile.hxx"
++#include "tilecache.hxx"
++
++
++// the tile cache
++fgTILECACHE global_tile_cache;
++
++
++// Constructor
++fgTILECACHE::fgTILECACHE( void ) {
++}
++
++
++// Initialize the tile cache subsystem
++void
++fgTILECACHE::init( void )
++{
++ int i;
++
++ FG_LOG( FG_TERRAIN, FG_INFO, "Initializing the tile cache." );
++
++ for ( i = 0; i < FG_TILE_CACHE_SIZE; i++ ) {
++ tile_cache[i].used = 0;
++ }
++}
++
++
++// Search for the specified "bucket" in the cache
++int
++fgTILECACHE::exists( const FGBucket& p )
++{
++ int i;
++
++ for ( i = 0; i < FG_TILE_CACHE_SIZE; i++ ) {
++ if ( tile_cache[i].tile_bucket == p ) {
++ FG_LOG( FG_TERRAIN, FG_DEBUG,
++ "TILE EXISTS in cache ... index = " << i );
++ return( i );
++ }
++ }
++
++ return( -1 );
++}
++
++
++// Fill in a tile cache entry with real data for the specified bucket
++void
++fgTILECACHE::fill_in( int index, FGBucket& p )
++{
++ // Load the appropriate data file and build tile fragment list
++ string tile_path = current_options.get_fg_root() +
++ "/Scenery/" + p.gen_base_path() + "/" + p.gen_index_str();
++
++ tile_cache[index].used = true;
++ tile_cache[index].tile_bucket = p;
++ fgObjLoad( tile_path, &tile_cache[index] );
++// tile_cache[ index ].ObjLoad( tile_path, p );
++
++ // cout << " ncount before = " << tile_cache[index].ncount << "\n";
++ // cout << " fragments before = " << tile_cache[index].fragment_list.size()
++ // << "\n";
++
++ string apt_path = tile_path + ".apt";
++ fgAptGenerate( apt_path, &tile_cache[index] );
++
++ // cout << " ncount after = " << tile_cache[index].ncount << "\n";
++ // cout << " fragments after = " << tile_cache[index].fragment_list.size()
++ // << "\n";
++}
++
++
++// Free a tile cache entry
++void
++fgTILECACHE::entry_free( int index )
++{
++ tile_cache[index].release_fragments();
++}
++
++
++// Return index of next available slot in tile cache
++int
++fgTILECACHE::next_avail( void )
++{
++ Point3D delta, abs_view_pos;
++ int i;
++ float max, med, min, tmp;
++ float dist, max_dist;
++ int max_index;
++
++ max_dist = 0.0;
++ max_index = 0;
++
++ for ( i = 0; i < FG_TILE_CACHE_SIZE; i++ ) {
++ if ( ! tile_cache[i].used ) {
++ return(i);
++ } else {
++ // calculate approximate distance from view point
++ abs_view_pos = current_view.get_abs_view_pos();
++
++ FG_LOG( FG_TERRAIN, FG_DEBUG,
++ "DIST Abs view pos = " << abs_view_pos );
++ FG_LOG( FG_TERRAIN, FG_DEBUG,
++ " ref point = " << tile_cache[i].center );
++
++ delta.setx( fabs(tile_cache[i].center.x() - abs_view_pos.x() ) );
++ delta.sety( fabs(tile_cache[i].center.y() - abs_view_pos.y() ) );
++ delta.setz( fabs(tile_cache[i].center.z() - abs_view_pos.z() ) );
++
++ max = delta.x(); med = delta.y(); min = delta.z();
++ if ( max < med ) {
++ tmp = max; max = med; med = tmp;
++ }
++ if ( max < min ) {
++ tmp = max; max = min; min = tmp;
++ }
++ dist = max + (med + min) / 4;
++
++ FG_LOG( FG_TERRAIN, FG_DEBUG, " distance = " << dist );
++
++ if ( dist > max_dist ) {
++ max_dist = dist;
++ max_index = i;
++ }
++ }
++ }
++
++ // If we made it this far, then there were no open cache entries.
++ // We will instead free the furthest cache entry and return it's
++ // index.
++
++ entry_free( max_index );
++ return( max_index );
++}
++
++
++// Destructor
++fgTILECACHE::~fgTILECACHE( void ) {
++}
++
++
++// $Log$
++// Revision 1.23 1999/03/25 19:03:26 curt
++// Converted to use new bucket routines.
++//
++// Revision 1.22 1999/02/26 22:10:04 curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.21 1998/12/09 18:50:32 curt
++// Converted "class fgVIEW" to "class FGView" and updated to make data
++// members private and make required accessor functions.
++//
++// Revision 1.20 1998/11/09 23:40:49 curt
++// Bernie Bright <bbright@c031.aone.net.au> writes:
++// I've made some changes to the Scenery handling. Basically just tidy ups.
++// The main difference is in tile.[ch]xx where I've changed list<fgFRAGMENT> to
++// vector<fgFRAGMENT>. Studying our usage patterns this seems reasonable.
++// Lists are good if you need to insert/delete elements randomly but we
++// don't do that. All access seems to be sequential. Two additional
++// benefits are smaller memory usage - each list element requires pointers
++// to the next and previous elements, and faster access - vector iterators
++// are smaller and faster than list iterators. This should also help
++// Charlie Hotchkiss' problem when compiling with Borland and STLport.
++//
++// ./Lib/Bucket/bucketutils.hxx
++// Convenience functions for fgBUCKET.
++//
++// ./Simulator/Scenery/tile.cxx
++// ./Simulator/Scenery/tile.hxx
++// Changed fragment list to a vector.
++// Added some convenience member functions.
++//
++// ./Simulator/Scenery/tilecache.cxx
++// ./Simulator/Scenery/tilecache.hxx
++// use const fgBUCKET& instead of fgBUCKET* where appropriate.
++//
++// ./Simulator/Scenery/tilemgr.cxx
++// ./Simulator/Scenery/tilemgr.hxx
++// uses all the new convenience functions.
++//
++// Revision 1.19 1998/11/06 21:18:21 curt
++// Converted to new logstream debugging facility. This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.18 1998/10/16 18:12:28 curt
++// Fixed a bug in the conversion to Point3D.
++//
++// Revision 1.17 1998/10/16 00:55:48 curt
++// Converted to Point3D class.
++//
++// Revision 1.16 1998/09/14 12:45:23 curt
++// minor tweaks.
++//
++// Revision 1.15 1998/08/27 17:02:10 curt
++// Contributions from Bernie Bright <bbright@c031.aone.net.au>
++// - use strings for fg_root and airport_id and added methods to return
++// them as strings,
++// - inlined all access methods,
++// - made the parsing functions private methods,
++// - deleted some unused functions.
++// - propogated some of these changes out a bit further.
++//
++// Revision 1.14 1998/08/25 16:52:43 curt
++// material.cxx material.hxx obj.cxx obj.hxx texload.c texload.h moved to
++// ../Objects
++//
++// Revision 1.13 1998/07/13 21:02:00 curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.12 1998/07/12 03:18:29 curt
++// Added ground collision detection. This involved:
++// - saving the entire vertex list for each tile with the tile records.
++// - saving the face list for each fragment with the fragment records.
++// - code to intersect the current vertical line with the proper face in
++// an efficient manner as possible.
++// Fixed a bug where the tiles weren't being shifted to "near" (0,0,0)
++//
++// Revision 1.11 1998/07/04 00:54:30 curt
++// Added automatic mipmap generation.
++//
++// When rendering fragments, use saved model view matrix from associated tile
++// rather than recalculating it with push() translate() pop().
++//
++// Revision 1.10 1998/05/23 14:09:22 curt
++// Added tile.cxx and tile.hxx.
++// Working on rewriting the tile management system so a tile is just a list
++// fragments, and the fragment record contains the display list for that fragment.
++//
++// Revision 1.9 1998/05/20 20:53:54 curt
++// Moved global ref point and radius (bounding sphere info, and offset) to
++// data file rather than calculating it on the fly.
++// Fixed polygon winding problem in scenery generation stage rather than
++// compensating for it on the fly.
++// Made a fgTILECACHE class.
++//
++// Revision 1.8 1998/05/16 13:09:57 curt
++// Beginning to add support for view frustum culling.
++// Added some temporary code to calculate bouding radius, until the
++// scenery generation tools and scenery can be updated.
++//
++// Revision 1.7 1998/05/13 18:26:41 curt
++// Root path info moved to fgOPTIONS.
++//
++// Revision 1.6 1998/05/02 01:52:17 curt
++// Playing around with texture coordinates.
++//
++// Revision 1.5 1998/04/30 12:35:31 curt
++// Added a command line rendering option specify smooth/flat shading.
++//
++// Revision 1.4 1998/04/28 01:21:43 curt
++// Tweaked texture parameter calculations to keep the number smaller. This
++// avoids the "swimming" problem.
++// Type-ified fgTIME and fgVIEW.
++//
++// Revision 1.3 1998/04/25 22:06:32 curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.2 1998/04/24 00:51:08 curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Tweaked the scenery file extentions to be "file.obj" (uncompressed)
++// or "file.obz" (compressed.)
++//
++// Revision 1.1 1998/04/22 13:22:46 curt
++// C++ - ifing the code a bit.
++//
++// Revision 1.11 1998/04/18 04:14:07 curt
++// Moved fg_debug.c to it's own library.
++//
++// Revision 1.10 1998/04/14 02:23:17 curt
++// Code reorganizations. Added a Lib/ directory for more general libraries.
++//
++// Revision 1.9 1998/04/08 23:30:07 curt
++// Adopted Gnu automake/autoconf system.
++//
++// Revision 1.8 1998/04/03 22:11:38 curt
++// Converting to Gnu autoconf system.
++//
++// Revision 1.7 1998/02/01 03:39:55 curt
++// Minor tweaks.
++//
++// Revision 1.6 1998/01/31 00:43:26 curt
++// Added MetroWorks patches from Carmen Volpe.
++//
++// Revision 1.5 1998/01/29 00:51:39 curt
++// First pass at tile cache, dynamic tile loading and tile unloading now works.
++//
++// Revision 1.4 1998/01/27 03:26:43 curt
++// Playing with new fgPrintf command.
++//
++// Revision 1.3 1998/01/27 00:48:03 curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.2 1998/01/26 15:55:24 curt
++// Progressing on building dynamic scenery system.
++//
++// Revision 1.1 1998/01/24 00:03:29 curt
++// Initial revision.
++
++
++
--- /dev/null
--- /dev/null
++// tilecache.hxx -- routines to handle scenery tile caching
++//
++// Written by Curtis Olson, started January 1998.
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#ifndef _TILECACHE_HXX
++#define _TILECACHE_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#include <Bucket/newbucket.hxx>
++#include <Math/point3d.hxx>
++
++#include "tile.hxx"
++
++
++// For best results ... i.e. to avoid tile load problems and blank areas
++//
++// FG_TILE_CACHE_SIZE >= (o->tile_diameter + 1) ** 2
++#define FG_TILE_CACHE_SIZE 121
++
++// A class to store and manage a pile of tiles
++class fgTILECACHE {
++
++// enum
++// {
++// // For best results... i.e. to avoid tile load problems and blank areas
++// // FG_TILE_CACHE_SIZE >= (o->tile_diameter + 1) ** 2
++// FG_TILE_CACHE_SIZE = 121
++// };
++
++ // cache storage space
++ fgTILE tile_cache[ FG_TILE_CACHE_SIZE ];
++
++public:
++
++ // Constructor
++ fgTILECACHE( void );
++
++ // Initialize the tile cache subsystem
++ void init( void );
++
++ // Search for the specified "bucket" in the cache
++ int exists( const FGBucket& p );
++
++ // Return index of next available slot in tile cache
++ int next_avail( void );
++
++ // Free a tile cache entry
++ void entry_free( int index );
++
++ // Fill in a tile cache entry with real data for the specified bucket
++ void fill_in( int index, FGBucket& p );
++
++ // Return a pointer to the specified tile cache entry
++ fgTILE *get_tile( int index ) {
++ return &tile_cache[index];
++ }
++
++ // Destructor
++ ~fgTILECACHE( void );
++};
++
++
++// the tile cache
++extern fgTILECACHE global_tile_cache;
++
++
++#endif // _TILECACHE_HXX
++
++
++// $Log$
++// Revision 1.14 1999/03/25 19:03:27 curt
++// Converted to use new bucket routines.
++//
++// Revision 1.13 1998/11/09 23:40:51 curt
++// Bernie Bright <bbright@c031.aone.net.au> writes:
++// I've made some changes to the Scenery handling. Basically just tidy ups.
++// The main difference is in tile.[ch]xx where I've changed list<fgFRAGMENT> to
++// vector<fgFRAGMENT>. Studying our usage patterns this seems reasonable.
++// Lists are good if you need to insert/delete elements randomly but we
++// don't do that. All access seems to be sequential. Two additional
++// benefits are smaller memory usage - each list element requires pointers
++// to the next and previous elements, and faster access - vector iterators
++// are smaller and faster than list iterators. This should also help
++// Charlie Hotchkiss' problem when compiling with Borland and STLport.
++//
++// ./Lib/Bucket/bucketutils.hxx
++// Convenience functions for fgBUCKET.
++//
++// ./Simulator/Scenery/tile.cxx
++// ./Simulator/Scenery/tile.hxx
++// Changed fragment list to a vector.
++// Added some convenience member functions.
++//
++// ./Simulator/Scenery/tilecache.cxx
++// ./Simulator/Scenery/tilecache.hxx
++// use const fgBUCKET& instead of fgBUCKET* where appropriate.
++//
++// ./Simulator/Scenery/tilemgr.cxx
++// ./Simulator/Scenery/tilemgr.hxx
++// uses all the new convenience functions.
++//
++// Revision 1.12 1998/10/16 00:55:49 curt
++// Converted to Point3D class.
++//
++// Revision 1.11 1998/09/14 12:45:25 curt
++// minor tweaks.
++//
++// Revision 1.10 1998/07/04 00:54:31 curt
++// Added automatic mipmap generation.
++//
++// When rendering fragments, use saved model view matrix from associated tile
++// rather than recalculating it with push() translate() pop().
++//
++// Revision 1.9 1998/05/23 14:09:22 curt
++// Added tile.cxx and tile.hxx.
++// Working on rewriting the tile management system so a tile is just a list
++// fragments, and the fragment record contains the display list for that fragment.
++//
++// Revision 1.8 1998/05/20 20:53:54 curt
++// Moved global ref point and radius (bounding sphere info, and offset) to
++// data file rather than calculating it on the fly.
++// Fixed polygon winding problem in scenery generation stage rather than
++// compensating for it on the fly.
++// Made a fgTILECACHE class.
++//
++// Revision 1.7 1998/05/16 13:09:57 curt
++// Beginning to add support for view frustum culling.
++// Added some temporary code to calculate bouding radius, until the
++// scenery generation tools and scenery can be updated.
++//
++// Revision 1.6 1998/05/07 23:15:20 curt
++// Fixed a glTexImage2D() usage bug where width and height were mis-swapped.
++// Added support for --tile-radius=n option.
++//
++// Revision 1.5 1998/05/02 01:52:17 curt
++// Playing around with texture coordinates.
++//
++// Revision 1.4 1998/04/30 12:35:31 curt
++// Added a command line rendering option specify smooth/flat shading.
++//
++// Revision 1.3 1998/04/25 22:06:32 curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.2 1998/04/24 00:51:08 curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Tweaked the scenery file extentions to be "file.obj" (uncompressed)
++// or "file.obz" (compressed.)
++//
++// Revision 1.1 1998/04/22 13:22:47 curt
++// C++ - ifing the code a bit.
++//
++// Revision 1.10 1998/04/21 17:02:45 curt
++// Prepairing for C++ integration.
++//
++// Revision 1.9 1998/04/14 02:23:17 curt
++// Code reorganizations. Added a Lib/ directory for more general libraries.
++//
++// Revision 1.8 1998/04/08 23:30:08 curt
++// Adopted Gnu automake/autoconf system.
++//
++// Revision 1.7 1998/04/03 22:11:38 curt
++// Converting to Gnu autoconf system.
++//
++// Revision 1.6 1998/02/18 15:07:10 curt
++// Tweaks to build with SGI OpenGL (and therefor hopefully other accelerated
++// drivers will work.)
++//
++// Revision 1.5 1998/02/16 13:39:45 curt
++// Miscellaneous weekend tweaks. Fixed? a cache problem that caused whole
++// tiles to occasionally be missing.
++//
++// Revision 1.4 1998/01/31 00:43:27 curt
++// Added MetroWorks patches from Carmen Volpe.
++//
++// Revision 1.3 1998/01/29 00:51:40 curt
++// First pass at tile cache, dynamic tile loading and tile unloading now works.
++//
++// Revision 1.2 1998/01/27 00:48:04 curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.1 1998/01/24 00:03:29 curt
++// Initial revision.
++
++
--- /dev/null
--- /dev/null
++// tilemgr.cxx -- routines to handle dynamic management of scenery tiles
++//
++// Written by Curtis Olson, started January 1998.
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#include <Aircraft/aircraft.hxx>
++
++#include <Debug/logstream.hxx>
++// #include <Bucket/bucketutils.hxx>
++#include <Include/fg_constants.h>
++#include <Main/options.hxx>
++#include <Main/views.hxx>
++#include <Math/fg_geodesy.hxx>
++#include <Math/mat3.h>
++#include <Math/point3d.hxx>
++#include <Math/polar3d.hxx>
++#include <Math/vector.hxx>
++#include <Objects/material.hxx>
++#include <Objects/obj.hxx>
++#include <Weather/weather.hxx>
++
++#include "scenery.hxx"
++#include "tile.hxx"
++#include "tilecache.hxx"
++#include "tilemgr.hxx"
++
++
++// to test clipping speedup in fgTileMgrRender()
++#if defined ( USE_FAST_FOV_CLIP )
++ // #define TEST_FOV_CLIP
++ // #define TEST_ELEV
++#endif
++
++
++#define FG_LOCAL_X_Y 81 // max(o->tile_diameter) ** 2
++
++#define FG_SQUARE( X ) ( (X) * (X) )
++
++#if defined(USE_MEM) || defined(WIN32)
++# define FG_MEM_COPY(to,from,n) memcpy(to, from, n)
++#else
++# define FG_MEM_COPY(to,from,n) bcopy(from, to, n)
++#endif
++
++// closest (potentially viewable) tiles, centered on current tile.
++// This is an array of pointers to cache indexes.
++int tiles[FG_LOCAL_X_Y];
++
++
++// Initialize the Tile Manager subsystem
++int fgTileMgrInit( void ) {
++ FG_LOG( FG_TERRAIN, FG_INFO, "Initializing Tile Manager subsystem." );
++
++ // load default material library
++ material_mgr.load_lib();
++
++ return 1;
++}
++
++
++// load a tile
++void fgTileMgrLoadTile( const FGBucket& p, int *index) {
++ fgTILECACHE *c;
++
++ c = &global_tile_cache;
++
++ FG_LOG( FG_TERRAIN, FG_DEBUG, "Updating for bucket " << p );
++
++ // if not in cache, load tile into the next available slot
++ *index = c->exists(p);
++ if ( *index < 0 ) {
++ *index = c->next_avail();
++ c->fill_in(*index, p);
++ }
++
++ FG_LOG( FG_TERRAIN, FG_DEBUG, "Selected cache index: " << *index );
++}
++
++
++// Calculate shortest distance from point to line
++static double point_line_dist_squared( const Point3D& tc, const Point3D& vp,
++ MAT3vec d )
++{
++ MAT3vec p, p0;
++ double dist;
++
++ p[0] = tc.x(); p[1] = tc.y(); p[2] = tc.z();
++ p0[0] = vp.x(); p0[1] = vp.y(); p0[2] = vp.z();
++
++ return fgPointLineSquared(p, p0, d);
++}
++
++
++// Determine scenery altitude. Normally this just happens when we
++// render the scene, but we'd also like to be able to do this
++// explicitely. lat & lon are in radians. abs_view_pos in meters.
++// Returns result in meters.
++double
++fgTileMgrCurElevNEW( const FGBucket& p ) {
++ fgTILE *t;
++ fgFRAGMENT *frag_ptr;
++ Point3D abs_view_pos = current_view.get_abs_view_pos();
++ Point3D earth_center(0.0);
++ Point3D result;
++ MAT3vec local_up;
++ double dist, lat_geod, alt, sea_level_r;
++ int index;
++
++ local_up[0] = abs_view_pos.x();
++ local_up[1] = abs_view_pos.y();
++ local_up[2] = abs_view_pos.z();
++
++ // Find current translation offset
++ // fgBucketFind(lon * RAD_TO_DEG, lat * RAD_TO_DEG, &p);
++ index = global_tile_cache.exists(p);
++ if ( index < 0 ) {
++ FG_LOG( FG_TERRAIN, FG_WARN, "Tile not found" );
++ return 0.0;
++ }
++
++ t = global_tile_cache.get_tile(index);
++
++ scenery.next_center = t->center;
++
++ FG_LOG( FG_TERRAIN, FG_DEBUG,
++ "Current bucket = " << p << " Index = " << p.gen_index_str() );
++ FG_LOG( FG_TERRAIN, FG_DEBUG,
++ "abs_view_pos = " << abs_view_pos );
++
++ // calculate tile offset
++ // x = (t->offset.x = t->center.x - scenery.center.x);
++ // y = (t->offset.y = t->center.y - scenery.center.y);
++ // z = (t->offset.z = t->center.z - scenery.center.z);
++
++ // calc current terrain elevation calculate distance from
++ // vertical tangent line at current position to center of
++ // tile.
++
++ /* printf("distance squared = %.2f, bounding radius = %.2f\n",
++ point_line_dist_squared(&(t->offset), &(v->view_pos),
++ v->local_up), t->bounding_radius); */
++
++ dist = point_line_dist_squared( t->center, abs_view_pos, local_up );
++ if ( dist < FG_SQUARE(t->bounding_radius) ) {
++
++ // traverse fragment list for tile
++ fgTILE::FragmentIterator current = t->begin();
++ fgTILE::FragmentIterator last = t->end();
++
++ for ( ; current != last; ++current ) {
++ frag_ptr = &(*current);
++ /* printf("distance squared = %.2f, bounding radius = %.2f\n",
++ point_line_dist_squared( &(frag_ptr->center),
++ &abs_view_pos), local_up),
++ frag_ptr->bounding_radius); */
++
++ dist = point_line_dist_squared( frag_ptr->center,
++ abs_view_pos,
++ local_up);
++ if ( dist <= FG_SQUARE(frag_ptr->bounding_radius) ) {
++ if ( frag_ptr->intersect( abs_view_pos,
++ earth_center, 0, result ) ) {
++ FG_LOG( FG_TERRAIN, FG_DEBUG, "intersection point " <<
++ result );
++ // compute geocentric coordinates of tile center
++ Point3D pp = fgCartToPolar3d(result);
++ FG_LOG( FG_TERRAIN, FG_DEBUG, " polar form = " << pp );
++ // convert to geodetic coordinates
++ fgGeocToGeod(pp.lat(), pp.radius(), &lat_geod,
++ &alt, &sea_level_r);
++
++ // printf("alt = %.2f\n", alt);
++ // exit since we found an intersection
++ if ( alt > -9999.0 ) {
++ // printf("returning alt\n");
++ return alt;
++ } else {
++ // printf("returning 0\n");
++ return 0.0;
++ }
++ }
++ }
++ }
++ }
++
++ FG_LOG( FG_TERRAIN, FG_INFO, "(new) no terrain intersection found" );
++
++ return 0.0;
++}
++
++
++// Determine scenery altitude. Normally this just happens when we
++// render the scene, but we'd also like to be able to do this
++// explicitely. lat & lon are in radians. abs_view_pos in meters.
++// Returns result in meters.
++double
++fgTileMgrCurElev( double lon, double lat, const Point3D& abs_view_pos ) {
++ fgTILECACHE *c;
++ fgTILE *t;
++ fgFRAGMENT *frag_ptr;
++ Point3D earth_center(0.0);
++ Point3D result;
++ MAT3vec local_up;
++ double dist, lat_geod, alt, sea_level_r;
++ int index;
++
++ c = &global_tile_cache;
++
++ local_up[0] = abs_view_pos.x();
++ local_up[1] = abs_view_pos.y();
++ local_up[2] = abs_view_pos.z();
++
++ FG_LOG( FG_TERRAIN, FG_DEBUG, "Absolute view pos = " << abs_view_pos );
++
++ // Find current translation offset
++ FGBucket p( lon * RAD_TO_DEG, lat * RAD_TO_DEG );
++ index = c->exists(p);
++ if ( index < 0 ) {
++ FG_LOG( FG_TERRAIN, FG_WARN, "Tile not found" );
++ return 0.0;
++ }
++
++ t = c->get_tile(index);
++
++ scenery.next_center = t->center;
++
++ FG_LOG( FG_TERRAIN, FG_DEBUG,
++ "Pos = (" << lon * RAD_TO_DEG << ", " << lat * RAD_TO_DEG
++ << ") Current bucket = " << p
++ << " Index = " << p.gen_index_str() );
++
++ FG_LOG( FG_TERRAIN, FG_DEBUG, "Tile center " << t->center
++ << " bounding radius = " << t->bounding_radius );
++
++ // calculate tile offset
++ // x = (t->offset.x = t->center.x - scenery.center.x);
++ // y = (t->offset.y = t->center.y - scenery.center.y);
++ // z = (t->offset.z = t->center.z - scenery.center.z);
++
++ // calc current terrain elevation calculate distance from
++ // vertical tangent line at current position to center of
++ // tile.
++
++ /* printf("distance squared = %.2f, bounding radius = %.2f\n",
++ point_line_dist_squared(&(t->offset), &(v->view_pos),
++ v->local_up), t->bounding_radius); */
++
++ dist = point_line_dist_squared( t->center, abs_view_pos, local_up );
++ FG_LOG( FG_TERRAIN, FG_DEBUG, "(gross check) dist squared = " << dist );
++
++ if ( dist < FG_SQUARE(t->bounding_radius) ) {
++
++ // traverse fragment list for tile
++ fgTILE::FragmentIterator current = t->begin();
++ fgTILE::FragmentIterator last = t->end();
++
++ for ( ; current != last; ++current ) {
++ frag_ptr = &(*current);
++ /* printf("distance squared = %.2f, bounding radius = %.2f\n",
++ point_line_dist_squared( &(frag_ptr->center),
++ &abs_view_pos), local_up),
++ frag_ptr->bounding_radius); */
++
++ dist = point_line_dist_squared( frag_ptr->center,
++ abs_view_pos,
++ local_up);
++ if ( dist <= FG_SQUARE(frag_ptr->bounding_radius) ) {
++ if ( frag_ptr->intersect( abs_view_pos,
++ earth_center, 0, result ) ) {
++ FG_LOG( FG_TERRAIN, FG_DEBUG, "intersection point " <<
++ result );
++ // compute geocentric coordinates of tile center
++ Point3D pp = fgCartToPolar3d(result);
++ FG_LOG( FG_TERRAIN, FG_DEBUG, " polar form = " << pp );
++ // convert to geodetic coordinates
++ fgGeocToGeod(pp.lat(), pp.radius(), &lat_geod,
++ &alt, &sea_level_r);
++
++ // printf("alt = %.2f\n", alt);
++ // exit since we found an intersection
++ if ( alt > -9999.0 ) {
++ // printf("returning alt\n");
++ return alt;
++ } else {
++ // printf("returning 0\n");
++ return 0.0;
++ }
++ }
++ }
++ }
++ }
++
++ FG_LOG( FG_TERRAIN, FG_INFO, "(old) no terrain intersection found" );
++
++ return 0.0;
++}
++
++
++// given the current lon/lat, fill in the array of local chunks. If
++// the chunk isn't already in the cache, then read it from disk.
++int fgTileMgrUpdate( void ) {
++ fgTILECACHE *c;
++ FGInterface *f;
++ FGBucket p2;
++ static FGBucket p_last(false);
++ static double last_lon = -1000.0; // in degrees
++ static double last_lat = -1000.0; // in degrees
++ int tile_diameter;
++ int i, j, dw, dh;
++
++ c = &global_tile_cache;
++ f = current_aircraft.fdm_state;
++
++ tile_diameter = current_options.get_tile_diameter();
++
++ FGBucket p1( f->get_Longitude() * RAD_TO_DEG,
++ f->get_Latitude() * RAD_TO_DEG );
++ dw = tile_diameter / 2;
++ dh = tile_diameter / 2;
++
++ if ( p1 == p_last ) {
++ // same bucket as last time
++ FG_LOG( FG_TERRAIN, FG_DEBUG, "Same bucket as last time" );
++ } else if ( p_last.get_lon() == -1000 ) {
++ // First time through, initialize the system and load all
++ // relavant tiles
++
++ FG_LOG( FG_TERRAIN, FG_INFO, "Updating Tile list for " << p1 );
++ FG_LOG( FG_TERRAIN, FG_INFO, " First time through ... " );
++ FG_LOG( FG_TERRAIN, FG_INFO, " Updating Tile list for " << p1 );
++ FG_LOG( FG_TERRAIN, FG_INFO, " Loading "
++ << tile_diameter * tile_diameter << " tiles" );
++
++ // wipe/initialize tile cache
++ c->init();
++
++ // build the local area list and update cache
++ for ( j = 0; j < tile_diameter; j++ ) {
++ for ( i = 0; i < tile_diameter; i++ ) {
++ // fgBucketOffset(&p1, &p2, i - dw, j - dh);
++ p2 = fgBucketOffset( f->get_Longitude() * RAD_TO_DEG,
++ f->get_Latitude() * RAD_TO_DEG,
++ i - dw, j -dh );
++ fgTileMgrLoadTile( p2, &tiles[(j*tile_diameter) + i]);
++ }
++ }
++ } else {
++ // We've moved to a new bucket, we need to scroll our
++ // structures, and load in the new tiles
++
++ // CURRENTLY THIS ASSUMES WE CAN ONLY MOVE TO ADJACENT TILES.
++ // AT ULTRA HIGH SPEEDS THIS ASSUMPTION MAY NOT BE VALID IF
++ // THE AIRCRAFT CAN SKIP A TILE IN A SINGLE ITERATION.
++
++ FG_LOG( FG_TERRAIN, FG_INFO, "Updating Tile list for " << p1 );
++
++ if ( (p1.get_lon() > p_last.get_lon()) ||
++ ( (p1.get_lon() == p_last.get_lon()) && (p1.get_x() > p_last.get_x()) ) ) {
++ FG_LOG( FG_TERRAIN, FG_INFO,
++ " Loading " << tile_diameter << "tiles" );
++ for ( j = 0; j < tile_diameter; j++ ) {
++ // scrolling East
++ for ( i = 0; i < tile_diameter - 1; i++ ) {
++ tiles[(j*tile_diameter) + i] =
++ tiles[(j*tile_diameter) + i + 1];
++ }
++ // load in new column
++ // fgBucketOffset(&p_last, &p2, dw + 1, j - dh);
++ p2 = fgBucketOffset( last_lon, last_lat, dw + 1, j - dh );
++ fgTileMgrLoadTile( p2, &tiles[(j*tile_diameter) +
++ tile_diameter - 1]);
++ }
++ } else if ( (p1.get_lon() < p_last.get_lon()) ||
++ ( (p1.get_lon() == p_last.get_lon()) && (p1.get_x() < p_last.get_x()) ) ) {
++ FG_LOG( FG_TERRAIN, FG_INFO,
++ " Loading " << tile_diameter << "tiles" );
++ for ( j = 0; j < tile_diameter; j++ ) {
++ // scrolling West
++ for ( i = tile_diameter - 1; i > 0; i-- ) {
++ tiles[(j*tile_diameter) + i] =
++ tiles[(j*tile_diameter) + i - 1];
++ }
++ // load in new column
++ // fgBucketOffset(&p_last, &p2, -dw - 1, j - dh);
++ p2 = fgBucketOffset( last_lon, last_lat, -dw - 1, j - dh );
++ fgTileMgrLoadTile( p2, &tiles[(j*tile_diameter) + 0]);
++ }
++ }
++
++ if ( (p1.get_lat() > p_last.get_lat()) ||
++ ( (p1.get_lat() == p_last.get_lat()) && (p1.get_y() > p_last.get_y()) ) ) {
++ FG_LOG( FG_TERRAIN, FG_INFO,
++ " Loading " << tile_diameter << "tiles" );
++ for ( i = 0; i < tile_diameter; i++ ) {
++ // scrolling North
++ for ( j = 0; j < tile_diameter - 1; j++ ) {
++ tiles[(j * tile_diameter) + i] =
++ tiles[((j+1) * tile_diameter) + i];
++ }
++ // load in new column
++ // fgBucketOffset(&p_last, &p2, i - dw, dh + 1);
++ p2 = fgBucketOffset( last_lon, last_lat, i - dw, dh + 1);
++ fgTileMgrLoadTile( p2, &tiles[((tile_diameter-1) *
++ tile_diameter) + i]);
++ }
++ } else if ( (p1.get_lat() < p_last.get_lat()) ||
++ ( (p1.get_lat() == p_last.get_lat()) && (p1.get_y() < p_last.get_y()) ) ) {
++ FG_LOG( FG_TERRAIN, FG_INFO,
++ " Loading " << tile_diameter << "tiles" );
++ for ( i = 0; i < tile_diameter; i++ ) {
++ // scrolling South
++ for ( j = tile_diameter - 1; j > 0; j-- ) {
++ tiles[(j * tile_diameter) + i] =
++ tiles[((j-1) * tile_diameter) + i];
++ }
++ // load in new column
++ // fgBucketOffset(&p_last, &p2, i - dw, -dh - 1);
++ p2 = fgBucketOffset( last_lon, last_lat, i - dw, -dh - 1);
++ fgTileMgrLoadTile( p2, &tiles[0 + i]);
++ }
++ }
++ }
++
++ // find our current elevation (feed in the current bucket to save work)
++ Point3D geod_pos = Point3D( f->get_Longitude(), f->get_Latitude(), 0.0);
++ Point3D tmp_abs_view_pos = fgGeodToCart(geod_pos);
++
++ scenery.cur_elev =
++ fgTileMgrCurElev( f->get_Longitude(), f->get_Latitude(),
++ tmp_abs_view_pos );
++
++ p_last = p1;
++ last_lon = f->get_Longitude() * RAD_TO_DEG;
++ last_lat = f->get_Latitude() * RAD_TO_DEG;
++
++ return 1;
++}
++
++
++// Calculate if point/radius is inside view frustum
++static int viewable( const Point3D& cp, double radius ) {
++ int viewable = 1; // start by assuming it's viewable
++ double x1, y1;
++
++/********************************/
++#if defined( USE_FAST_FOV_CLIP ) // views.hxx
++/********************************/
++
++ MAT3vec eye;
++ double *mat;
++ double x, y, z;
++
++ x = cp.x();
++ y = cp.y();
++ z = cp.z();
++
++ mat = (double *)(current_view.get_WORLD_TO_EYE());
++
++ eye[2] = x*mat[2] + y*mat[6] + z*mat[10] + mat[14];
++
++ // Check near and far clip plane
++ if( ( eye[2] > radius ) ||
++ ( eye[2] + radius + current_weather.get_visibility() < 0) )
++ {
++ return(0);
++ }
++
++ eye[0] = (x*mat[0] + y*mat[4] + z*mat[8] + mat[12])
++ * current_view.get_slope_x();
++
++ // check right and left clip plane (from eye perspective)
++ x1 = radius * current_view.get_fov_x_clip();
++ if( (eye[2] > -(eye[0]+x1)) || (eye[2] > (eye[0]-x1)) )
++ {
++ return(0);
++ }
++
++ eye[1] = (x*mat[1] + y*mat[5] + z*mat[9] + mat[13])
++ * current_view.get_slope_y();
++
++ // check bottom and top clip plane (from eye perspective)
++ y1 = radius * current_view.get_fov_y_clip();
++ if( (eye[2] > -(eye[1]+y1)) || (eye[2] > (eye[1]-y1)) )
++ {
++ return(0);
++ }
++
++/********************************/
++#else // DO NOT USE_FAST_FOV_CLIP
++/********************************/
++
++ fgVIEW *v;
++ MAT3hvec world, eye;
++ double x0, slope;
++
++ v = ¤t_view;
++
++ MAT3_SET_HVEC(world, cp->x, cp->y, cp->z, 1.0);
++ // MAT3mult_vec(eye, world, v->WORLD_TO_EYE);
++ // printf( "\nworld -> eye = %.2f %.2f %.2f radius = %.2f\n",
++ // eye[0], eye[1], eye[2], radius);
++
++ // Use lazy evaluation for calculating eye hvec.
++#define vec world
++#define mat v->WORLD_TO_EYE
++ eye[2] = vec[0]*mat[0][2]+vec[1]*mat[1][2]+vec[2]*mat[2][2]+mat[3][2];
++
++ // Check near clip plane
++ if ( eye[2] > radius ) {
++ return(0);
++ }
++
++ // Check far clip plane
++ if ( eye[2] + radius < -current_weather.get_visibility() ) {
++ return(0);
++ }
++
++ // check right clip plane (from eye perspective)
++ // y = m * (x - x0) = equation of a line intercepting X axis at x0
++ x1 = v->cos_fov_x * radius;
++ y1 = v->sin_fov_x * radius;
++ slope = v->slope_x;
++ eye[0] = vec[0]*mat[0][0]+vec[1]*mat[1][0]+vec[2]*mat[2][0]+mat[3][0];
++
++ if ( eye[2] > ((slope * (eye[0] - x1)) + y1) ) {
++ return( false );
++ }
++
++ // check left clip plane (from eye perspective)
++ if ( eye[2] > -((slope * (eye[0] + x1)) - y1) ) {
++ return( false );
++ }
++
++ // check bottom clip plane (from eye perspective)
++ x1 = -(v->cos_fov_y) * radius;
++ y1 = v->sin_fov_y * radius;
++ slope = v->slope_y;
++ eye[1] = vec[0]*mat[0][1]+vec[1]*mat[1][1]+vec[2]*mat[2][1]+mat[3][1];
++#undef vec
++#undef mat
++
++ if ( eye[2] > ((slope * (eye[1] - x1)) + y1) ) {
++ return( false );
++ }
++
++ // check top clip plane (from eye perspective)
++ if ( eye[2] > -((slope * (eye[1] + x1)) - y1) ) {
++ return( false );
++ }
++
++#endif // defined( USE_FAST_FOV_CLIP )
++
++ return(viewable);
++}
++
++
++// NEW
++
++// inrange() IS THIS POINT WITHIN POSSIBLE VIEWING RANGE ?
++// calculate distance from vertical tangent line at
++// current position to center of object.
++// this is equivalent to
++// dist = point_line_dist_squared( &(t->center), &(v->abs_view_pos),
++// v->local_up );
++// if ( dist < FG_SQUARE(t->bounding_radius) ) {
++//
++// the compiler should inline this for us
++
++static int
++inrange( const double radius, const Point3D& center, const Point3D& vp,
++ const MAT3vec up)
++{
++ MAT3vec u, u1, v;
++ // double tmp;
++
++ // u = p - p0
++ u[0] = center.x() - vp.x();
++ u[1] = center.y() - vp.y();
++ u[2] = center.z() - vp.z();
++
++ // calculate the projection, u1, of u along d.
++ // u1 = ( dot_prod(u, d) / dot_prod(d, d) ) * d;
++
++ MAT3_SCALE_VEC(u1, up,
++ (MAT3_DOT_PRODUCT(u, up) / MAT3_DOT_PRODUCT(up, up)) );
++
++ // v = u - u1 = vector from closest point on line, p1, to the
++ // original point, p.
++ MAT3_SUB_VEC(v, u, u1);
++
++ return( FG_SQUARE(radius) >= MAT3_DOT_PRODUCT(v, v));
++}
++
++
++// NEW for legibility
++
++// update this tile's geometry for current view
++// The Compiler should inline this
++static void
++update_tile_geometry( fgTILE *t, GLdouble *MODEL_VIEW)
++{
++ GLdouble *m;
++ double x, y, z;
++
++ // calculate tile offset
++ t->offset = t->center - scenery.center;
++
++ x = t->offset.x();
++ y = t->offset.y();
++ z = t->offset.z();
++
++ m = t->model_view;
++
++ // Calculate the model_view transformation matrix for this tile
++ FG_MEM_COPY( m, MODEL_VIEW, 16*sizeof(GLdouble) );
++
++ // This is equivalent to doing a glTranslatef(x, y, z);
++ m[12] += (m[0]*x + m[4]*y + m[8] *z);
++ m[13] += (m[1]*x + m[5]*y + m[9] *z);
++ m[14] += (m[2]*x + m[6]*y + m[10]*z);
++ // m[15] += (m[3]*x + m[7]*y + m[11]*z);
++ // m[3] m7[] m[11] are 0.0 see LookAt() in views.cxx
++ // so m[15] is unchanged
++}
++
++
++// Render the local tiles
++void fgTileMgrRender( void ) {
++ FGInterface *f;
++ fgTILECACHE *c;
++ fgTILE *t;
++ FGView *v;
++ Point3D frag_offset;
++ fgFRAGMENT *frag_ptr;
++ fgMATERIAL *mtl_ptr;
++ int i;
++ int tile_diameter;
++ int index;
++ int culled = 0;
++ int drawn = 0;
++
++ c = &global_tile_cache;
++ f = current_aircraft.fdm_state;
++ v = ¤t_view;
++
++ tile_diameter = current_options.get_tile_diameter();
++
++ // moved to fgTileMgrUpdate, right after we check if we need to
++ // load additional tiles:
++ // scenery.cur_elev = fgTileMgrCurElev( FG_Longitude, FG_Latitude,
++ // v->abs_view_pos );
++
++ // initialize the transient per-material fragment lists
++ material_mgr.init_transient_material_lists();
++
++ // Pass 1
++ // traverse the potentially viewable tile list
++ for ( i = 0; i < (tile_diameter * tile_diameter); i++ ) {
++ index = tiles[i];
++ // fgPrintf( FG_TERRAIN, FG_DEBUG, "Index = %d\n", index);
++ t = c->get_tile(index);
++
++ // calculate tile offset
++ t->SetOffset( scenery.center );
++
++ // Course (tile based) culling
++ if ( viewable(t->offset, t->bounding_radius) ) {
++ // at least a portion of this tile could be viewable
++
++ // Calculate the model_view transformation matrix for this tile
++ // This is equivalent to doing a glTranslatef(x, y, z);
++ t->UpdateViewMatrix( v->get_MODEL_VIEW() );
++
++ // xglPushMatrix();
++ // xglTranslatef(t->offset.x, t->offset.y, t->offset.z);
++
++ // traverse fragment list for tile
++ fgTILE::FragmentIterator current = t->begin();
++ fgTILE::FragmentIterator last = t->end();
++
++ for ( ; current != last; ++current ) {
++ frag_ptr = &(*current);
++
++ if ( frag_ptr->display_list >= 0 ) {
++ // Fine (fragment based) culling
++ frag_offset = frag_ptr->center - scenery.center;
++
++ if ( viewable(frag_offset, frag_ptr->bounding_radius*2) ) {
++ // add to transient per-material property fragment list
++ // frag_ptr->tile_offset.x = t->offset.x;
++ // frag_ptr->tile_offset.y = t->offset.y;
++ // frag_ptr->tile_offset.z = t->offset.z;
++
++ mtl_ptr = frag_ptr->material_ptr;
++ // printf(" lookup = %s\n", mtl_ptr->texture_name);
++ if ( ! mtl_ptr->append_sort_list( frag_ptr ) ) {
++ FG_LOG( FG_TERRAIN, FG_ALERT,
++ "Overran material sorting array" );
++ }
++
++ // xglCallList(frag_ptr->display_list);
++ drawn++;
++ } else {
++ // printf("Culled a fragment %.2f %.2f %.2f %.2f\n",
++ // frag_ptr->center.x, frag_ptr->center.y,
++ // frag_ptr->center.z, frag_ptr->bounding_radius);
++ culled++;
++ }
++ }
++ }
++
++ // xglPopMatrix();
++ } else {
++ culled += t->fragment_list.size();
++ }
++ }
++
++ if ( (drawn + culled) > 0 ) {
++ v->set_vfc_ratio( (double)culled / (double)(drawn + culled) );
++ } else {
++ v->set_vfc_ratio( 0.0 );
++ }
++ // printf("drawn = %d culled = %d saved = %.2f\n", drawn, culled,
++ // v->vfc_ratio);
++
++ // Pass 2
++ // traverse the transient per-material fragment lists and render
++ // out all fragments for each material property.
++ xglPushMatrix();
++ material_mgr.render_fragments();
++ xglPopMatrix();
++}
++
++
++// $Log$
++// Revision 1.55 1999/03/25 19:03:28 curt
++// Converted to use new bucket routines.
++//
++// Revision 1.54 1999/02/26 22:10:05 curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.53 1999/02/05 21:29:16 curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.52 1999/01/27 04:49:48 curt
++// Fixes so that the sim can start out at an airport below sea level.
++//
++// Revision 1.51 1998/12/09 18:50:33 curt
++// Converted "class fgVIEW" to "class FGView" and updated to make data
++// members private and make required accessor functions.
++//
++// Revision 1.50 1998/12/06 13:51:25 curt
++// Turned "struct fgWEATHER" into "class FGWeather".
++//
++// Revision 1.49 1998/12/05 15:54:26 curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.48 1998/12/05 14:20:21 curt
++// Looking into a terrain intersection problem.
++//
++// Revision 1.47 1998/12/05 14:11:19 curt
++// Sun portability tweak.
++//
++// Revision 1.46 1998/12/03 14:15:24 curt
++// Actually set the current scenery elevation based on scenery intersection point
++// rather than calculating the intesection point and throwing it away.
++//
++// Revision 1.45 1998/12/03 01:18:18 curt
++// Converted fgFLIGHT to a class.
++// Tweaks for Sun Portability.
++// Tweaked current terrain elevation code as per NHV.
++//
++// Revision 1.44 1998/11/23 21:49:48 curt
++// minor tweaks.
++//
++// Revision 1.43 1998/11/09 23:40:52 curt
++// Bernie Bright <bbright@c031.aone.net.au> writes:
++// I've made some changes to the Scenery handling. Basically just tidy ups.
++// The main difference is in tile.[ch]xx where I've changed list<fgFRAGMENT> to
++// vector<fgFRAGMENT>. Studying our usage patterns this seems reasonable.
++// Lists are good if you need to insert/delete elements randomly but we
++// don't do that. All access seems to be sequential. Two additional
++// benefits are smaller memory usage - each list element requires pointers
++// to the next and previous elements, and faster access - vector iterators
++// are smaller and faster than list iterators. This should also help
++// Charlie Hotchkiss' problem when compiling with Borland and STLport.
++//
++// ./Lib/Bucket/bucketutils.hxx
++// Convenience functions for fgBUCKET.
++//
++// ./Simulator/Scenery/tile.cxx
++// ./Simulator/Scenery/tile.hxx
++// Changed fragment list to a vector.
++// Added some convenience member functions.
++//
++// ./Simulator/Scenery/tilecache.cxx
++// ./Simulator/Scenery/tilecache.hxx
++// use const fgBUCKET& instead of fgBUCKET* where appropriate.
++//
++// ./Simulator/Scenery/tilemgr.cxx
++// ./Simulator/Scenery/tilemgr.hxx
++// uses all the new convenience functions.
++//
++// Revision 1.42 1998/11/06 21:18:23 curt
++// Converted to new logstream debugging facility. This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.41 1998/10/18 01:17:23 curt
++// Point3D tweaks.
++//
++// Revision 1.40 1998/10/17 01:34:28 curt
++// C++ ifying ...
++//
++// Revision 1.39 1998/10/16 00:55:50 curt
++// Converted to Point3D class.
++//
++// Revision 1.38 1998/09/17 18:36:18 curt
++// Tweaks and optimizations by Norman Vine.
++//
++// Revision 1.37 1998/09/15 01:36:45 curt
++// cleaned up my fragment.num_faces hack :-) to use the STL (no need in
++// duplicating work.)
++// Tweaked fgTileMgrRender() do not calc tile matrix unless necessary.
++// removed some unneeded stuff from fgTileMgrCurElev()
++//
++// Revision 1.36 1998/09/14 12:45:26 curt
++// minor tweaks.
++//
++// Revision 1.35 1998/09/10 19:07:16 curt
++// /Simulator/Objects/fragment.hxx
++// Nested fgFACE inside fgFRAGMENT since its not used anywhere else.
++//
++// ./Simulator/Objects/material.cxx
++// ./Simulator/Objects/material.hxx
++// Made fgMATERIAL and fgMATERIAL_MGR bona fide classes with private
++// data members - that should keep the rabble happy :)
++//
++// ./Simulator/Scenery/tilemgr.cxx
++// In viewable() delay evaluation of eye[0] and eye[1] in until they're
++// actually needed.
++// Change to fgTileMgrRender() to call fgMATERIAL_MGR::render_fragments()
++// method.
++//
++// ./Include/fg_stl_config.h
++// ./Include/auto_ptr.hxx
++// Added support for g++ 2.7.
++// Further changes to other files are forthcoming.
++//
++// Brief summary of changes required for g++ 2.7.
++// operator->() not supported by iterators: use (*i).x instead of i->x
++// default template arguments not supported,
++// <functional> doesn't have mem_fun_ref() needed by callbacks.
++// some std include files have different names.
++// template member functions not supported.
++//
++// Revision 1.34 1998/09/09 20:58:09 curt
++// Tweaks to loop constructs with STL usage.
++//
++// Revision 1.33 1998/09/08 15:05:10 curt
++// Optimization by Norman Vine.
++//
++// Revision 1.32 1998/08/25 16:52:44 curt
++// material.cxx material.hxx obj.cxx obj.hxx texload.c texload.h moved to
++// ../Objects
++//
++// Revision 1.31 1998/08/24 20:11:40 curt
++// Tweaks ...
++//
++// Revision 1.30 1998/08/22 14:49:59 curt
++// Attempting to iron out seg faults and crashes.
++// Did some shuffling to fix a initialization order problem between view
++// position, scenery elevation.
++//
++// Revision 1.29 1998/08/20 15:12:06 curt
++// Used a forward declaration of classes fgTILE and fgMATERIAL to eliminate
++// the need for "void" pointers and casts.
++// Quick hack to count the number of scenery polygons that are being drawn.
++//
++// Revision 1.28 1998/08/12 21:13:06 curt
++// material.cxx: don't load textures if they are disabled
++// obj.cxx: optimizations from Norman Vine
++// tile.cxx: minor tweaks
++// tile.hxx: addition of num_faces
++// tilemgr.cxx: minor tweaks
++//
++// Revision 1.27 1998/07/24 21:42:09 curt
++// material.cxx: whups, double method declaration with no definition.
++// obj.cxx: tweaks to avoid errors in SGI's CC.
++// tile.cxx: optimizations by Norman Vine.
++// tilemgr.cxx: optimizations by Norman Vine.
++//
++// Revision 1.26 1998/07/20 12:51:26 curt
++// Added far clip plane to fragment clipping calculations and tie this to
++// weather->visibility. This way you can increase framerates by increasing
++// for and lowering visibility.
++//
++// Revision 1.25 1998/07/13 21:02:01 curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.24 1998/07/12 03:18:29 curt
++// Added ground collision detection. This involved:
++// - saving the entire vertex list for each tile with the tile records.
++// - saving the face list for each fragment with the fragment records.
++// - code to intersect the current vertical line with the proper face in
++// an efficient manner as possible.
++// Fixed a bug where the tiles weren't being shifted to "near" (0,0,0)
++//
++// Revision 1.23 1998/07/08 14:47:23 curt
++// Fix GL_MODULATE vs. GL_DECAL problem introduced by splash screen.
++// polare3d.h renamed to polar3d.hxx
++// fg{Cartesian,Polar}Point3d consolodated.
++// Added some initial support for calculating local current ground elevation.
++//
++// Revision 1.22 1998/07/04 00:54:31 curt
++// Added automatic mipmap generation.
++//
++// When rendering fragments, use saved model view matrix from associated tile
++// rather than recalculating it with push() translate() pop().
++//
++// Revision 1.21 1998/06/27 16:54:59 curt
++// Check for GL_VERSION_1_1 or GL_EXT_texture_object to decide whether to use
++// "EXT" versions of texture management routines.
++//
++// Revision 1.20 1998/06/17 21:36:42 curt
++// Load and manage multiple textures defined in the Materials library.
++// Boost max material fagments for each material property to 800.
++// Multiple texture support when rendering.
++//
++// Revision 1.19 1998/06/08 17:57:54 curt
++// Working first pass at material proporty sorting.
++//
++// Revision 1.18 1998/06/06 01:09:32 curt
++// I goofed on the log message in the last commit ... now fixed.
++//
++// Revision 1.17 1998/06/06 01:07:18 curt
++// Increased per material fragment list size from 100 to 400.
++// Now correctly draw viewable fragments in per material order.
++//
++// Revision 1.16 1998/06/05 22:39:55 curt
++// Working on sorting by, and rendering by material properties.
++//
++// Revision 1.15 1998/06/03 00:47:51 curt
++// No .h for STL includes.
++// Minor view culling optimizations.
++//
++// Revision 1.14 1998/06/01 17:56:20 curt
++// Incremental additions to material.cxx (not fully functional)
++// Tweaked vfc_ratio math to avoid divide by zero.
++//
++// Revision 1.13 1998/05/24 02:49:10 curt
++// Implimented fragment level view frustum culling.
++//
++// Revision 1.12 1998/05/23 14:09:23 curt
++// Added tile.cxx and tile.hxx.
++// Working on rewriting the tile management system so a tile is just a list
++// fragments, and the fragment record contains the display list for that fragment.
++//
++// Revision 1.11 1998/05/20 20:53:55 curt
++// Moved global ref point and radius (bounding sphere info, and offset) to
++// data file rather than calculating it on the fly.
++// Fixed polygon winding problem in scenery generation stage rather than
++// compensating for it on the fly.
++// Made a fgTILECACHE class.
++//
++// Revision 1.10 1998/05/17 16:59:34 curt
++// Frist pass at view frustum culling now operational.
++//
++// Revision 1.9 1998/05/16 13:09:58 curt
++// Beginning to add support for view frustum culling.
++// Added some temporary code to calculate bouding radius, until the
++// scenery generation tools and scenery can be updated.
++//
++// Revision 1.8 1998/05/07 23:15:21 curt
++// Fixed a glTexImage2D() usage bug where width and height were mis-swapped.
++// Added support for --tile-radius=n option.
++//
++// Revision 1.7 1998/05/06 03:16:42 curt
++// Added an option to control square tile radius.
++//
++// Revision 1.6 1998/05/02 01:52:18 curt
++// Playing around with texture coordinates.
++//
++// Revision 1.5 1998/04/30 12:35:32 curt
++// Added a command line rendering option specify smooth/flat shading.
++//
++// Revision 1.4 1998/04/27 03:30:14 curt
++// Minor transformation adjustments to try to keep scenery tiles closer to
++// (0, 0, 0) GLfloats run out of precision at the distances we need to model
++// the earth, but we can do a bunch of pre-transformations using double math
++// and then cast to GLfloat once everything is close in where we have less
++// precision problems.
++//
++// Revision 1.3 1998/04/25 22:06:32 curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.2 1998/04/24 00:51:09 curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Tweaked the scenery file extentions to be "file.obj" (uncompressed)
++// or "file.obz" (compressed.)
++//
++// Revision 1.1 1998/04/22 13:22:48 curt
++// C++ - ifing the code a bit.
++//
++// Revision 1.25 1998/04/18 04:14:07 curt
++// Moved fg_debug.c to it's own library.
++//
++// Revision 1.24 1998/04/14 02:23:18 curt
++// Code reorganizations. Added a Lib/ directory for more general libraries.
++//
++// Revision 1.23 1998/04/08 23:30:08 curt
++// Adopted Gnu automake/autoconf system.
++//
++// Revision 1.22 1998/04/03 22:11:38 curt
++// Converting to Gnu autoconf system.
++//
++// Revision 1.21 1998/03/23 21:23:05 curt
++// Debugging output tweaks.
++//
++// Revision 1.20 1998/03/14 00:30:51 curt
++// Beginning initial terrain texturing experiments.
++//
++// Revision 1.19 1998/02/20 00:16:25 curt
++// Thursday's tweaks.
++//
++// Revision 1.18 1998/02/19 13:05:54 curt
++// Incorporated some HUD tweaks from Michelle America.
++// Tweaked the sky's sunset/rise colors.
++// Other misc. tweaks.
++//
++// Revision 1.17 1998/02/16 13:39:46 curt
++// Miscellaneous weekend tweaks. Fixed? a cache problem that caused whole
++// tiles to occasionally be missing.
++//
++// Revision 1.16 1998/02/12 21:59:53 curt
++// Incorporated code changes contributed by Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.14 1998/02/09 21:30:19 curt
++// Fixed a nagging problem with terrain tiles not "quite" matching up perfectly.
++//
++// Revision 1.13 1998/02/07 15:29:46 curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.12 1998/02/01 03:39:55 curt
++// Minor tweaks.
++//
++// Revision 1.11 1998/01/31 00:43:27 curt
++// Added MetroWorks patches from Carmen Volpe.
++//
++// Revision 1.10 1998/01/29 00:51:40 curt
++// First pass at tile cache, dynamic tile loading and tile unloading now works.
++//
++// Revision 1.9 1998/01/27 03:26:44 curt
++// Playing with new fgPrintf command.
++//
++// Revision 1.8 1998/01/27 00:48:04 curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.7 1998/01/26 15:55:25 curt
++// Progressing on building dynamic scenery system.
++//
++// Revision 1.6 1998/01/24 00:03:30 curt
++// Initial revision.
++//
++// Revision 1.5 1998/01/19 19:27:18 curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.4 1998/01/19 18:40:38 curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.3 1998/01/13 00:23:11 curt
++// Initial changes to support loading and management of scenery tiles. Note,
++// there's still a fair amount of work left to be done.
++//
++// Revision 1.2 1998/01/08 02:22:27 curt
++// Continue working on basic features.
++//
++// Revision 1.1 1998/01/07 23:50:51 curt
++// "area" renamed to "tile"
++//
++// Revision 1.2 1998/01/07 03:29:29 curt
++// Given an arbitrary lat/lon, we can now:
++// generate a unique index for the chunk containing the lat/lon
++// generate a path name to the chunk file
++// build a list of the indexes of all the nearby areas.
++//
++// Revision 1.1 1998/01/07 02:05:48 curt
++// Initial revision.
--- /dev/null
--- /dev/null
++// tilemgr.hxx -- routines to handle dynamic management of scenery tiles
++//
++// Written by Curtis Olson, started January 1998.
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#ifndef _TILEMGR_HXX
++#define _TILEMGR_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++
++#include <Bucket/newbucket.hxx>
++
++
++// Initialize the Tile Manager subsystem
++int fgTileMgrInit( void );
++
++
++// given the current lon/lat, fill in the array of local chunks. If
++// the chunk isn't already in the cache, then read it from disk.
++int fgTileMgrUpdate( void );
++
++
++// Determine scenery altitude. Normally this just happens when we
++// render the scene, but we'd also like to be able to do this
++// explicitely. lat & lon are in radians. abs_view_pos in meters.
++// Returns result in meters.
++double fgTileMgrCurElevNEW( const FGBucket& p );
++double fgTileMgrCurElev( double lon, double lat, const Point3D& abs_view_pos );
++
++
++// Render the local tiles --- hack, hack, hack
++void fgTileMgrRender( void );
++
++
++#endif // _TILEMGR_HXX
++
++
++// $Log$
++// Revision 1.8 1999/03/25 19:03:29 curt
++// Converted to use new bucket routines.
++//
++// Revision 1.7 1999/01/27 04:49:49 curt
++// Fixes so that the sim can start out at an airport below sea level.
++//
++// Revision 1.6 1998/12/03 01:18:19 curt
++// Converted fgFLIGHT to a class.
++// Tweaks for Sun Portability.
++// Tweaked current terrain elevation code as per NHV.
++//
++// Revision 1.5 1998/10/16 00:55:52 curt
++// Converted to Point3D class.
++//
++// Revision 1.4 1998/09/09 20:58:11 curt
++// Tweaks to loop constructs with STL usage.
++//
++// Revision 1.3 1998/08/22 14:49:59 curt
++// Attempting to iron out seg faults and crashes.
++// Did some shuffling to fix a initialization order problem between view
++// position, scenery elevation.
++//
++// Revision 1.2 1998/05/20 20:53:56 curt
++// Moved global ref point and radius (bounding sphere info, and offset) to
++// data file rather than calculating it on the fly.
++// Fixed polygon winding problem in scenery generation stage rather than
++// compensating for it on the fly.
++// Made a fgTILECACHE class.
++//
++// Revision 1.1 1998/04/22 13:22:49 curt
++// C++ - ifing the code a bit.
++//
++// Revision 1.6 1998/04/21 17:02:45 curt
++// Prepairing for C++ integration.
++//
++// Revision 1.5 1998/02/12 21:59:53 curt
++// Incorporated code changes contributed by Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.4 1998/01/22 02:59:42 curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.3 1998/01/19 18:40:38 curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.2 1998/01/13 00:23:11 curt
++// Initial changes to support loading and management of scenery tiles. Note,
++// there's still a fair amount of work left to be done.
++//
++// Revision 1.1 1998/01/07 23:50:51 curt
++// "area" renamed to "tile"
--- /dev/null
--- /dev/null
++--------------------------------------------------------------------------
++| Done
++--------------------------------------------------------------------------
++
++7/21/98 - add a --enable/disable-sound option.
++
++7/11/98 - Ground collision detection
++
++7/3/98 - Generate and store the transform matrix when rendering by
++ material property so we don't have to push, transform, pop
++ continually. See mesa code for gluLookAt()
++
++6/11/98 - convert to static libraries and reduce libtool usage ...
++
++6/11/98 - Converted to GL_FOG_EXP2
++
++5/29/98 - Widened edges of tiles to overlap a bit. This should help
++ reduce floating point induced gaps between tiles.
++
++5/27/98 - Rewrote airport list manager using an STL "map" (associative
++ array) for quick lookup.
++
++5/26/98 - Impose a maximum triangle area during scenery generation so
++ even very flat areas will get split into a few smaller sub
++ triangles.
++
++5/26/98 - Overhaul view parameter generation ... see if we can piggy
++ back off of larcsim calcs, and consolate potentially
++ redundant code -- Norman Vine
++
++5/24/98 - Fine grain view frustum culling
++
++5/20/98 - fix winding problem with tri-strips in obj.c (wait for next
++ version of stripe)
++
++5/17/98 - Course grain (tile based) view frustum culling
++
++5/6/98 - HUD updates from Jeff Goeke-Smith.
++
++5/5/98 - Added a visual frame rate counter on the HUD.
++
++5/2/98 - Option to go full screen. call glutFullScreen()
++
++4/29/98 - Option to toggle between smooth / flat shading.
++
++4/28/98 - Physically check if airport list overruns array size when loading.
++
++4/28/98 - Wrap up zlib so we can conditionally compile back in normal
++ behavior on systems that have trouble building zlib.
++
++4/27/98 - Do a better job of translating scenery tiles towards (0,0,0)
++
++4/27/98 - fgTIME fgVIEW struct -> typedef
++
++4/27/98 - Add a option to disable texturing.
++
++4/25/98 - Clean up initialization sequence and eliminate
++ interdependencies between lighting and position.
++
++4/23/98 - encapsulate all #include <config.h>'s with #ifdef HAVE_CONFIG_H
++
++4/23/98 - Give all textured polygons ambient and diffuse glMaterial()
++ properties of "white" so GL_MODULATE works as expected and
++ textures are not oddly tinted.
++
++4/21/98 - Convert lighting equations to table lookups
++
++4/21/98 - Make sure all #ifdef _cplusplus are after any other includes
++ Make sure all .hxx files have #ifndef cplusplus #error
++
++4/21/98 - various autoconf cleanups/preparation for C++
++
++4/9/98 - Fixed a bug in event management where the next event run time
++ was miscalculated so it was never run.
++
++4/6/98 - Cleanups
++
++--------------------------------------------------------------------------
++
++4/3/98 - Released version 0.40
++
++4/3/98 - Incorporated the Gnu automake/autoconf/libtool system.
++
++3/17/98 - Fix time jumping problem on win32
++
++3/1/98 - Unify sun position render code with existing sunpos
++ calculations so the sun doesn't do it's little jump every
++ hour.
++
++2/19/98 - Fixed a problem with smooth view (scenery center) switch
++ when entering a new tile.
++
++2/18/98 - Fixed a problem with terrain generation that was causing
++ some strips to be put in the wrong winding list.
++
++2/9/98 - Fixed a problem with terrain tiles not quite matching up perfectly.
++
++2/2/98 - Fix warning when compiling with c++ ... also successfully built
++ with cygnus-g++. There should be nothing holding us back from
++ using C++.
++
++1/30/98 - remove Scenery/geometry.c and Scenery/mesh.c
++
++1/28/98 - Dynamic unloading of scenery.
++
++1/26/98 - Debug message system.
++
++1/26/98 - Dynamic loading of scenery
++
++1/24/98 - Remove some of the unused files such as ls_sync.c
++
++1/23/98 - in all .h's change #ifdef FILE_H -> #ifdef _FILE_H
++
++--------------------------------------------------------------------------
++
++1/22/98 - Released version 0.25
++
++1/19/98 - Compile with c++
++
++1/17/98 - Change all "type function();" to "type function( void );"
++
++--------------------------------------------------------------------------
++
++1/16/98 - Release verison 0.23
++
++1/6/98 - Added FGwin32.mak (a MSVC++ Makefile for building win32 versions)
++
++--------------------------------------------------------------------------
++
++1/5/98 - Released version 0.21
++
++12/31/97 - remove Unix dependencies from .../Time/fg_time.c
++
++--------------------------------------------------------------------------
++
++12/30/97 - Released version 0.20
++
++12/30/97 - Released version 0.19
++
++12/30/97 - Event manager
++
++12/23/97 - First stab at a reasonable sky ... I'm going to probably
++ leave this for now so I don't spend the rest of my life
++ trying to tweak it.
++
++12/17/97 - Released version 0.18
++
++12/17/97 - Fix sun/moon initialization code so display lists aren't
++ re-created at every Init().
++
++12/12/97 - Released verison 0.17
++
++12/10/97 - Released version 0.16
++
++12/9/97 - Released demtools version 0.01
++
++12/9/97 - Released version 0.15
++
++11/25/97 - Released version 0.14
++
++10/24/97 - Released version 0.13
++
++9/22/97 - Released version 0.12
++
++9/16/97 - Released version 0.11
++
--- /dev/null
--- /dev/null
++SUBDIRS = \
++ Aircraft \
++ Airports \
++ Astro \
++ Autopilot \
++ Cockpit \
++ Controls \
++ FDM \
++ GUI \
++ Joystick \
++ Objects \
++ Scenery \
++ Time \
++ Weather \
++ Main
--- /dev/null
--- /dev/null
++--------------------------------------------------------------------------
++| Todo
++--------------------------------------------------------------------------
++
++ - M82, HSV , 3M5
++ Charlie Scanlon (757) 864-2034 LaRC
++ Geotif - geolocation tools for mapping.
++ Dr. Nevan Bryant (818) 354-7236
++ Position Integrity -- Terravoid Bob Servano (714) 854-2643
++ http://www.jpl.nasa.gov/releases/98/damds3.html
++ Press release #
++ John G. Watson (818) 354-5011 release 98-52
++
++7/22/98 - add some trig debugging wrappers that can be #ifdef'd in
++ kind of like the xgl stuff. The debugging version can do
++ bounds checking and such.
++
++6/10/98 - problem with view culling when not looking forward. Need to
++ generate the correct matrix and work it into the calculations.
++
++6/10/98 - terrain generation - add an option to try to iteratively change
++ the error tolerance to try to generate "close" to a certain
++ number of vertices so that we can have consistent size, rendering
++ speed etc. among various terrain tiles.
++
++5/26/98 - Add version checking to scenery files
++
++4/25/98 - Roll all of Time/sunpos.cxx into Astro/sun.cxx
++
++4/21/98 - Tweak lighting parameter interpolation tables to better fit
++ "perceived" reality
++
++4/21/98 - Make sure all .hxx files have #ifndef cplusplus #error
++ Make sure all #ifdef _FILE_H or _FILE_HXX
++
++4/14/98 - Convert gl__() calls in Cockpit/ to xgl__() calls
++
++12/29/97 - Add a mechanism to parse additional command line options?
++ * No astronomy.
++ * Less detailed terrain.
++ * Texture - but no MIP-mapping.
++ * Texture - but no bilinear blending.
++
++12/29/97 - sky tweaking
++ Steve Baker writes:
++ So, by building the sky in the flattened shape, we can have it be
++ very foggy at the horizon and clear blue overhead.
++
++ The other important feature of this model is the colours. We
++ colour each vertex of the dish individually to allow for cute
++ sunsets, a darker blue overhead than at the horizon in daylight, a
++ gradual darkening of the sky as a function of altitude for very
++ high altitude flight - into space. Also we tint the horizon more
++ in the direction of the sun so that sunset starts where the sun
++ goes down - and the sky remains blue on the opposite side of the
++ sky - then as the sun gets lower, the colour spreads outwards all
++ around the sky and the black of night creeps in slowly from the
++ opposite side of the sky from the sunset.
++
++ We also like to tint the bottom edge of the sky with white - even
++ in broad daylight - so it looks fuzzy - even when there is very
++ little fog to achieve that effect.
++
++ We use a text file that contains a lookup table relating the sun
++ angle relative to the horizon to:
++
++ * The colour at the top of the sky dome,
++ * The colour of the horizon nearest to the sun
++ * The colour of the horizon farthest from the sun
++ * The colour of the texture environment blend for the clouds.
++ * The fog colour.
++
++ We can then tweak that file to set up all the conditions. The
++ realtime system interpolates the horizon colours all around the edge
++ of the sky.
--- /dev/null
--- /dev/null
++noinst_LIBRARIES = libSlew.a
++
++libSlew_a_SOURCES = slew.cxx slew.hxx
++
++INCLUDES += -I$(top_builddir) -I$(top_builddir)/Simulator
--- /dev/null
--- /dev/null
++// slew.cxx -- the "slew" flight model
++//
++// Written by Curtis Olson, started May 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$
++// (Log is kept at end of this file)
++
++
++#include <math.h>
++
++#include "slew.hxx"
++
++#include <FDM/flight.hxx>
++#include <Aircraft/aircraft.hxx>
++#include <Controls/controls.hxx>
++#include <Include/fg_constants.h>
++
++
++// reset flight params to a specific position
++void fgSlewInit(double pos_x, double pos_y, double pos_z, double heading) {
++ FGInterface *f;
++
++ f = current_aircraft.fdm_state;
++
++ /*
++ f->pos_x = pos_x;
++ f->pos_y = pos_y;
++ f->pos_z = pos_z;
++
++ f->vel_x = 0.0;
++ f->vel_y = 0.0;
++ f->vel_z = 0.0;
++
++ f->Phi = 0.0;
++ f->Theta = 0.0;
++ f->Psi = 0.0;
++
++ f->vel_Phi = 0.0;
++ f->vel_Theta = 0.0;
++ f->vel_Psi = 0.0;
++
++ f->Psi = heading;
++ */
++}
++
++
++// update position based on inputs, positions, velocities, etc.
++void fgSlewUpdate( void ) {
++ FGInterface *f;
++ FGControls *c;
++
++ f = current_aircraft.fdm_state;
++ c = current_aircraft.controls;
++
++ /* f->Psi += ( c->aileron / 8 );
++ if ( f->Psi > FG_2PI ) {
++ f->Psi -= FG_2PI;
++ } else if ( f->Psi < 0 ) {
++ f->Psi += FG_2PI;
++ }
++
++ f->vel_x = -c->elev;
++
++ f->pos_x = f->pos_x + (cos(f->Psi) * f->vel_x);
++ f->pos_y = f->pos_y + (sin(f->Psi) * f->vel_x); */
++}
++
++
++// $Log$
++// Revision 1.6 1999/02/05 21:29:05 curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.5 1999/02/01 21:33:33 curt
++// Renamed FlightGear/Simulator/Flight to FlightGear/Simulator/FDM since
++// Jon accepted my offer to do this and thought it was a good idea.
++//
++// Revision 1.4 1998/12/05 16:13:14 curt
++// Renamed class fgCONTROLS to class FGControls.
++//
++// Revision 1.3 1998/12/05 15:54:16 curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.2 1998/10/17 01:34:17 curt
++// C++ ifying ...
++//
++// Revision 1.1 1998/10/16 23:27:50 curt
++// C++-ifying.
++//
++// Revision 1.13 1998/04/25 22:06:29 curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.12 1998/04/08 23:35:30 curt
++// Tweaks to Gnu automake/autoconf system.
++//
++// Revision 1.11 1998/02/07 15:29:39 curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.10 1998/01/27 00:47:53 curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.9 1998/01/19 19:27:06 curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.8 1998/01/19 18:40:30 curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.7 1997/12/15 23:54:42 curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.6 1997/08/27 03:30:11 curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.5 1997/07/19 22:35:06 curt
++// Moved fiddled with PI to avoid compiler warnings.
++//
++// Revision 1.4 1997/06/21 17:12:51 curt
++// Capitalized subdirectory names.
++//
++// Revision 1.3 1997/05/29 22:40:00 curt
++// Working on incorporating the LaRCsim flight model.
++//
++// Revision 1.2 1997/05/29 12:30:19 curt
++// Some initial mods to work better in a timer environment.
++//
++// Revision 1.1 1997/05/29 02:29:42 curt
++// Moved to their own directory.
++//
++// Revision 1.2 1997/05/23 15:40:37 curt
++// Added GNU copyright headers.
++//
++// Revision 1.1 1997/05/16 16:04:45 curt
++// Initial revision.
++//
++
--- /dev/null
--- /dev/null
++// slew.hxx -- the "slew" flight model
++//
++// Written by Curtis Olson, started May 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$
++// (Log is kept at end of this file)
++
++
++#ifndef _SLEW_HXX
++#define _SLEW_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++
++// reset flight params to a specific position
++void fgSlewInit(double pos_x, double pos_y, double pos_z, double heading);
++
++// update position based on inputs, positions, velocities, etc.
++void fgSlewUpdate( void );
++
++
++#endif // _SLEW_HXX
++
++
++// $Log$
++// Revision 1.2 1998/10/17 01:34:18 curt
++// C++ ifying ...
++//
++// Revision 1.1 1998/10/16 23:27:52 curt
++// C++-ifying.
++//
++// Revision 1.4 1998/01/22 02:59:34 curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.3 1998/01/19 18:40:30 curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.2 1997/07/23 21:52:20 curt
++// Put comments around the text after an #endif for increased portability.
++//
++// Revision 1.1 1997/05/29 02:29:43 curt
++// Moved to their own directory.
++//
++// Revision 1.2 1997/05/23 15:40:38 curt
++// Added GNU copyright headers.
++//
++// Revision 1.1 1997/05/16 16:04:46 curt
++// Initial revision.
++//
++
--- /dev/null
--- /dev/null
++if HAVE_DAYLIGHT
++DEFS += -DHAVE_DAYLIGHT
++endif
++
++if HAVE_TIMEZONE
++DEFS += -DHAVE_TIMEZONE
++endif
++
++noinst_LIBRARIES = libTime.a
++
++libTime_a_SOURCES = \
++ event.cxx event.hxx \
++ fg_time.cxx fg_time.hxx \
++ fg_timer.cxx fg_timer.hxx \
++ light.cxx light.hxx \
++ moonpos.cxx moonpos.hxx \
++ sunpos.cxx sunpos.hxx \
++ timestamp.hxx
++
++INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib -I$(top_builddir)/Simulator
--- /dev/null
--- /dev/null
++// event.cxx -- Flight Gear periodic event scheduler
++//
++// Written by Curtis Olson, started December 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$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#include <string>
++
++#include "Include/compiler.h"
++
++#include STL_ALGORITHM
++#include STL_FUNCTIONAL
++
++#ifdef FG_HAVE_STD_INCLUDES
++# include <cstdio>
++# ifdef HAVE_STDLIB_H
++# include <cstdlib>
++# endif
++#else
++# include <stdio.h>
++# ifdef HAVE_STDLIB_H
++# include <stdlib.h>
++# endif
++#endif
++
++#if defined( HAVE_WINDOWS_H ) && defined(__MWERKS__)
++# include <windows.h> // For Metrowerks environment
++# include <winbase.h> // There is no ANSI/MSL time function that
++ // contains milliseconds
++#endif
++
++#include <Debug/logstream.hxx>
++
++#include "event.hxx"
++
++FG_USING_STD(for_each);
++FG_USING_STD(mem_fun);
++
++fgEVENT_MGR global_events;
++
++
++fgEVENT::fgEVENT( const string& desc,
++ const fgCallback& cb,
++ EventState evt_status,
++ int evt_interval )
++ : description(desc),
++ event_cb(cb.clone()),
++ status(evt_status),
++ interval(evt_interval),
++ cum_time(0),
++ min_time(100000),
++ max_time(0),
++ count(0)
++{
++}
++
++#if 0
++fgEVENT::fgEVENT( const fgEVENT& evt )
++ : description(evt.description),
++ event_cb(evt.event_cb),
++ status(evt.status),
++ interval(evt.interval),
++ last_run(evt.last_run),
++ current(evt.current),
++ next_run(evt.next_run),
++ cum_time(evt.cum_time),
++ min_time(evt.min_time),
++ max_time(evt.max_time),
++ count(evt.count)
++{
++}
++
++fgEVENT&
++fgEVENT::operator= ( const fgEVENT& evt )
++{
++ if ( this != &evt )
++ {
++ description = evt.description;
++ event_cb = evt.event_cb;
++ status = evt.status;
++ interval = evt.interval;
++ last_run = evt.last_run;
++ current = evt.current;
++ next_run = evt.next_run;
++ cum_time = evt.cum_time;
++ min_time = evt.min_time;
++ max_time = evt.max_time;
++ count = evt.count;
++ }
++ return *this;
++}
++#endif
++
++fgEVENT::~fgEVENT()
++{
++ delete event_cb;
++}
++
++void
++fgEVENT::run()
++{
++ FG_LOG(FG_EVENT, FG_INFO, "Running " << description );
++
++ // record starting time
++ last_run.stamp();
++
++ // run the event
++ event_cb->call( (void**)NULL );
++
++ // increment the counter for this event
++ count++;
++
++ // update the event status
++ status = FG_EVENT_READY;
++
++ // calculate duration and stats
++ current.stamp();
++ long duration = current - last_run;
++
++ cum_time += duration;
++
++ if ( duration < min_time ) {
++ min_time = duration;
++ }
++
++ if ( duration > max_time ) {
++ max_time = duration;
++ }
++
++ // determine the next absolute run time
++ next_run = last_run + interval;
++}
++
++
++// Dump scheduling stats
++int
++fgEVENT::PrintStats() const
++{
++ FG_LOG( FG_EVENT, FG_INFO,
++ " " << description
++ << " int=" << interval / 1000.0
++ << " cum=" << cum_time
++ << " min=" << min_time
++ << " max=" << max_time
++ << " count=" << count
++ << " ave=" << cum_time / (double)count );
++ return 0;
++}
++
++// Constructor
++fgEVENT_MGR::fgEVENT_MGR( void ) {
++}
++
++
++// Initialize the scheduling subsystem
++void fgEVENT_MGR::Init( void ) {
++ FG_LOG(FG_EVENT, FG_INFO, "Initializing event manager" );
++
++ run_queue.erase( run_queue.begin(), run_queue.end() );
++ event_table.erase( event_table.begin(), event_table.end() );
++}
++
++
++// Register an event with the scheduler.
++void
++fgEVENT_MGR::Register( const string& desc,
++ const fgCallback& cb,
++ fgEVENT::EventState status,
++ int interval )
++{
++ // convert interval specified in milleseconds to usec
++ fgEVENT* e = new fgEVENT( desc, cb, status, interval * 1000 );
++
++ FG_LOG( FG_EVENT, FG_INFO, "Registering event: " << desc );
++
++ // Actually run the event
++ e->run();
++
++ // Now add to event_table
++ event_table.push_back(e);
++}
++
++
++// Update the scheduling parameters for an event
++void fgEVENT_MGR::Update( void ) {
++}
++
++
++// Delete a scheduled event
++void fgEVENT_MGR::Delete( void ) {
++}
++
++
++// Temporarily suspend scheduling of an event
++void fgEVENT_MGR::Suspend( void ) {
++}
++
++
++// Resume scheduling and event
++void fgEVENT_MGR::Resume( void ) {
++}
++
++// Dump scheduling stats
++void
++fgEVENT_MGR::PrintStats()
++{
++ FG_LOG( FG_EVENT, FG_INFO, "" );
++ FG_LOG( FG_EVENT, FG_INFO, "Event Stats" );
++ FG_LOG( FG_EVENT, FG_INFO, "-----------" );
++
++ ConstEventIterator first = event_table.begin();
++ ConstEventIterator last = event_table.end();
++ while ( first != last )
++ {
++ (*first)->PrintStats();
++ ++first;
++ }
++#if 0 // msvc++ 6.0 barfs at mem_fun()
++ for_each( event_table.begin(),
++ event_table.end(),
++ mem_fun( &fgEVENT::PrintStats ) );
++#endif
++ FG_LOG( FG_EVENT, FG_INFO, "");
++}
++
++
++// Add pending jobs to the run queue and run the job at the front of
++// the queue
++void fgEVENT_MGR::Process( void ) {
++ fgEVENT *e_ptr;
++ FGTimeStamp cur_time;
++ unsigned int i, size;
++
++ FG_LOG( FG_EVENT, FG_DEBUG, "Processing events" );
++
++ // get the current time
++ cur_time.stamp();
++
++ FG_LOG( FG_EVENT, FG_DEBUG,
++ " Current timestamp = " << cur_time.get_seconds() );
++
++ // printf("Checking if anything is ready to move to the run queue\n");
++
++ // see if anything else is ready to be placed on the run queue
++ size = event_table.size();
++ // while ( current != last ) {
++ for ( i = 0; i < size; i++ ) {
++ // e = *current++;
++ e_ptr = event_table[i];
++ if ( e_ptr->status == fgEVENT::FG_EVENT_READY ) {
++ FG_LOG( FG_EVENT, FG_DEBUG,
++ " Item " << i << " current " << cur_time.get_seconds()
++ << " next run @ " << e_ptr->next_run.get_seconds() );
++ if ( ( e_ptr->next_run - cur_time ) <= 0 ) {
++ run_queue.push_back(e_ptr);
++ e_ptr->status = fgEVENT::FG_EVENT_QUEUED;
++ }
++ }
++ }
++
++ // Checking to see if there is anything on the run queue
++ // printf("Checking to see if there is anything on the run queue\n");
++ if ( run_queue.size() ) {
++ // printf("Yep, running it\n");
++ e_ptr = run_queue.front();
++ run_queue.pop_front();
++ e_ptr->run();
++ }
++}
++
++
++// Destructor
++fgEVENT_MGR::~fgEVENT_MGR( void ) {
++ EventIterator first = event_table.begin();
++ EventIterator last = event_table.end();
++ for ( ; first != last; ++first )
++ {
++ delete (*first);
++ }
++
++ run_queue.erase( run_queue.begin(), run_queue.end() );
++ event_table.erase( event_table.begin(), event_table.end() );
++}
++
++
++// $Log$
++// Revision 1.17 1999/01/27 04:50:18 curt
++// Move sun/solaris specific stuff to compiler.h
++//
++// Revision 1.16 1999/01/21 20:14:18 curt
++// Sun portability hack.
++//
++// Revision 1.15 1999/01/09 13:37:42 curt
++// Convert fgTIMESTAMP to FGTimeStamp which holds usec instead of ms.
++//
++// Revision 1.14 1999/01/07 20:25:32 curt
++// Portability changes and updates from Bernie Bright.
++//
++// Revision 1.13 1998/12/04 01:32:46 curt
++// Converted "struct fg_timestamp" to "class fgTIMESTAMP" and added some
++// convenience inline operators.
++//
++// Revision 1.12 1998/11/23 21:49:07 curt
++// Borland portability tweaks.
++//
++// Revision 1.11 1998/11/09 23:41:51 curt
++// Log message clean ups.
++//
++// Revision 1.10 1998/11/07 19:07:13 curt
++// Enable release builds using the --without-logging option to the configure
++// script. Also a couple log message cleanups, plus some C to C++ comment
++// conversion.
++//
++// Revision 1.9 1998/11/06 21:18:24 curt
++// Converted to new logstream debugging facility. This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.8 1998/09/15 02:09:29 curt
++// Include/fg_callback.hxx
++// Moved code inline to stop g++ 2.7 from complaining.
++//
++// Simulator/Time/event.[ch]xx
++// Changed return type of fgEVENT::printStat(). void caused g++ 2.7 to
++// complain bitterly.
++//
++// Minor bugfix and changes.
++//
++// Simulator/Main/GLUTmain.cxx
++// Added missing type to idle_state definition - eliminates a warning.
++//
++// Simulator/Main/fg_init.cxx
++// Changes to airport lookup.
++//
++// Simulator/Main/options.cxx
++// Uses fg_gzifstream when loading config file.
++//
++// Revision 1.7 1998/08/29 13:11:31 curt
++// Bernie Bright writes:
++// I've created some new classes to enable pointers-to-functions and
++// pointers-to-class-methods to be treated like objects. These objects
++// can be registered with fgEVENT_MGR.
++//
++// File "Include/fg_callback.hxx" contains the callback class defns.
++//
++// Modified fgEVENT and fgEVENT_MGR to use the callback classes. Also
++// some minor tweaks to STL usage.
++//
++// Added file "Include/fg_stl_config.h" to deal with STL portability
++// issues. I've added an initial config for egcs (and probably gcc-2.8.x).
++// I don't have access to Visual C++ so I've left that for someone else.
++// This file is influenced by the stl_config.h file delivered with egcs.
++//
++// Added "Include/auto_ptr.hxx" which contains an implementation of the
++// STL auto_ptr class which is not provided in all STL implementations
++// and is needed to use the callback classes.
++//
++// Deleted fgLightUpdate() which was just a wrapper to call
++// fgLIGHT::Update().
++//
++// Modified fg_init.cxx to register two method callbacks in place of the
++// old wrapper functions.
++//
++// Revision 1.6 1998/08/20 15:12:26 curt
++// Tweak ...
++//
++// Revision 1.5 1998/06/12 00:59:52 curt
++// Build only static libraries.
++// Declare memmove/memset for Sloaris.
++// Rewrote fg_time.c routine to get LST start seconds to better handle
++// Solaris, and be easier to port, and understand the GMT vs. local
++// timezone issues.
++//
++// Revision 1.4 1998/06/05 18:18:12 curt
++// Incorporated some automake conditionals to try to support mktime() correctly
++// on a wider variety of platforms.
++// Added the declaration of memmove needed by the stl which apparently
++// solaris only defines for cc compilations and not for c++ (__STDC__)
++//
++// Revision 1.3 1998/05/22 21:14:53 curt
++// Rewrote event.cxx in C++ as a class using STL for the internal event list
++// and run queue this removes the arbitrary list sizes and makes things much
++// more dynamic. Because this is C++-classified we can now have multiple
++// event_tables if we'd ever want them.
++//
++// Revision 1.2 1998/04/25 22:06:33 curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.1 1998/04/24 00:52:26 curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Fog color fixes.
++// Separated out lighting calcs into their own file.
++//
++// Revision 1.13 1998/04/18 04:14:08 curt
++// Moved fg_debug.c to it's own library.
++//
++// Revision 1.12 1998/04/09 18:40:13 curt
++// We had unified some of the platform disparate time handling code, and
++// there was a bug in timesum() which calculated a new time stamp based on
++// the current time stamp + offset. This hosed the periodic event processing
++// logic because you'd never arrive at the time the event was scheduled for.
++// Sky updates and lighting changes are handled via this event mechanism so
++// they never changed ... it is fixed now.
++//
++// Revision 1.11 1998/04/03 22:12:55 curt
++// Converting to Gnu autoconf system.
++// Centralized time handling differences.
++//
++// Revision 1.10 1998/03/14 00:28:34 curt
++// replaced a printf() with an fgPrintf().
++//
++// Revision 1.9 1998/01/31 00:43:44 curt
++// Added MetroWorks patches from Carmen Volpe.
++//
++// Revision 1.8 1998/01/27 00:48:05 curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.7 1998/01/19 19:27:19 curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.6 1998/01/19 18:40:39 curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.5 1998/01/06 01:20:27 curt
++// Tweaks to help building with MSVC++
++//
++// Revision 1.4 1997/12/31 17:46:50 curt
++// Tweaked fg_time.c to be able to use ftime() instead of gettimeofday()
++//
++// Revision 1.3 1997/12/30 22:22:42 curt
++// Further integration of event manager.
++//
++// Revision 1.2 1997/12/30 20:47:58 curt
++// Integrated new event manager with subsystem initializations.
++//
++// Revision 1.1 1997/12/30 04:19:22 curt
++// Initial revision.
--- /dev/null
--- /dev/null
++// event.hxx -- Flight Gear periodic event scheduler
++//
++// Written by Curtis Olson, started December 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$
++// (Log is kept at end of this file)
++
++
++#ifndef _EVENT_HXX
++#define _EVENT_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++
++#include <Include/compiler.h>
++#include <Include/fg_callback.hxx>
++
++#include <deque> // STL double ended queue
++#include <list> // STL list
++#include STL_STRING
++
++#include "fg_time.hxx"
++#include "timestamp.hxx"
++
++FG_USING_STD(deque);
++FG_USING_STD(list);
++FG_USING_STD(string);
++
++
++class fgEVENT
++{
++public:
++ enum EventState
++ {
++ FG_EVENT_SUSP = 0,
++ FG_EVENT_READY = 1,
++ FG_EVENT_QUEUED = 2
++ };
++
++ friend class fgEVENT_MGR;
++
++ fgEVENT() {} // Required by deque<>.
++
++ fgEVENT( const string& desc,
++ const fgCallback& cb,
++ EventState evt_status,
++ int evt_interval );
++
++ ~fgEVENT();
++
++ void run();
++
++// void PrintStats() const;
++ int PrintStats() const;
++
++private:
++ // not defined
++ fgEVENT( const fgEVENT& evt );
++ fgEVENT& operator= ( const fgEVENT& evt );
++
++private:
++
++ string description;
++
++ // The callback object.
++ fgCallback* event_cb;
++
++ EventState status; // status flag
++
++ long interval; // interval in ms between each iteration of this event
++
++ FGTimeStamp last_run;
++ FGTimeStamp current;
++ FGTimeStamp next_run;
++
++ long cum_time; // cumulative processor time of this event
++ long min_time; // time of quickest execution
++ long max_time; // time of slowest execution
++ long count; // number of times executed
++};
++
++
++class fgEVENT_MGR {
++
++ // Event table
++ typedef deque < fgEVENT* > EventContainer;
++ typedef EventContainer::iterator EventIterator;
++ typedef EventContainer::const_iterator ConstEventIterator;
++
++ EventContainer event_table;
++
++ // Run Queue
++ typedef list < fgEVENT * > RunContainer;
++
++ RunContainer run_queue;
++
++public:
++
++ // Constructor
++ fgEVENT_MGR ( void );
++
++ // Initialize the scheduling subsystem
++ void Init( void );
++
++ // Register an event with the scheduler
++ void Register( const string& desc, void (*event)( void ),
++ fgEVENT::EventState status, int interval) {
++ Register( desc, fgFunctionCallback(event), status, interval );
++ }
++
++ void Register( const string& desc,
++ const fgCallback& cb,
++ fgEVENT::EventState status,
++ int interval );
++
++ // Update the scheduling parameters for an event
++ void Update( void );
++
++ // Delete a scheduled event
++ void Delete( void );
++
++ // Temporarily suspend scheduling of an event
++ void Suspend( void );
++
++ // Resume scheduling and event
++ void Resume( void );
++
++ // Dump scheduling stats
++ void PrintStats( void );
++
++ // Add pending jobs to the run queue and run the job at the front
++ // of the queue
++ void Process( void );
++
++ // Destructor
++ ~fgEVENT_MGR ( void );
++};
++
++
++// Wrapper to dump scheduling stats
++void fgEventPrintStats( void );
++
++extern fgEVENT_MGR global_events;
++
++
++#endif // _EVENT_HXX
++
++
++// $Log$
++// Revision 1.18 1999/03/02 01:03:33 curt
++// Tweaks for building with native SGI compilers.
++//
++// Revision 1.17 1999/02/26 22:10:08 curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.16 1999/01/09 13:37:43 curt
++// Convert fgTIMESTAMP to FGTimeStamp which holds usec instead of ms.
++//
++// Revision 1.15 1999/01/07 20:25:33 curt
++// Portability changes and updates from Bernie Bright.
++//
++// Revision 1.14 1998/12/05 14:21:28 curt
++// Moved struct fg_timestamp to class fgTIMESTAMP and moved it's definition
++// to it's own file, timestamp.hxx.
++//
++// Revision 1.13 1998/12/04 01:32:47 curt
++// Converted "struct fg_timestamp" to "class fgTIMESTAMP" and added some
++// convenience inline operators.
++//
++// Revision 1.12 1998/10/16 00:56:08 curt
++// Converted to Point3D class.
++//
++// Revision 1.11 1998/09/15 02:09:30 curt
++// Include/fg_callback.hxx
++// Moved code inline to stop g++ 2.7 from complaining.
++//
++// Simulator/Time/event.[ch]xx
++// Changed return type of fgEVENT::printStat(). void caused g++ 2.7 to
++// complain bitterly.
++//
++// Minor bugfix and changes.
++//
++// Simulator/Main/GLUTmain.cxx
++// Added missing type to idle_state definition - eliminates a warning.
++//
++// Simulator/Main/fg_init.cxx
++// Changes to airport lookup.
++//
++// Simulator/Main/options.cxx
++// Uses fg_gzifstream when loading config file.
++//
++// Revision 1.10 1998/09/08 21:41:06 curt
++// Added constructor for fgEVENT.
++//
++// Revision 1.9 1998/09/02 14:37:45 curt
++// Renamed struct -> class.
++//
++// Revision 1.8 1998/08/29 13:11:32 curt
++// Bernie Bright writes:
++// I've created some new classes to enable pointers-to-functions and
++// pointers-to-class-methods to be treated like objects. These objects
++// can be registered with fgEVENT_MGR.
++//
++// File "Include/fg_callback.hxx" contains the callback class defns.
++//
++// Modified fgEVENT and fgEVENT_MGR to use the callback classes. Also
++// some minor tweaks to STL usage.
++//
++// Added file "Include/fg_stl_config.h" to deal with STL portability
++// issues. I've added an initial config for egcs (and probably gcc-2.8.x).
++// I don't have access to Visual C++ so I've left that for someone else.
++// This file is influenced by the stl_config.h file delivered with egcs.
++//
++// Added "Include/auto_ptr.hxx" which contains an implementation of the
++// STL auto_ptr class which is not provided in all STL implementations
++// and is needed to use the callback classes.
++//
++// Deleted fgLightUpdate() which was just a wrapper to call
++// fgLIGHT::Update().
++//
++// Modified fg_init.cxx to register two method callbacks in place of the
++// old wrapper functions.
++//
++// Revision 1.7 1998/07/30 23:48:54 curt
++// Sgi build tweaks.
++// Pause support.
++//
++// Revision 1.6 1998/07/24 21:42:25 curt
++// Output message tweaks.
++//
++// Revision 1.5 1998/07/13 21:02:07 curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.4 1998/06/12 00:59:52 curt
++// Build only static libraries.
++// Declare memmove/memset for Sloaris.
++// Rewrote fg_time.c routine to get LST start seconds to better handle
++// Solaris, and be easier to port, and understand the GMT vs. local
++// timezone issues.
++//
++// Revision 1.3 1998/06/03 00:48:12 curt
++// No .h for STL includes.
++//
++// Revision 1.2 1998/05/22 21:14:54 curt
++// Rewrote event.cxx in C++ as a class using STL for the internal event list
++// and run queue this removes the arbitrary list sizes and makes things much
++// more dynamic. Because this is C++-classified we can now have multiple
++// event_tables if we'd ever want them.
++//
++// Revision 1.1 1998/04/24 00:52:26 curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Fog color fixes.
++// Separated out lighting calcs into their own file.
++//
++// Revision 1.4 1998/04/21 17:01:43 curt
++// Fixed a problems where a pointer to a function was being passed around. In
++// one place this functions arguments were defined as ( void ) while in another
++// place they were defined as ( int ). The correct answer was ( int ).
++//
++// Prepairing for C++ integration.
++//
++// Revision 1.3 1998/01/22 02:59:43 curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.2 1998/01/19 18:40:39 curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.1 1997/12/30 04:19:22 curt
++// Initial revision.
++
--- /dev/null
--- /dev/null
++//
++// fg_time.cxx -- data structures and routines for managing time related stuff.
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#include <Include/compiler.h>
++
++#ifdef FG_HAVE_STD_INCLUDES
++# include <cmath>
++# include <cstdio>
++# include <cstdlib>
++# include <ctime>
++#else
++# include <math.h>
++# include <stdio.h>
++# include <stdlib.h>
++# include <time.h>
++#endif
++
++#ifdef HAVE_SYS_TIMEB_H
++# include <sys/timeb.h> // for ftime() and struct timeb
++#endif
++#ifdef HAVE_UNISTD_H
++# include <unistd.h> // for gettimeofday()
++#endif
++#ifdef HAVE_SYS_TIME_H
++# include <sys/time.h> // for get/setitimer, gettimeofday, struct timeval
++#endif
++
++#include <Debug/logstream.hxx>
++#include <Astro/sky.hxx>
++#include <Astro/solarsystem.hxx>
++#include <FDM/flight.hxx>
++#include <Include/fg_constants.h>
++#include <Main/options.hxx>
++#include <Time/light.hxx>
++
++#include "fg_time.hxx"
++
++
++#define DEGHR(x) ((x)/15.)
++#define RADHR(x) DEGHR(x*RAD_TO_DEG)
++
++// #define MK_TIME_IS_GMT 0 // default value
++// #define TIME_ZONE_OFFSET_WORK 0 // default value
++
++
++fgTIME cur_time_params;
++
++
++// Force an update of the sky and lighting parameters
++static void local_update_sky_and_lighting_params( void ) {
++ // fgSunInit();
++ SolarSystem::theSolarSystem->rebuild();
++ cur_light_params.Update();
++ fgSkyColorsInit();
++}
++
++
++// Initialize the time dependent variables
++void fgTimeInit(fgTIME *t) {
++ FG_LOG( FG_EVENT, FG_INFO, "Initializing Time" );
++
++ t->gst_diff = -9999.0;
++
++ FG_LOG( FG_EVENT, FG_DEBUG,
++ "time offset = " << current_options.get_time_offset() );
++
++ t->warp = current_options.get_time_offset();
++ t->warp_delta = 0;
++
++ t->pause = current_options.get_pause();
++}
++
++
++// given a date in months, mn, days, dy, years, yr, return the
++// modified Julian date (number of days elapsed since 1900 jan 0.5),
++// mjd. Adapted from Xephem.
++
++double cal_mjd (int mn, double dy, int yr) {
++ static double last_mjd, last_dy;
++ double mjd;
++ static int last_mn, last_yr;
++ int b, d, m, y;
++ long c;
++
++ if (mn == last_mn && yr == last_yr && dy == last_dy) {
++ mjd = last_mjd;
++ return(mjd);
++ }
++
++ m = mn;
++ y = (yr < 0) ? yr + 1 : yr;
++ if (mn < 3) {
++ m += 12;
++ y -= 1;
++ }
++
++ if (yr < 1582 || (yr == 1582 && (mn < 10 || (mn == 10 && dy < 15)))) {
++ b = 0;
++ } else {
++ int a;
++ a = y/100;
++ b = 2 - a + a/4;
++ }
++
++ if (y < 0) {
++ c = (long)((365.25*y) - 0.75) - 694025L;
++ } else {
++ c = (long)(365.25*y) - 694025L;
++ }
++
++ d = (int)(30.6001*(m+1));
++
++ mjd = b + c + d + dy - 0.5;
++
++ last_mn = mn;
++ last_dy = dy;
++ last_yr = yr;
++ last_mjd = mjd;
++
++ return(mjd);
++}
++
++
++// given an mjd, return greenwich mean sidereal time, gst
++
++double utc_gst (double mjd) {
++ double gst;
++ double day = floor(mjd-0.5)+0.5;
++ double hr = (mjd-day)*24.0;
++ double T, x;
++
++ T = ((int)(mjd - 0.5) + 0.5 - J2000)/36525.0;
++ x = 24110.54841 + (8640184.812866 + (0.093104 - 6.2e-6 * T) * T) * T;
++ x /= 3600.0;
++ gst = (1.0/SIDRATE)*hr + x;
++
++ FG_LOG( FG_EVENT, FG_DEBUG, " gst => " << gst );
++
++ return(gst);
++}
++
++
++// given Julian Date and Longitude (decimal degrees West) compute and
++// return Local Sidereal Time, in decimal hours.
++//
++// Provided courtesy of ecdowney@noao.edu (Elwood Downey)
++//
++
++double sidereal_precise (double mjd, double lng) {
++ double gst;
++ double lst;
++
++ /* printf ("Current Lst on JD %13.5f at %8.4f degrees West: ",
++ mjd + MJD0, lng); */
++
++ // convert to required internal units
++ lng *= DEG_TO_RAD;
++
++ // compute LST and print
++ gst = utc_gst (mjd);
++ lst = gst - RADHR (lng);
++ lst -= 24.0*floor(lst/24.0);
++ // printf ("%7.4f\n", lst);
++
++ // that's all
++ return (lst);
++}
++
++
++// Fix up timezone if using ftime()
++long int fix_up_timezone( long int timezone_orig ) {
++#if !defined( HAVE_GETTIMEOFDAY ) && defined( HAVE_FTIME )
++ // ftime() needs a little extra help finding the current timezone
++ struct timeb current;
++ ftime(¤t);
++ return( current.timezone * 60 );
++#else
++ return( timezone_orig );
++#endif
++}
++
++
++// Return time_t for Sat Mar 21 12:00:00 GMT
++//
++// I believe the mktime() has a SYSV vs. BSD behavior difference.
++//
++// The BSD style mktime() is nice because it returns its result
++// assuming you have specified the input time in GMT
++//
++// The SYSV style mktime() is a pain because it returns its result
++// assuming you have specified the input time in your local timezone.
++// Therefore you have to go to extra trouble to convert back to GMT.
++//
++// If you are having problems with incorrectly positioned astronomical
++// bodies, this is a really good place to start looking.
++
++time_t get_start_gmt(int year) {
++ struct tm mt;
++
++ // For now we assume that if daylight is not defined in
++ // /usr/include/time.h that we have a machine with a BSD behaving
++ // mktime()
++# if !defined(HAVE_DAYLIGHT)
++# define MK_TIME_IS_GMT 1
++# endif
++
++ // timezone seems to work as a proper offset for Linux & Solaris
++# if defined( __linux__ ) || defined( __sun__ )
++# define TIMEZONE_OFFSET_WORKS 1
++# endif
++
++ mt.tm_mon = 2;
++ mt.tm_mday = 21;
++ mt.tm_year = year;
++ mt.tm_hour = 12;
++ mt.tm_min = 0;
++ mt.tm_sec = 0;
++ mt.tm_isdst = -1; // let the system determine the proper time zone
++
++# if defined( MK_TIME_IS_GMT )
++ return ( mktime(&mt) );
++# else // ! defined ( MK_TIME_IS_GMT )
++
++ long int start = mktime(&mt);
++
++ FG_LOG( FG_EVENT, FG_DEBUG, "start1 = " << start );
++ // the ctime() call can screw up time progression on some versions
++ // of Linux
++ // fgPrintf( FG_EVENT, FG_DEBUG, "start2 = %s", ctime(&start));
++ FG_LOG( FG_EVENT, FG_DEBUG, "(tm_isdst = " << mt.tm_isdst << ")" );
++
++ timezone = fix_up_timezone( timezone );
++
++# if defined( TIMEZONE_OFFSET_WORKS )
++ FG_LOG( FG_EVENT, FG_DEBUG,
++ "start = " << start << ", timezone = " << timezone );
++ return( start - timezone );
++# else // ! defined( TIMEZONE_OFFSET_WORKS )
++
++ daylight = mt.tm_isdst;
++ if ( daylight > 0 ) {
++ daylight = 1;
++ } else if ( daylight < 0 ) {
++ FG_LOG( FG_EVENT, FG_WARN,
++ "OOOPS, problem in fg_time.cxx, no daylight savings info." );
++ }
++
++ long int offset = -(timezone / 3600 - daylight);
++
++ FG_LOG( FG_EVENT, FG_DEBUG, " Raw time zone offset = " << timezone );
++ FG_LOG( FG_EVENT, FG_DEBUG, " Daylight Savings = " << daylight );
++ FG_LOG( FG_EVENT, FG_DEBUG, " Local hours from GMT = " << offset );
++
++ long int start_gmt = start - timezone + (daylight * 3600);
++
++ FG_LOG( FG_EVENT, FG_DEBUG, " March 21 noon (CST) = " << start );
++
++ return ( start_gmt );
++# endif // ! defined( TIMEZONE_OFFSET_WORKS )
++# endif // ! defined ( MK_TIME_IS_GMT )
++}
++
++static char*
++format_time( const struct tm* p, char* buf )
++{
++ sprintf( buf, "%d/%d/%2d %d:%02d:%02d",
++ p->tm_mon, p->tm_mday, p->tm_year,
++ p->tm_hour, p->tm_min, p->tm_sec);
++ return buf;
++}
++
++// return a courser but cheaper estimate of sidereal time
++double sidereal_course(fgTIME *t, double lng) {
++ struct tm *gmt;
++ time_t start_gmt, now;
++ double diff, part, days, hours, lst;
++ char tbuf[64];
++
++ gmt = t->gmt;
++ now = t->cur_time;
++ start_gmt = get_start_gmt(gmt->tm_year);
++
++ FG_LOG( FG_EVENT, FG_DEBUG, " COURSE: GMT = " << format_time(gmt, tbuf) );
++ FG_LOG( FG_EVENT, FG_DEBUG, " March 21 noon (GMT) = " << start_gmt );
++
++ diff = (now - start_gmt) / (3600.0 * 24.0);
++
++ FG_LOG( FG_EVENT, FG_DEBUG,
++ " Time since 3/21/" << gmt->tm_year << " GMT = " << diff );
++
++ part = fmod(diff, 1.0);
++ days = diff - part;
++ hours = gmt->tm_hour + gmt->tm_min/60.0 + gmt->tm_sec/3600.0;
++
++ lst = (days - lng)/15.0 + hours - 12;
++
++ while ( lst < 0.0 ) {
++ lst += 24.0;
++ }
++
++ FG_LOG( FG_EVENT, FG_DEBUG,
++ " days = " << days << " hours = " << hours << " lon = "
++ << lng << " lst = " << lst );
++
++ return(lst);
++}
++
++
++// Update time variables such as gmt, julian date, and sidereal time
++void fgTimeUpdate(FGInterface *f, fgTIME *t) {
++ double gst_precise, gst_course;
++
++ FG_LOG( FG_EVENT, FG_DEBUG, "Updating time" );
++
++ // get current Unix calendar time (in seconds)
++ t->warp += t->warp_delta;
++ t->cur_time = time(NULL) + t->warp;
++ FG_LOG( FG_EVENT, FG_DEBUG,
++ " Current Unix calendar time = " << t->cur_time
++ << " warp = " << t->warp << " delta = " << t->warp_delta );
++
++ if ( t->warp_delta ) {
++ // time is changing so force an update
++ local_update_sky_and_lighting_params();
++ }
++
++ // get GMT break down for current time
++ t->gmt = gmtime(&t->cur_time);
++ FG_LOG( FG_EVENT, FG_DEBUG,
++ " Current GMT = " << t->gmt->tm_mon+1 << "/"
++ << t->gmt->tm_mday << "/" << t->gmt->tm_year << " "
++ << t->gmt->tm_hour << ":" << t->gmt->tm_min << ":"
++ << t->gmt->tm_sec );
++
++ // calculate modified Julian date
++ t->mjd = cal_mjd ((int)(t->gmt->tm_mon+1), (double)t->gmt->tm_mday,
++ (int)(t->gmt->tm_year + 1900));
++
++ // add in partial day
++ t->mjd += (t->gmt->tm_hour / 24.0) + (t->gmt->tm_min / (24.0 * 60.0)) +
++ (t->gmt->tm_sec / (24.0 * 60.0 * 60.0));
++
++ // convert "back" to Julian date + partial day (as a fraction of one)
++ t->jd = t->mjd + MJD0;
++ FG_LOG( FG_EVENT, FG_DEBUG, " Current Julian Date = " << t->jd );
++
++ // printf(" Current Longitude = %.3f\n", FG_Longitude * RAD_TO_DEG);
++
++ // Calculate local side real time
++ if ( t->gst_diff < -100.0 ) {
++ // first time through do the expensive calculation & cheap
++ // calculation to get the difference.
++ FG_LOG( FG_EVENT, FG_INFO, " First time, doing precise gst" );
++ t->gst = gst_precise = sidereal_precise(t->mjd, 0.00);
++ gst_course = sidereal_course(t, 0.00);
++ t->gst_diff = gst_precise - gst_course;
++
++ t->lst =
++ sidereal_course(t, -(f->get_Longitude() * RAD_TO_DEG)) + t->gst_diff;
++ } else {
++ // course + difference should drift off very slowly
++ t->gst = sidereal_course(t, 0.00) + t->gst_diff;
++ t->lst = sidereal_course(t, -(f->get_Longitude() * RAD_TO_DEG)) +
++ t->gst_diff;
++ }
++ FG_LOG( FG_EVENT, FG_DEBUG,
++ " Current lon=0.00 Sidereal Time = " << t->gst );
++ FG_LOG( FG_EVENT, FG_DEBUG,
++ " Current LOCAL Sidereal Time = " << t->lst << " ("
++ << sidereal_precise(t->mjd, -(f->get_Longitude() * RAD_TO_DEG))
++ << ") (diff = " << t->gst_diff << ")" );
++}
++
++
++// $Log$
++// Revision 1.32 1999/02/26 22:10:10 curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.31 1999/02/05 21:29:18 curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.30 1999/02/01 21:33:37 curt
++// Renamed FlightGear/Simulator/Flight to FlightGear/Simulator/FDM since
++// Jon accepted my offer to do this and thought it was a good idea.
++//
++// Revision 1.29 1999/01/19 20:57:08 curt
++// MacOS portability changes contributed by "Robert Puyol" <puyol@abvent.fr>
++//
++// Revision 1.28 1999/01/07 20:25:34 curt
++// Portability changes and updates from Bernie Bright.
++//
++// Revision 1.27 1998/12/11 20:26:55 curt
++// #include tweaks.
++//
++// Revision 1.26 1998/12/05 15:54:28 curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.25 1998/12/05 14:21:30 curt
++// Moved struct fg_timestamp to class fgTIMESTAMP and moved it's definition
++// to it's own file, timestamp.hxx.
++//
++// Revision 1.24 1998/12/04 01:32:49 curt
++// Converted "struct fg_timestamp" to "class fgTIMESTAMP" and added some
++// convenience inline operators.
++//
++// Revision 1.23 1998/12/03 01:18:40 curt
++// Converted fgFLIGHT to a class.
++//
++// Revision 1.22 1998/11/16 14:00:28 curt
++// FG_LOG() message tweaks.
++//
++// Revision 1.21 1998/11/06 21:18:26 curt
++// Converted to new logstream debugging facility. This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.20 1998/11/02 18:25:38 curt
++// Check for __CYGWIN__ (b20) as well as __CYGWIN32__ (pre b20 compilers)
++// Other misc. tweaks.
++//
++// Revision 1.19 1998/10/17 01:34:29 curt
++// C++ ifying ...
++//
++// Revision 1.18 1998/10/02 21:36:09 curt
++// Fixes to try to break through the win95/98 18.3 fps barrier.
++//
++// Revision 1.17 1998/09/15 04:27:49 curt
++// Changes for new astro code.
++//
++// Revision 1.16 1998/08/29 13:11:32 curt
++// Bernie Bright writes:
++// I've created some new classes to enable pointers-to-functions and
++// pointers-to-class-methods to be treated like objects. These objects
++// can be registered with fgEVENT_MGR.
++//
++// File "Include/fg_callback.hxx" contains the callback class defns.
++//
++// Modified fgEVENT and fgEVENT_MGR to use the callback classes. Also
++// some minor tweaks to STL usage.
++//
++// Added file "Include/fg_stl_config.h" to deal with STL portability
++// issues. I've added an initial config for egcs (and probably gcc-2.8.x).
++// I don't have access to Visual C++ so I've left that for someone else.
++// This file is influenced by the stl_config.h file delivered with egcs.
++//
++// Added "Include/auto_ptr.hxx" which contains an implementation of the
++// STL auto_ptr class which is not provided in all STL implementations
++// and is needed to use the callback classes.
++//
++// Deleted fgLightUpdate() which was just a wrapper to call
++// fgLIGHT::Update().
++//
++// Modified fg_init.cxx to register two method callbacks in place of the
++// old wrapper functions.
++//
++// Revision 1.15 1998/08/24 20:12:16 curt
++// Rewrote sidereal_course with simpler parameters.
++//
++// Revision 1.14 1998/08/05 00:20:07 curt
++// Added a local routine to update lighting params every frame when time is
++// accelerated.
++//
++// Revision 1.13 1998/07/30 23:48:55 curt
++// Sgi build tweaks.
++// Pause support.
++//
++// Revision 1.12 1998/07/27 18:42:22 curt
++// Added a pause option.
++//
++// Revision 1.11 1998/07/22 21:45:37 curt
++// fg_time.cxx: Removed call to ctime() in a printf() which should be harmless
++// but seems to be triggering a bug.
++// light.cxx: Added code to adjust fog color based on sunrise/sunset effects
++// and view orientation. This is an attempt to match the fog color to the
++// sky color in the center of the screen. You see discrepancies at the
++// edges, but what else can be done?
++// sunpos.cxx: Caculate local direction to sun here. (what compass direction
++// do we need to face to point directly at sun)
++//
++// Revision 1.10 1998/07/13 21:02:07 curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.9 1998/06/12 00:59:53 curt
++// Build only static libraries.
++// Declare memmove/memset for Sloaris.
++// Rewrote fg_time.c routine to get LST start seconds to better handle
++// Solaris, and be easier to port, and understand the GMT vs. local
++// timezone issues.
++//
++// Revision 1.8 1998/06/05 18:18:13 curt
++// Incorporated some automake conditionals to try to support mktime() correctly
++// on a wider variety of platforms.
++// Added the declaration of memmove needed by the stl which apparently
++// solaris only defines for cc compilations and not for c++ (__STDC__)
++//
++// Revision 1.7 1998/05/30 01:57:25 curt
++// misc updates.
++//
++// Revision 1.6 1998/05/02 01:53:17 curt
++// Fine tuning mktime() support because of varying behavior on different
++// platforms.
++//
++// Revision 1.5 1998/04/28 21:45:34 curt
++// Fixed a horible bug that cause the time to be *WAY* off when compiling
++// with the CygWin32 compiler. This may not yet completely address other
++// Win32 compilers, but we'll have to take them on a case by case basis.
++//
++// Revision 1.4 1998/04/28 01:22:16 curt
++// Type-ified fgTIME and fgVIEW.
++//
++// Revision 1.3 1998/04/25 22:06:33 curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.2 1998/04/25 20:24:02 curt
++// Cleaned up initialization sequence to eliminate interdependencies
++// between sun position, lighting, and view position. This creates a
++// valid single pass initialization path.
++//
++// Revision 1.1 1998/04/24 00:52:27 curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Fog color fixes.
++// Separated out lighting calcs into their own file.
++//
++// Revision 1.41 1998/04/22 13:24:05 curt
++// C++ - ifiing the code a bit.
++// Starting to reorginize some of the lighting calcs to use a table lookup.
++//
++// Revision 1.40 1998/04/18 04:14:09 curt
++// Moved fg_debug.c to it's own library.
++//
++// Revision 1.39 1998/04/09 18:40:14 curt
++// We had unified some of the platform disparate time handling code, and
++// there was a bug in timesum() which calculated a new time stamp based on
++// the current time stamp + offset. This hosed the periodic event processing
++// logic because you'd never arrive at the time the event was scheduled for.
++// Sky updates and lighting changes are handled via this event mechanism so
++// they never changed ... it is fixed now.
++//
++// Revision 1.38 1998/04/08 23:35:40 curt
++// Tweaks to Gnu automake/autoconf system.
++//
++// Revision 1.37 1998/04/03 22:12:55 curt
++// Converting to Gnu autoconf system.
++// Centralized time handling differences.
++//
++// Revision 1.36 1998/03/09 22:48:09 curt
++// Debug message tweaks.
++//
++// Revision 1.35 1998/02/09 15:07:52 curt
++// Minor tweaks.
++//
++// Revision 1.34 1998/02/07 15:29:47 curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.33 1998/02/02 20:54:04 curt
++// Incorporated Durk's changes.
++//
++// Revision 1.32 1998/02/01 03:39:56 curt
++// Minor tweaks.
++//
++// Revision 1.31 1998/01/27 00:48:06 curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.30 1998/01/21 21:11:35 curt
++// Misc. tweaks.
++//
++// Revision 1.29 1998/01/19 19:27:20 curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.28 1998/01/19 18:35:49 curt
++// Minor tweaks and fixes for cygwin32.
++//
++// Revision 1.27 1998/01/13 00:23:13 curt
++// Initial changes to support loading and management of scenery tiles. Note,
++// there's still a fair amount of work left to be done.
++//
++// Revision 1.26 1998/01/05 18:44:36 curt
++// Add an option to advance/decrease time from keyboard.
++//
++// Revision 1.25 1997/12/31 17:46:50 curt
++// Tweaked fg_time.c to be able to use ftime() instead of gettimeofday()
++//
++// Revision 1.24 1997/12/30 22:22:42 curt
++// Further integration of event manager.
++//
++// Revision 1.23 1997/12/30 20:47:58 curt
++// Integrated new event manager with subsystem initializations.
++//
++// Revision 1.22 1997/12/30 01:38:47 curt
++// Switched back to per vertex normals and smooth shading for terrain.
++//
++// Revision 1.21 1997/12/23 04:58:39 curt
++// Tweaked the sky coloring a bit to build in structures to allow finer rgb
++// control.
++//
++// Revision 1.20 1997/12/15 23:55:06 curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.19 1997/12/15 20:59:10 curt
++// Misc. tweaks.
++//
++// Revision 1.18 1997/12/12 21:41:31 curt
++// More light/material property tweaking ... still a ways off.
++//
++// Revision 1.17 1997/12/12 19:53:04 curt
++// Working on lightling and material properties.
++//
++// Revision 1.16 1997/12/11 04:43:57 curt
++// Fixed sun vector and lighting problems. I thing the moon is now lit
++// correctly.
++//
++// Revision 1.15 1997/12/10 22:37:54 curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.14 1997/12/10 01:19:52 curt
++// Tweaks for verion 0.15 release.
++//
++// Revision 1.13 1997/12/09 05:11:56 curt
++// Working on tweaking lighting.
++//
++// Revision 1.12 1997/12/09 04:25:37 curt
++// Working on adding a global lighting params structure.
++//
++// Revision 1.11 1997/11/25 19:25:40 curt
++// Changes to integrate Durk's moon/sun code updates + clean up.
++//
++// Revision 1.10 1997/11/15 18:16:42 curt
++// minor tweaks.
++//
++// Revision 1.9 1997/11/14 00:26:50 curt
++// Transform scenery coordinates earlier in pipeline when scenery is being
++// created, not when it is being loaded. Precalculate normals for each node
++// as average of the normals of each containing polygon so Garoude shading is
++// now supportable.
++//
++// Revision 1.8 1997/10/25 03:30:08 curt
++// Misc. tweaks.
++//
++// Revision 1.7 1997/09/23 00:29:50 curt
++// Tweaks to get things to compile with gcc-win32.
++//
++// Revision 1.6 1997/09/20 03:34:34 curt
++// Still trying to get those durned stars aligned properly.
++//
++// Revision 1.5 1997/09/16 22:14:52 curt
++// Tweaked time of day lighting equations. Don't draw stars during the day.
++//
++// Revision 1.4 1997/09/16 15:50:31 curt
++// Working on star alignment and time issues.
++//
++// Revision 1.3 1997/09/13 02:00:08 curt
++// Mostly working on stars and generating sidereal time for accurate star
++// placement.
++//
++// Revision 1.2 1997/08/27 03:30:35 curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.1 1997/08/13 21:55:59 curt
++// Initial revision.
++//
--- /dev/null
--- /dev/null
++//
++// fg_time.hxx -- data structures and routines for managing time related stuff.
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#ifndef _FG_TIME_HXX
++#define _FG_TIME_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++
++#include <GL/glut.h>
++
++#include "Include/compiler.h"
++#ifdef FG_HAVE_STD_INCLUDES
++# include <ctime>
++#else
++# include <time.h>
++#endif
++
++#include <FDM/flight.hxx>
++
++
++// Define a structure containing global time parameters
++typedef struct {
++ // the date/time in various forms
++ // Unix "calendar" time in seconds
++ time_t cur_time;
++
++ // Break down of GMT time
++ struct tm *gmt;
++
++ // Julian date
++ double jd;
++
++ // modified Julian date
++ double mjd;
++
++ // side real time at prime meridian
++ double gst;
++
++ // local side real time
++ double lst;
++
++ // the difference between the precise sidereal time algorithm
++ // result and the course result.
++ // course + diff has good accuracy for the short term
++ double gst_diff;
++
++ // An offset in seconds from the true time. Allows us to adjust
++ // the effective time of day.
++ long int warp;
++
++ // How much to change the value of warp each iteration. Allows us
++ // to make time progress faster than normal.
++ long int warp_delta;
++
++ // Paused (0 = no, 1 = yes)
++ int pause;
++} fgTIME;
++
++extern fgTIME cur_time_params;
++
++
++// Update time variables such as gmt, julian date, and sidereal time
++void fgTimeInit(fgTIME *t);
++
++
++// Update the time dependent variables
++void fgTimeUpdate(FGInterface *f, fgTIME *t);
++
++
++#endif // _FG_TIME_HXX
++
++
++// $Log$
++// Revision 1.14 1999/02/05 21:29:19 curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.13 1999/02/01 21:33:39 curt
++// Renamed FlightGear/Simulator/Flight to FlightGear/Simulator/FDM since
++// Jon accepted my offer to do this and thought it was a good idea.
++//
++// Revision 1.12 1999/01/07 20:25:35 curt
++// Portability changes and updates from Bernie Bright.
++//
++// Revision 1.11 1998/12/05 15:54:29 curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.10 1998/12/05 14:21:31 curt
++// Moved struct fg_timestamp to class fgTIMESTAMP and moved it's definition
++// to it's own file, timestamp.hxx.
++//
++// Revision 1.9 1998/12/04 01:32:50 curt
++// Converted "struct fg_timestamp" to "class fgTIMESTAMP" and added some
++// convenience inline operators.
++//
++// Revision 1.8 1998/10/16 23:28:00 curt
++// C++-ifying.
++//
++// Revision 1.7 1998/10/16 00:56:09 curt
++// Converted to Point3D class.
++//
++// Revision 1.6 1998/07/27 18:42:22 curt
++// Added a pause option.
++//
++// Revision 1.5 1998/05/22 21:14:54 curt
++// Rewrote event.cxx in C++ as a class using STL for the internal event list
++// and run queue this removes the arbitrary list sizes and makes things much
++// more dynamic. Because this is C++-classified we can now have multiple
++// event_tables if we'd ever want them.
++//
++// Revision 1.4 1998/04/28 01:22:17 curt
++// Type-ified fgTIME and fgVIEW.
++//
++// Revision 1.3 1998/04/25 22:06:34 curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.2 1998/04/25 20:24:03 curt
++// Cleaned up initialization sequence to eliminate interdependencies
++// between sun position, lighting, and view position. This creates a
++// valid single pass initialization path.
++//
++// Revision 1.1 1998/04/24 00:52:28 curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Fog color fixes.
++// Separated out lighting calcs into their own file.
++//
++// Revision 1.20 1998/04/22 13:24:05 curt
++// C++ - ifiing the code a bit.
++// Starting to reorginize some of the lighting calcs to use a table lookup.
++//
++// Revision 1.19 1998/04/21 17:01:44 curt
++// Fixed a problems where a pointer to a function was being passed around. In
++// one place this functions arguments were defined as ( void ) while in another
++// place they were defined as ( int ). The correct answer was ( int ).
++//
++// Prepairing for C++ integration.
++//
++// Revision 1.18 1998/04/08 23:35:40 curt
++// Tweaks to Gnu automake/autoconf system.
++//
++// Revision 1.17 1998/04/03 22:12:56 curt
++// Converting to Gnu autoconf system.
++// Centralized time handling differences.
++//
++// Revision 1.16 1998/02/07 15:29:47 curt
++// Incorporated HUD changes and struct/typedef changes from Charlie Hotchkiss
++// <chotchkiss@namg.us.anritsu.com>
++//
++// Revision 1.15 1998/01/27 00:48:06 curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.14 1998/01/22 02:59:43 curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.13 1998/01/19 19:27:20 curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.12 1998/01/05 18:44:37 curt
++// Add an option to advance/decrease time from keyboard.
++//
++// Revision 1.11 1997/12/19 23:35:07 curt
++// Lot's of tweaking with sky rendering and lighting.
++//
++// Revision 1.10 1997/12/15 23:55:07 curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.9 1997/12/10 22:37:55 curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.8 1997/12/09 04:25:38 curt
++// Working on adding a global lighting params structure.
++//
++// Revision 1.7 1997/11/25 19:25:41 curt
++// Changes to integrate Durk's moon/sun code updates + clean up.
++//
++// Revision 1.6 1997/09/20 03:34:35 curt
++// Still trying to get those durned stars aligned properly.
++//
++// Revision 1.5 1997/09/16 15:50:31 curt
++// Working on star alignment and time issues.
++//
++// Revision 1.4 1997/09/13 02:00:08 curt
++// Mostly working on stars and generating sidereal time for accurate star
++// placement.
++//
++// Revision 1.3 1997/09/04 02:17:39 curt
++// Shufflin' stuff.
++//
++// Revision 1.2 1997/08/27 03:30:36 curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.1 1997/08/13 21:56:00 curt
++// Initial revision.
++//
--- /dev/null
--- /dev/null
++// fg_timer.cxx -- time handling routines
++//
++// Written by Curtis Olson, started June 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$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#include <signal.h> // for timer routines
++#include <stdio.h> // for printf()
++
++#ifdef HAVE_STDLIB_H
++# include <stdlib.h>
++#endif
++
++#ifdef HAVE_SYS_TIME_H
++# include <sys/time.h> // for get/setitimer, gettimeofday, struct timeval
++#endif
++
++#include "fg_time.hxx"
++#include "fg_timer.hxx"
++#include "timestamp.hxx"
++
++
++unsigned long int fgSimTime;
++
++#ifdef HAVE_SETITIMER
++ static struct itimerval t, ot;
++ static void (*callbackfunc)(int multi_loop);
++
++
++// This routine catches the SIGALRM
++void fgTimerCatch( int dummy ) {
++ int warning_avoider;
++
++ // get past a compiler warning
++ warning_avoider = dummy;
++
++ // ignore any SIGALRM's until we come back from our EOM iteration
++ signal(SIGALRM, SIG_IGN);
++
++ // printf("In fgTimerCatch()\n");
++
++ // -1 tells the routine to use default interval rather than
++ // something dynamically calculated based on frame rate
++ callbackfunc(-1);
++
++ signal(SIGALRM, fgTimerCatch);
++}
++
++
++// this routine initializes the interval timer to generate a SIGALRM
++// after the specified interval (dt)
++void fgTimerInit(float dt, void (*f)( int )) {
++ int terr;
++ int isec;
++ int usec;
++
++ callbackfunc = f;
++
++ isec = (int) dt;
++ usec = 1000000 * ((int)dt - isec);
++
++ t.it_interval.tv_sec = isec;
++ t.it_interval.tv_usec = usec;
++ t.it_value.tv_sec = isec;
++ t.it_value.tv_usec = usec;
++ // printf("fgTimerInit() called\n");
++ fgTimerCatch(0); // set up for SIGALRM signal catch
++ terr = setitimer( ITIMER_REAL, &t, &ot );
++ if (terr) {
++ printf("Error returned from setitimer");
++ exit(0);
++ }
++}
++#endif // HAVE_SETITIMER
++
++
++// This function returns the number of microseconds since the last
++// time it was called.
++int fgGetTimeInterval( void ) {
++ int interval;
++ static int inited = 0;
++ static FGTimeStamp last;
++ FGTimeStamp current;
++
++ if ( ! inited ) {
++ inited = 1;
++ last.stamp();
++ interval = 0;
++ } else {
++ current.stamp();
++ interval = current - last;
++ last = current;
++ }
++
++ return(interval);
++}
++
++
++// $Log$
++// Revision 1.6 1999/01/09 13:37:45 curt
++// Convert fgTIMESTAMP to FGTimeStamp which holds usec instead of ms.
++//
++// Revision 1.5 1998/12/05 14:21:32 curt
++// Moved struct fg_timestamp to class fgTIMESTAMP and moved it's definition
++// to it's own file, timestamp.hxx.
++//
++// Revision 1.4 1998/12/04 01:32:51 curt
++// Converted "struct fg_timestamp" to "class fgTIMESTAMP" and added some
++// convenience inline operators.
++//
++// Revision 1.3 1998/04/28 01:22:18 curt
++// Type-ified fgTIME and fgVIEW.
++//
++// Revision 1.2 1998/04/25 20:24:03 curt
++// Cleaned up initialization sequence to eliminate interdependencies
++// between sun position, lighting, and view position. This creates a
++// valid single pass initialization path.
++//
++// Revision 1.1 1998/04/24 00:52:29 curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Fog color fixes.
++// Separated out lighting calcs into their own file.
++//
++// Revision 1.12 1998/04/21 17:01:44 curt
++// Fixed a problems where a pointer to a function was being passed around. In
++// one place this functions arguments were defined as ( void ) while in another
++// place they were defined as ( int ). The correct answer was ( int ).
++//
++// Prepairing for C++ integration.
++//
++// Revision 1.11 1998/04/03 22:12:56 curt
++// Converting to Gnu autoconf system.
++// Centralized time handling differences.
++//
++// Revision 1.10 1998/01/31 00:43:45 curt
++// Added MetroWorks patches from Carmen Volpe.
++//
++// Revision 1.9 1998/01/19 19:27:21 curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.8 1998/01/19 18:40:39 curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.7 1997/12/30 13:06:58 curt
++// A couple lighting tweaks ...
++//
++// Revision 1.6 1997/07/12 02:13:04 curt
++// Add ftime() support for those that don't have gettimeofday()
++//
++// Revision 1.5 1997/06/26 19:08:38 curt
++// Restructuring make, adding automatic "make dep" support.
++//
++// Revision 1.4 1997/06/25 15:39:49 curt
++// Minor changes to compile with rsxnt/win32.
++//
++// Revision 1.3 1997/06/17 16:52:04 curt
++// Timer interval stuff now uses gettimeofday() instead of ftime()
++//
++// Revision 1.2 1997/06/17 03:41:10 curt
++// Nonsignal based interval timing is now working.
++// This would be a good time to look at cleaning up the code structure a bit.
++//
++// Revision 1.1 1997/06/16 19:24:20 curt
++// Initial revision.
++//
++
--- /dev/null
--- /dev/null
++/**************************************************************************
++ * fg_timer.hxx -- time handling routines
++ *
++ * Written by Curtis Olson, started June 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$
++ * (Log is kept at end of this file)
++ **************************************************************************/
++
++
++#ifndef _FG_TIMER_HXX
++#define _FG_TIMER_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++
++extern unsigned long int fgSimTime;
++
++/* this routine initializes the interval timer to generate a SIGALRM
++ * after the specified interval (dt) the function f() will be called
++ * at each signal */
++void fgTimerInit( float dt, void (*f)( int ) );
++
++/* This function returns the number of milleseconds since the last
++ time it was called. */
++int fgGetTimeInterval( void );
++
++
++#endif /* _FG_TIMER_HXX */
++
++
++/* $Log$
++/* Revision 1.1 1998/04/24 00:52:30 curt
++/* Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++/* Fog color fixes.
++/* Separated out lighting calcs into their own file.
++/*
++ * Revision 1.5 1998/04/21 17:01:45 curt
++ * Fixed a problems where a pointer to a function was being passed around. In
++ * one place this functions arguments were defined as ( void ) while in another
++ * place they were defined as ( int ). The correct answer was ( int ).
++ *
++ * Prepairing for C++ integration.
++ *
++ * Revision 1.4 1998/01/22 02:59:43 curt
++ * Changed #ifdef FILE_H to #ifdef _FILE_H
++ *
++ * Revision 1.3 1998/01/19 18:40:40 curt
++ * Tons of little changes to clean up the code and to remove fatal errors
++ * when building with the c++ compiler.
++ *
++ * Revision 1.2 1997/07/23 21:52:27 curt
++ * Put comments around the text after an #endif for increased portability.
++ *
++ * Revision 1.1 1997/06/16 19:24:20 curt
++ * Initial revision.
++ *
++ */
--- /dev/null
--- /dev/null
++//
++// light.hxx -- lighting routines
++//
++// Written by Curtis Olson, started April 1998.
++//
++// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
++//
++// 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
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#include "Include/compiler.h"
++
++#ifdef FG_MATH_EXCEPTION_CLASH
++# define exception c_exception
++#endif
++
++#ifdef FG_HAVE_STD_INCLUDES
++# include <cmath>
++#else
++# include <math.h>
++#endif
++
++#include <string>
++FG_USING_STD(string);
++
++#include <Aircraft/aircraft.hxx>
++#include <Debug/logstream.hxx>
++#include <Include/fg_constants.h>
++#include <Main/options.hxx>
++#include <Main/views.hxx>
++#include <Math/fg_geodesy.hxx>
++#include <Math/interpolater.hxx>
++#include <Math/mat3.h>
++#include <Math/polar3d.hxx>
++
++#include "fg_time.hxx"
++#include "light.hxx"
++#include "sunpos.hxx"
++
++
++fgLIGHT cur_light_params;
++
++
++// Constructor
++fgLIGHT::fgLIGHT( void ) {
++}
++
++
++// initialize lighting tables
++void fgLIGHT::Init( void ) {
++ FG_LOG( FG_EVENT, FG_INFO,
++ "Initializing Lighting interpolation tables." );
++
++ // build the path name to the ambient lookup table
++ string path = current_options.get_fg_root();
++ string ambient = path + "/Lighting/ambient";
++ string diffuse = path + "/Lighting/diffuse";
++ string sky = path + "/Lighting/sky";
++
++ // initialize ambient table
++ ambient_tbl = new fgINTERPTABLE( ambient );
++
++ // initialize diffuse table
++ diffuse_tbl = new fgINTERPTABLE( diffuse );
++
++ // initialize sky table
++ sky_tbl = new fgINTERPTABLE( sky );
++}
++
++
++// update lighting parameters based on current sun position
++void fgLIGHT::Update( void ) {
++ FGInterface *f;
++ fgTIME *t;
++ // if the 4th field is 0.0, this specifies a direction ...
++ GLfloat white[4] = { 1.0, 1.0, 1.0, 1.0 };
++ // base sky color
++ GLfloat base_sky_color[4] = {0.60, 0.60, 0.90, 1.0};
++ // base fog color
++ GLfloat base_fog_color[4] = {0.90, 0.90, 1.00, 1.0};
++ double deg, ambient, diffuse, sky_brightness;
++
++ f = current_aircraft.fdm_state;
++ t = &cur_time_params;
++
++ FG_LOG( FG_EVENT, FG_INFO, "Updating light parameters." );
++
++ // calculate lighting parameters based on sun's relative angle to
++ // local up
++
++ deg = sun_angle * 180.0 / FG_PI;
++ FG_LOG( FG_EVENT, FG_INFO, " Sun angle = " << deg );
++
++ ambient = ambient_tbl->interpolate( deg );
++ diffuse = diffuse_tbl->interpolate( deg );
++ sky_brightness = sky_tbl->interpolate( deg );
++
++ FG_LOG( FG_EVENT, FG_INFO,
++ " ambient = " << ambient << " diffuse = " << diffuse
++ << " sky = " << sky_brightness );
++
++ // sky_brightness = 0.15; // used to force a dark sky (when testing)
++
++ // if ( ambient < 0.02 ) { ambient = 0.02; }
++ // if ( diffuse < 0.0 ) { diffuse = 0.0; }
++ // if ( sky_brightness < 0.1 ) { sky_brightness = 0.1; }
++
++ scene_ambient[0] = white[0] * ambient;
++ scene_ambient[1] = white[1] * ambient;
++ scene_ambient[2] = white[2] * ambient;
++
++ scene_diffuse[0] = white[0] * diffuse;
++ scene_diffuse[1] = white[1] * diffuse;
++ scene_diffuse[2] = white[2] * diffuse;
++
++ // set sky color
++ sky_color[0] = base_sky_color[0] * sky_brightness;
++ sky_color[1] = base_sky_color[1] * sky_brightness;
++ sky_color[2] = base_sky_color[2] * sky_brightness;
++ sky_color[3] = base_sky_color[3];
++
++ // set fog color
++ fog_color[0] = base_fog_color[0] * sky_brightness;
++ fog_color[1] = base_fog_color[1] * sky_brightness;
++ fog_color[2] = base_fog_color[2] * sky_brightness;
++ fog_color[3] = base_fog_color[3];
++}
++
++
++// calculate fog color adjusted for sunrise/sunset effects
++void fgLIGHT::UpdateAdjFog( void ) {
++ FGInterface *f;
++ double sun_angle_deg, rotation, param1[3], param2[3];
++
++ f = current_aircraft.fdm_state;
++
++ FG_LOG( FG_EVENT, FG_DEBUG, "Updating adjusted fog parameters." );
++
++ // set fog color (we'll try to match the sunset color in the
++ // direction we are looking
++
++ // first determine the difference between our view angle and local
++ // direction to the sun
++ rotation = -(sun_rotation + FG_PI)
++ - (f->get_Psi() - current_view.get_view_offset());
++ while ( rotation < 0 ) {
++ rotation += FG_2PI;
++ }
++ while ( rotation > FG_2PI ) {
++ rotation -= FG_2PI;
++ }
++ rotation *= RAD_TO_DEG;
++ // fgPrintf( FG_EVENT, FG_INFO,
++ // " View to sun difference in degrees = %.2f\n", rotation);
++
++ // next check if we are in a sunset/sunrise situation
++ sun_angle_deg = sun_angle * RAD_TO_DEG;
++ if ( (sun_angle_deg > 80.0) && (sun_angle_deg < 100.0) ) {
++ /* 0.0 - 0.6 */
++ param1[0] = (10.0 - fabs(90.0 - sun_angle_deg)) / 20.0;
++ param1[1] = (10.0 - fabs(90.0 - sun_angle_deg)) / 40.0;
++ param1[2] = (10.0 - fabs(90.0 - sun_angle_deg)) / 30.0;
++ // param2[2] = -(10.0 - fabs(90.0 - sun_angle)) / 30.0;
++ } else {
++ param1[0] = param1[1] = param1[2] = 0.0;
++ }
++
++ if ( rotation - 180.0 <= 0.0 ) {
++ param2[0] = param1[0] * (180.0 - rotation) / 180.0;
++ param2[1] = param1[1] * (180.0 - rotation) / 180.0;
++ param2[2] = param1[2] * (180.0 - rotation) / 180.0;
++ // printf("param1[0] = %.2f param2[0] = %.2f\n", param1[0], param2[0]);
++ } else {
++ param2[0] = param1[0] * (rotation - 180.0) / 180.0;
++ param2[1] = param1[1] * (rotation - 180.0) / 180.0;
++ param2[2] = param1[2] * (rotation - 180.0) / 180.0;
++ // printf("param1[0] = %.2f param2[0] = %.2f\n", param1[0], param2[0]);
++ }
++
++ adj_fog_color[0] = fog_color[0] + param2[0];
++ if ( adj_fog_color[0] > 1.0 ) { adj_fog_color[0] = 1.0; }
++
++ adj_fog_color[1] = fog_color[1] + param2[1];
++ if ( adj_fog_color[1] > 1.0 ) { adj_fog_color[1] = 1.0; }
++
++ adj_fog_color[2] = fog_color[2] + param2[2];
++ if ( adj_fog_color[2] > 1.0 ) { adj_fog_color[2] = 1.0; }
++
++ adj_fog_color[3] = fog_color[3];
++}
++
++
++// Destructor
++fgLIGHT::~fgLIGHT( void ) {
++}
++
++
++// $Log$
++// Revision 1.27 1999/04/05 02:14:40 curt
++// Fixed a fog coloring bug.
++//
++// Revision 1.26 1999/02/05 21:29:20 curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.25 1999/01/07 20:25:36 curt
++// Portability changes and updates from Bernie Bright.
++//
++// Revision 1.24 1998/12/09 18:50:35 curt
++// Converted "class fgVIEW" to "class FGView" and updated to make data
++// members private and make required accessor functions.
++//
++// Revision 1.23 1998/12/05 15:54:30 curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.22 1998/12/03 01:18:42 curt
++// Converted fgFLIGHT to a class.
++//
++// Revision 1.21 1998/11/23 21:49:09 curt
++// Borland portability tweaks.
++//
++// Revision 1.20 1998/11/06 21:18:27 curt
++// Converted to new logstream debugging facility. This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.19 1998/10/20 18:41:53 curt
++// Tweaked sunrise/sunset colors.
++//
++// Revision 1.18 1998/10/17 01:34:30 curt
++// C++ ifying ...
++//
++// Revision 1.17 1998/08/29 13:11:33 curt
++// Bernie Bright writes:
++// I've created some new classes to enable pointers-to-functions and
++// pointers-to-class-methods to be treated like objects. These objects
++// can be registered with fgEVENT_MGR.
++//
++// File "Include/fg_callback.hxx" contains the callback class defns.
++//
++// Modified fgEVENT and fgEVENT_MGR to use the callback classes. Also
++// some minor tweaks to STL usage.
++//
++// Added file "Include/fg_stl_config.h" to deal with STL portability
++// issues. I've added an initial config for egcs (and probably gcc-2.8.x).
++// I don't have access to Visual C++ so I've left that for someone else.
++// This file is influenced by the stl_config.h file delivered with egcs.
++//
++// Added "Include/auto_ptr.hxx" which contains an implementation of the
++// STL auto_ptr class which is not provided in all STL implementations
++// and is needed to use the callback classes.
++//
++// Deleted fgLightUpdate() which was just a wrapper to call
++// fgLIGHT::Update().
++//
++// Modified fg_init.cxx to register two method callbacks in place of the
++// old wrapper functions.
++//
++// Revision 1.16 1998/08/27 17:02:11 curt
++// Contributions from Bernie Bright <bbright@c031.aone.net.au>
++// - use strings for fg_root and airport_id and added methods to return
++// them as strings,
++// - inlined all access methods,
++// - made the parsing functions private methods,
++// - deleted some unused functions.
++// - propogated some of these changes out a bit further.
++//
++// Revision 1.15 1998/08/25 20:53:33 curt
++// Shuffled $FG_ROOT file layout.
++//
++// Revision 1.14 1998/08/06 12:47:22 curt
++// Adjusted dusk/dawn lighting ...
++//
++// Revision 1.13 1998/07/24 21:42:26 curt
++// Output message tweaks.
++//
++// Revision 1.12 1998/07/22 21:45:38 curt
++// fg_time.cxx: Removed call to ctime() in a printf() which should be harmless
++// but seems to be triggering a bug.
++// light.cxx: Added code to adjust fog color based on sunrise/sunset effects
++// and view orientation. This is an attempt to match the fog color to the
++// sky color in the center of the screen. You see discrepancies at the
++// edges, but what else can be done?
++// sunpos.cxx: Caculate local direction to sun here. (what compass direction
++// do we need to face to point directly at sun)
++//
++// Revision 1.11 1998/07/13 21:02:08 curt
++// Wrote access functions for current fgOPTIONS.
++//
++// Revision 1.10 1998/07/08 14:48:38 curt
++// polar3d.h renamed to polar3d.hxx
++//
++// Revision 1.9 1998/05/29 20:37:51 curt
++// Renamed <Table>.table to be <Table> so we can add a .gz under DOS.
++//
++// Revision 1.8 1998/05/20 20:54:16 curt
++// Converted fgLIGHT to a C++ class.
++//
++// Revision 1.7 1998/05/13 18:26:50 curt
++// Root path info moved to fgOPTIONS.
++//
++// Revision 1.6 1998/05/11 18:18:51 curt
++// Made fog color slightly bluish.
++//
++// Revision 1.5 1998/05/03 00:48:38 curt
++// polar.h -> polar3d.h
++//
++// Revision 1.4 1998/04/28 01:22:18 curt
++// Type-ified fgTIME and fgVIEW.
++//
++// Revision 1.3 1998/04/26 05:10:04 curt
++// "struct fgLIGHT" -> "fgLIGHT" because fgLIGHT is typedef'd.
++//
++// Revision 1.2 1998/04/24 00:52:30 curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Fog color fixes.
++// Separated out lighting calcs into their own file.
++//
++// Revision 1.1 1998/04/22 13:24:06 curt
++// C++ - ifiing the code a bit.
++// Starting to reorginize some of the lighting calcs to use a table lookup.
++//
--- /dev/null
--- /dev/null
++// light.hxx -- lighting routines
++//
++// Written by Curtis Olson, started April 1998.
++//
++// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
++//
++// 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$
++
++
++#ifndef _LIGHT_HXX
++#define _LIGHT_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++// #include <Include/fg_types.h>
++#include <Math/interpolater.hxx>
++#include <Math/point3d.hxx>
++
++
++// Define a structure containing the global lighting parameters
++class fgLIGHT {
++
++ // Lighting look up tables (based on sun angle with local horizon)
++ fgINTERPTABLE *ambient_tbl;
++ fgINTERPTABLE *diffuse_tbl;
++ fgINTERPTABLE *sky_tbl;
++
++public:
++
++ ///////////////////////////////////////////////////////////
++ // position of the sun in various forms
++
++ // in geocentric coordinates
++ double sun_lon, sun_gc_lat;
++
++ // in cartesian coordiantes
++ Point3D fg_sunpos;
++
++ // (in view coordinates)
++ GLfloat sun_vec[4];
++
++ // inverse (in view coordinates)
++ GLfloat sun_vec_inv[4];
++
++ // the angle between the sun and the local horizontal (in radians)
++ double sun_angle;
++
++ // the rotation around our vertical axis of the sun (relative to
++ // due south with positive numbers going in the counter clockwise
++ // direction.) This is the direction we'd need to face if we
++ // wanted to travel towards the sun.
++ double sun_rotation;
++
++ ///////////////////////////////////////////////////////////
++ // Have the same for the moon. Useful for having some light at night
++ // and stuff. I (Durk) also want to use this for adding similar
++ // coloring effects to the moon as I did to the sun.
++ ///////////////////////////////////////////////////////////
++ // position of the moon in various forms
++
++ // in geocentric coordinates
++ double moon_lon, moon_gc_lat;
++
++ // in cartesian coordiantes
++ Point3D fg_moonpos;
++
++ // (in view coordinates)
++ GLfloat moon_vec[4];
++
++ // inverse (in view coordinates)
++ GLfloat moon_vec_inv[4];
++
++ // the angle between the moon and the local horizontal (in radians)
++ double moon_angle;
++
++ // the rotation around our vertical axis of the moon (relative to
++ // due south with positive numbers going in the counter clockwise
++ // direction.) This is the direction we'd need to face if we
++ // wanted to travel towards the sun.
++ double moon_rotation;
++
++ ///////////////////////////////////////////////////////////
++ // Derived lighting values
++
++ // ambient component
++ GLfloat scene_ambient[3];
++
++ // diffuse component
++ GLfloat scene_diffuse[3];
++
++ // fog color
++ GLfloat fog_color[4];
++
++ // fog color adjusted for sunset effects
++ GLfloat adj_fog_color[4];
++
++ // clear screen color
++ GLfloat sky_color[4];
++
++ // Constructor
++ fgLIGHT( void );
++
++ // initialize lighting tables
++ void Init( void );
++
++ // update lighting parameters based on current sun position
++ void Update( void);
++
++ // calculate fog color adjusted for sunrise/sunset effects
++ void UpdateAdjFog( void );
++
++ // Destructor
++ ~fgLIGHT( void );
++};
++
++
++// Global shared light parameter structure
++extern fgLIGHT cur_light_params;
++
++
++#endif // _LIGHT_HXX
++
++
++// $Log$
++// Revision 1.9 1999/03/22 02:08:17 curt
++// Changes contributed by Durk Talsma:
++//
++// Here's a few changes I made to fg-0.58 this weekend. Included are the
++// following features:
++// - Sun and moon have a halo
++// - The moon has a light vector, moon_angle, etc. etc. so that we can have
++// some moonlight during the night.
++// - Lot's of small changes tweakes, including some stuff Norman Vine sent
++// me earlier.
++//
++// Revision 1.8 1998/10/16 00:56:10 curt
++// Converted to Point3D class.
++//
++// Revision 1.7 1998/08/29 13:11:33 curt
++// Bernie Bright writes:
++// I've created some new classes to enable pointers-to-functions and
++// pointers-to-class-methods to be treated like objects. These objects
++// can be registered with fgEVENT_MGR.
++//
++// File "Include/fg_callback.hxx" contains the callback class defns.
++//
++// Modified fgEVENT and fgEVENT_MGR to use the callback classes. Also
++// some minor tweaks to STL usage.
++//
++// Added file "Include/fg_stl_config.h" to deal with STL portability
++// issues. I've added an initial config for egcs (and probably gcc-2.8.x).
++// I don't have access to Visual C++ so I've left that for someone else.
++// This file is influenced by the stl_config.h file delivered with egcs.
++//
++// Added "Include/auto_ptr.hxx" which contains an implementation of the
++// STL auto_ptr class which is not provided in all STL implementations
++// and is needed to use the callback classes.
++//
++// Deleted fgLightUpdate() which was just a wrapper to call
++// fgLIGHT::Update().
++//
++// Modified fg_init.cxx to register two method callbacks in place of the
++// old wrapper functions.
++//
++// Revision 1.6 1998/07/22 21:45:39 curt
++// fg_time.cxx: Removed call to ctime() in a printf() which should be harmless
++// but seems to be triggering a bug.
++// light.cxx: Added code to adjust fog color based on sunrise/sunset effects
++// and view orientation. This is an attempt to match the fog color to the
++// sky color in the center of the screen. You see discrepancies at the
++// edges, but what else can be done?
++// sunpos.cxx: Caculate local direction to sun here. (what compass direction
++// do we need to face to point directly at sun)
++//
++// Revision 1.5 1998/07/08 14:48:39 curt
++// polar3d.h renamed to polar3d.hxx
++//
++// Revision 1.4 1998/05/20 20:54:17 curt
++// Converted fgLIGHT to a C++ class.
++//
++// Revision 1.3 1998/05/02 01:53:18 curt
++// Fine tuning mktime() support because of varying behavior on different
++// platforms.
++//
++// Revision 1.2 1998/04/24 00:52:31 curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Fog color fixes.
++// Separated out lighting calcs into their own file.
++//
++// Revision 1.1 1998/04/22 13:24:06 curt
++// C++ - ifiing the code a bit.
++// Starting to reorginize some of the lighting calcs to use a table lookup.
++//
++//
--- /dev/null
--- /dev/null
++// moonpos.cxx (basically, this is a slightly modified version of the 'sunpos.cxx' file, adapted from XEarth)
++
++// kirk johnson
++// july 1993
++//
++// code for calculating the position on the earth's surface for which
++// the moon is directly overhead (adapted from _practical astronomy
++// with your calculator, third edition_, peter duffett-smith,
++// cambridge university press, 1988.)
++//
++// Copyright (C) 1989, 1990, 1993, 1994, 1995 Kirk Lauritz Johnson
++//
++// Parts of the source code (as marked) are:
++// Copyright (C) 1989, 1990, 1991 by Jim Frost
++// Copyright (C) 1992 by Jamie Zawinski <jwz@lucid.com>
++//
++// Permission to use, copy, modify and freely distribute xearth for
++// non-commercial and not-for-profit purposes is hereby granted
++// without fee, provided that both the above copyright notice and this
++// permission notice appear in all copies and in supporting
++// documentation.
++//
++// The author makes no representations about the suitability of this
++// software for any purpose. It is provided "as is" without express or
++// implied warranty.
++//
++// THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++// INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
++// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT
++// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
++// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
++// NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#include "Include/compiler.h"
++#ifdef FG_HAVE_STD_INCLUDES
++# include <cmath>
++# include <cstdio>
++# include <ctime>
++#else
++# include <math.h>
++# include <stdio.h>
++# include <time.h>
++#endif
++
++
++//#include <Astro/orbits.hxx>
++#include <Astro/solarsystem.hxx>
++#include <Debug/logstream.hxx>
++#include <Include/fg_constants.h>
++#include <Main/views.hxx>
++#include <Math/fg_geodesy.hxx>
++#include <Math/mat3.h>
++#include <Math/point3d.hxx>
++#include <Math/polar3d.hxx>
++#include <Math/vector.hxx>
++#include <Scenery/scenery.hxx>
++
++#include "fg_time.hxx"
++#include "moonpos.hxx"
++
++extern SolarSystem *solarSystem;
++
++#undef E
++
++
++/*
++ * the epoch upon which these astronomical calculations are based is
++ * 1990 january 0.0, 631065600 seconds since the beginning of the
++ * "unix epoch" (00:00:00 GMT, Jan. 1, 1970)
++ *
++ * given a number of seconds since the start of the unix epoch,
++ * DaysSinceEpoch() computes the number of days since the start of the
++ * astronomical epoch (1990 january 0.0)
++ */
++
++#define EpochStart (631065600)
++#define DaysSinceEpoch(secs) (((secs)-EpochStart)*(1.0/(24*3600)))
++
++/*
++ * assuming the apparent orbit of the moon about the earth is circular,
++ * the rate at which the orbit progresses is given by RadsPerDay --
++ * FG_2PI radians per orbit divided by 365.242191 days per year:
++ */
++
++#define RadsPerDay (FG_2PI/365.242191)
++
++/*
++ * details of moon's apparent orbit at epoch 1990.0 (after
++ * duffett-smith, table 6, section 46)
++ *
++ * Epsilon_g (ecliptic longitude at epoch 1990.0) 279.403303 degrees
++ * OmegaBar_g (ecliptic longitude of perigee) 282.768422 degrees
++ * Eccentricity (eccentricity of orbit) 0.016713
++ */
++
++#define Epsilon_g (279.403303*(FG_2PI/360))
++#define OmegaBar_g (282.768422*(FG_2PI/360))
++#define Eccentricity (0.016713)
++
++/*
++ * MeanObliquity gives the mean obliquity of the earth's axis at epoch
++ * 1990.0 (computed as 23.440592 degrees according to the method given
++ * in duffett-smith, section 27)
++ */
++#define MeanObliquity (23.440592*(FG_2PI/360))
++
++/* static double solve_keplers_equation(double); */
++/* static double moon_ecliptic_longitude(time_t); */
++static void ecliptic_to_equatorial(double, double, double *, double *);
++static double julian_date(int, int, int);
++static double GST(time_t);
++
++/*
++ * solve Kepler's equation via Newton's method
++ * (after duffett-smith, section 47)
++ */
++/*
++static double solve_keplers_equation(double M) {
++ double E;
++ double delta;
++
++ E = M;
++ while (1) {
++ delta = E - Eccentricity*sin(E) - M;
++ if (fabs(delta) <= 1e-10) break;
++ E -= delta / (1 - Eccentricity*cos(E));
++ }
++
++ return E;
++}
++*/
++
++
++/* compute ecliptic longitude of moon (in radians) (after
++ * duffett-smith, section 47) */
++/*
++static double moon_ecliptic_longitude(time_t ssue) {
++ // time_t ssue; // seconds since unix epoch
++ double D, N;
++ double M_moon, E;
++ double v;
++
++ D = DaysSinceEpoch(ssue);
++
++ N = RadsPerDay * D;
++ N = fmod(N, FG_2PI);
++ if (N < 0) N += FG_2PI;
++
++ M_moon = N + Epsilon_g - OmegaBar_g;
++ if (M_moon < 0) M_moon += FG_2PI;
++
++ E = solve_keplers_equation(M_moon);
++ v = 2 * atan(sqrt((1+Eccentricity)/(1-Eccentricity)) * tan(E/2));
++
++ return (v + OmegaBar_g);
++}
++*/
++
++
++/* convert from ecliptic to equatorial coordinates (after
++ * duffett-smith, section 27) */
++
++static void ecliptic_to_equatorial(double lambda, double beta,
++ double *alpha, double *delta) {
++ /* double lambda; ecliptic longitude */
++ /* double beta; ecliptic latitude */
++ /* double *alpha; (return) right ascension */
++ /* double *delta; (return) declination */
++
++ double sin_e, cos_e;
++ double sin_l, cos_l;
++
++ sin_e = sin(MeanObliquity);
++ cos_e = cos(MeanObliquity);
++ sin_l = sin(lambda);
++ cos_l = cos(lambda);
++
++ *alpha = atan2(sin_l*cos_e - tan(beta)*sin_e, cos_l);
++ *delta = asin(sin(beta)*cos_e + cos(beta)*sin_e*sin_l);
++}
++
++
++/* computing julian dates (assuming gregorian calendar, thus this is
++ * only valid for dates of 1582 oct 15 or later) (after duffett-smith,
++ * section 4) */
++
++static double julian_date(int y, int m, int d) {
++ /* int y; year (e.g. 19xx) */
++ /* int m; month (jan=1, feb=2, ...) */
++ /* int d; day of month */
++
++ int A, B, C, D;
++ double JD;
++
++ /* lazy test to ensure gregorian calendar */
++ if (y < 1583) {
++ FG_LOG( FG_EVENT, FG_ALERT,
++ "WHOOPS! Julian dates only valid for 1582 oct 15 or later" );
++ }
++
++ if ((m == 1) || (m == 2)) {
++ y -= 1;
++ m += 12;
++ }
++
++ A = y / 100;
++ B = 2 - A + (A / 4);
++ C = (int)(365.25 * y);
++ D = (int)(30.6001 * (m + 1));
++
++ JD = B + C + D + d + 1720994.5;
++
++ return JD;
++}
++
++
++/* compute greenwich mean sidereal time (GST) corresponding to a given
++ * number of seconds since the unix epoch (after duffett-smith,
++ * section 12) */
++static double GST(time_t ssue) {
++ /* time_t ssue; seconds since unix epoch */
++
++ double JD;
++ double T, T0;
++ double UT;
++ struct tm *tm;
++
++ tm = gmtime(&ssue);
++
++ JD = julian_date(tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
++ T = (JD - 2451545) / 36525;
++
++ T0 = ((T + 2.5862e-5) * T + 2400.051336) * T + 6.697374558;
++
++ T0 = fmod(T0, 24.0);
++ if (T0 < 0) T0 += 24;
++
++ UT = tm->tm_hour + (tm->tm_min + tm->tm_sec / 60.0) / 60.0;
++
++ T0 += UT * 1.002737909;
++ T0 = fmod(T0, 24.0);
++ if (T0 < 0) T0 += 24;
++
++ return T0;
++}
++
++
++/* given a particular time (expressed in seconds since the unix
++ * epoch), compute position on the earth (lat, lon) such that moon is
++ * directly overhead. (lat, lon are reported in radians */
++
++void fgMoonPosition(time_t ssue, double *lon, double *lat) {
++ /* time_t ssue; seconds since unix epoch */
++ /* double *lat; (return) latitude */
++ /* double *lon; (return) longitude */
++
++ /* double lambda; */
++ double alpha, delta;
++ double tmp;
++
++ /* lambda = moon_ecliptic_longitude(ssue); */
++ /* ecliptic_to_equatorial(lambda, 0.0, &alpha, &delta); */
++ //ecliptic_to_equatorial (solarPosition.lonMoon, 0.0, &alpha, &delta);
++
++ /* **********************************************************************
++ * NOTE: in the next function, each time the moon's position is updated, the
++ * the moon's longitude is returned from solarSystem->moon. Note that the
++ * moon's position is updated at a much higher frequency than the rate at
++ * which the solar system's rebuilds occur. This is not a problem, however,
++ * because the fgMoonPosition we're talking about here concerns the changing
++ * position of the moon due to the daily rotation of the earth.
++ * The ecliptic longitude, however, represents the position of the moon with
++ * respect to the stars, and completes just one cycle over the course of a
++ * year. Its therefore pretty safe to update the moon's longitude only once
++ * every ten minutes. (Comment added by Durk Talsma).
++ ************************************************************************/
++
++ ecliptic_to_equatorial( SolarSystem::theSolarSystem->getMoon()->getLon(),
++ 0.0, &alpha, &delta );
++ tmp = alpha - (FG_2PI/24)*GST(ssue);
++ if (tmp < -FG_PI) {
++ do tmp += FG_2PI;
++ while (tmp < -FG_PI);
++ } else if (tmp > FG_PI) {
++ do tmp -= FG_2PI;
++ while (tmp < -FG_PI);
++ }
++
++ *lon = tmp;
++ *lat = delta;
++}
++
++
++/* given a particular time expressed in side real time at prime
++ * meridian (GST), compute position on the earth (lat, lon) such that
++ * moon is directly overhead. (lat, lon are reported in radians */
++
++static void fgMoonPositionGST(double gst, double *lon, double *lat) {
++ /* time_t ssue; seconds since unix epoch */
++ /* double *lat; (return) latitude */
++ /* double *lon; (return) longitude */
++
++ /* double lambda; */
++ double alpha, delta;
++ double tmp;
++
++ /* lambda = moon_ecliptic_longitude(ssue); */
++ /* ecliptic_to_equatorial(lambda, 0.0, &alpha, &delta); */
++ //ecliptic_to_equatorial (solarPosition.lonMoon, 0.0, &alpha, &delta);
++ ecliptic_to_equatorial( SolarSystem::theSolarSystem->getMoon()->getLon(),
++ SolarSystem::theSolarSystem->getMoon()->getLat(),
++ &alpha, &delta );
++
++// tmp = alpha - (FG_2PI/24)*GST(ssue);
++ tmp = alpha - (FG_2PI/24)*gst;
++ if (tmp < -FG_PI) {
++ do tmp += FG_2PI;
++ while (tmp < -FG_PI);
++ } else if (tmp > FG_PI) {
++ do tmp -= FG_2PI;
++ while (tmp < -FG_PI);
++ }
++
++ *lon = tmp;
++ *lat = delta;
++}
++
++
++// update the cur_time_params structure with the current moon position
++void fgUpdateMoonPos( void ) {
++ fgLIGHT *l;
++ fgTIME *t;
++ FGView *v;
++ MAT3vec nup, nmoon, v0, surface_to_moon;
++ Point3D p, rel_moonpos;
++ double dot, east_dot;
++ double moon_gd_lat, sl_radius;
++ double ntmp;
++
++ l = &cur_light_params;
++ t = &cur_time_params;
++ v = ¤t_view;
++
++ FG_LOG( FG_EVENT, FG_INFO, " Updating Moon position" );
++
++ // (not sure why there was two)
++ // fgMoonPosition(t->cur_time, &l->moon_lon, &moon_gd_lat);
++ fgMoonPositionGST(t->gst, &l->moon_lon, &moon_gd_lat);
++
++ fgGeodToGeoc(moon_gd_lat, 0.0, &sl_radius, &l->moon_gc_lat);
++
++ p = Point3D( l->moon_lon, l->moon_gc_lat, sl_radius );
++ l->fg_moonpos = fgPolarToCart3d(p);
++
++ FG_LOG( FG_EVENT, FG_INFO, " t->cur_time = " << t->cur_time );
++ FG_LOG( FG_EVENT, FG_INFO,
++ " Moon Geodetic lat = " << moon_gd_lat
++ << " Geocentric lat = " << l->moon_gc_lat );
++
++ // I think this will work better for generating the moon light vector
++ l->moon_vec[0] = l->fg_moonpos.x();
++ l->moon_vec[1] = l->fg_moonpos.y();
++ l->moon_vec[2] = l->fg_moonpos.z();
++ MAT3_NORMALIZE_VEC(l->moon_vec, ntmp);
++ MAT3_SCALE_VEC(l->moon_vec_inv, l->moon_vec, -1.0);
++
++ // make sure these are directional light sources only
++ l->moon_vec[3] = 0.0;
++ l->moon_vec_inv[3] = 0.0;
++
++ // printf(" l->moon_vec = %.2f %.2f %.2f\n", l->moon_vec[0], l->moon_vec[1],
++ // l->moon_vec[2]);
++
++ // calculate the moon's relative angle to local up
++ MAT3_COPY_VEC(nup, v->get_local_up());
++ nmoon[0] = l->fg_moonpos.x();
++ nmoon[1] = l->fg_moonpos.y();
++ nmoon[2] = l->fg_moonpos.z();
++ MAT3_NORMALIZE_VEC(nup, ntmp);
++ MAT3_NORMALIZE_VEC(nmoon, ntmp);
++
++ l->moon_angle = acos(MAT3_DOT_PRODUCT(nup, nmoon));
++ // printf(" MOON ANGLE relative to current location = %.3f rads.\n",
++ // l->moon_angle);
++
++ // calculate vector to moon's position on the earth's surface
++ rel_moonpos = l->fg_moonpos - (v->get_view_pos() + scenery.center);
++ v->set_to_moon( rel_moonpos.x(), rel_moonpos.y(), rel_moonpos.z() );
++ // printf( "Vector to moon = %.2f %.2f %.2f\n",
++ // v->to_moon[0], v->to_moon[1], v->to_moon[2]);
++
++ // make a vector to the current view position
++ Point3D view_pos = v->get_view_pos();
++ MAT3_SET_VEC(v0, view_pos.x(), view_pos.y(), view_pos.z());
++
++ // Given a vector from the view position to the point on the
++ // earth's surface the moon is directly over, map into onto the
++ // local plane representing "horizontal".
++ map_vec_onto_cur_surface_plane( v->get_local_up(), v0, v->get_to_moon(),
++ surface_to_moon );
++ MAT3_NORMALIZE_VEC(surface_to_moon, ntmp);
++ v->set_surface_to_moon( surface_to_moon[0], surface_to_moon[1],
++ surface_to_moon[2] );
++ // printf("Surface direction to moon is %.2f %.2f %.2f\n",
++ // v->surface_to_moon[0], v->surface_to_moon[1], v->surface_to_moon[2]);
++ // printf("Should be close to zero = %.2f\n",
++ // MAT3_DOT_PRODUCT(v->local_up, v->surface_to_moon));
++
++ // calculate the angle between v->surface_to_moon and
++ // v->surface_east. We do this so we can sort out the acos()
++ // ambiguity. I wish I could think of a more efficient way ... :-(
++ east_dot = MAT3_DOT_PRODUCT( surface_to_moon, v->get_surface_east() );
++ // printf(" East dot product = %.2f\n", east_dot);
++
++ // calculate the angle between v->surface_to_moon and
++ // v->surface_south. this is how much we have to rotate the sky
++ // for it to align with the moon
++ dot = MAT3_DOT_PRODUCT( surface_to_moon, v->get_surface_south() );
++ // printf(" Dot product = %.2f\n", dot);
++ if ( east_dot >= 0 ) {
++ l->moon_rotation = acos(dot);
++ } else {
++ l->moon_rotation = -acos(dot);
++ }
++ // printf(" Sky needs to rotate = %.3f rads = %.1f degrees.\n",
++ // angle, angle * RAD_TO_DEG); */
++}
++
++
++// $Log$
++// Revision 1.1 1999/03/22 12:08:57 curt
++// Initial revision.
++//
++// Revision 1.19 1999/01/07 20:25:37 curt
++// Portability changes and updates from Bernie Bright.
++//
++// Revision 1.18 1998/12/09 18:50:36 curt
++// Converted "class fgVIEW" to "class FGView" and updated to make data
++// members private and make required accessor functions.
++//
++// Revision 1.17 1998/11/09 23:41:53 curt
++// Log message clean ups.
++//
++// Revision 1.16 1998/11/07 19:07:14 curt
++// Enable release builds using the --without-logging option to the configure
++// script. Also a couple log message cleanups, plus some C to C++ comment
++// conversion.
++//
++// Revision 1.15 1998/10/18 01:17:24 curt
++// Point3D tweaks.
++//
++// Revision 1.14 1998/10/17 01:34:32 curt
++// C++ ifying ...
++//
++// Revision 1.13 1998/10/16 00:56:12 curt
++// Converted to Point3D class.
++//
++// Revision 1.12 1998/09/15 04:27:50 curt
++// Changes for new astro code.
++//
++// Revision 1.11 1998/08/12 21:13:22 curt
++// Optimizations by Norman Vine.
++//
++// Revision 1.10 1998/07/22 21:45:39 curt
++// fg_time.cxx: Removed call to ctime() in a printf() which should be harmless
++// but seems to be triggering a bug.
++// light.cxx: Added code to adjust fog color based on moonrise/moonset effects
++// and view orientation. This is an attempt to match the fog color to the
++// sky color in the center of the screen. You see discrepancies at the
++// edges, but what else can be done?
++// moonpos.cxx: Caculate local direction to moon here. (what compass direction
++// do we need to face to point directly at moon)
++//
++// Revision 1.9 1998/07/08 14:48:39 curt
++// polar3d.h renamed to polar3d.hxx
++//
++// Revision 1.8 1998/05/02 01:53:18 curt
++// Fine tuning mktime() support because of varying behavior on different
++// platforms.
++//
++// Revision 1.7 1998/04/30 12:36:05 curt
++// C++-ifying a couple source files.
++//
++// Revision 1.6 1998/04/28 01:22:18 curt
++// Type-ified fgTIME and fgVIEW.
++//
++// Revision 1.5 1998/04/26 05:10:05 curt
++// "struct fgLIGHT" -> "fgLIGHT" because fgLIGHT is typedef'd.
++//
++// Revision 1.4 1998/04/25 22:06:34 curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.3 1998/04/25 20:24:03 curt
++// Cleaned up initialization sequence to eliminate interdependencies
++// between moon position, lighting, and view position. This creates a
++// valid single pass initialization path.
++//
++// Revision 1.2 1998/04/24 00:52:31 curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Fog color fixes.
++// Separated out lighting calcs into their own file.
++//
++// Revision 1.1 1998/04/22 13:24:07 curt
++// C++ - ifiing the code a bit.
++// Starting to reorginize some of the lighting calcs to use a table lookup.
++//
++// Revision 1.27 1998/04/03 22:12:57 curt
++// Converting to Gnu autoconf system.
++// Centralized time handling differences.
++//
++// Revision 1.26 1998/02/23 19:08:00 curt
++// Incorporated Durk's Astro/ tweaks. Includes unifying the moon position
++// calculation code between moon display, and other FG sections that use this
++// for things like lighting.
++//
++// Revision 1.25 1998/02/09 15:07:53 curt
++// Minor tweaks.
++//
++// Revision 1.24 1998/01/27 00:48:07 curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.23 1998/01/19 19:27:21 curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.22 1998/01/19 18:40:40 curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.21 1997/12/30 23:10:19 curt
++// Calculate lighting parameters here.
++//
++// Revision 1.20 1997/12/30 22:22:43 curt
++// Further integration of event manager.
++//
++// Revision 1.19 1997/12/30 20:47:59 curt
++// Integrated new event manager with subsystem initializations.
++//
++// Revision 1.18 1997/12/23 04:58:40 curt
++// Tweaked the sky coloring a bit to build in structures to allow finer rgb
++// control.
++//
++// Revision 1.17 1997/12/15 23:55:08 curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.16 1997/12/11 04:43:57 curt
++// Fixed moon vector and lighting problems. I thing the moon is now lit
++// correctly.
++//
++// Revision 1.15 1997/12/10 22:37:55 curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.14 1997/12/09 04:25:39 curt
++// Working on adding a global lighting params structure.
++//
++// Revision 1.13 1997/11/25 19:25:42 curt
++// Changes to integrate Durk's moon/moon code updates + clean up.
++//
++// Revision 1.12 1997/11/15 18:15:39 curt
++// Reverse direction of moon vector, so object normals can be more normal.
++//
++// Revision 1.11 1997/10/28 21:07:21 curt
++// Changed GLUT/ -> Main/
++//
++// Revision 1.10 1997/09/13 02:00:09 curt
++// Mostly working on stars and generating sidereal time for accurate star
++// placement.
++//
++// Revision 1.9 1997/09/05 14:17:31 curt
++// More tweaking with stars.
++//
++// Revision 1.8 1997/09/05 01:36:04 curt
++// Working on getting stars right.
++//
++// Revision 1.7 1997/09/04 02:17:40 curt
++// Shufflin' stuff.
++//
++// Revision 1.6 1997/08/27 03:30:37 curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.5 1997/08/22 21:34:41 curt
++// Doing a bit of reorganizing and house cleaning.
++//
++// Revision 1.4 1997/08/19 23:55:09 curt
++// Worked on better simulating real lighting.
++//
++// Revision 1.3 1997/08/13 20:23:49 curt
++// The interface to moonpos now updates a global structure rather than returning
++// current moon position.
++//
++// Revision 1.2 1997/08/06 00:24:32 curt
++// Working on correct real time moon lighting.
++//
++// Revision 1.1 1997/08/01 15:27:56 curt
++// Initial revision.
++//
--- /dev/null
--- /dev/null
++/*
++ * moonpos.hxx (taken from XEarth)
++ * kirk johnson
++ * july 1993
++ *
++ * code for calculating the position on the earth's surface for which
++ * the sun is directly overhead (adapted from _practical astronomy
++ * with your calculator, third edition_, peter duffett-smith,
++ * cambridge university press, 1988.)
++ *
++ * RCS $Id$
++ *
++ * Copyright (C) 1989, 1990, 1993, 1994, 1995 Kirk Lauritz Johnson
++ *
++ * Parts of the source code (as marked) are:
++ * Copyright (C) 1989, 1990, 1991 by Jim Frost
++ * Copyright (C) 1992 by Jamie Zawinski <jwz@lucid.com>
++ *
++ * Permission to use, copy, modify and freely distribute xearth for
++ * non-commercial and not-for-profit purposes is hereby granted
++ * without fee, provided that both the above copyright notice and this
++ * permission notice appear in all copies and in supporting
++ * documentation.
++ *
++ * The author makes no representations about the suitability of this
++ * software for any purpose. It is provided "as is" without express or
++ * implied warranty.
++ *
++ * THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT
++ * OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
++ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
++ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++
++#ifndef _MOONPOS_HXX
++#define _MOONPOS_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++#include "Include/compiler.h"
++#ifdef FG_HAVE_STD_INCLUDES
++# include <ctime>
++#else
++# include <time.h>
++#endif
++
++/* update the cur_time_params structure with the current moon position */
++void fgUpdateMoonPos( void );
++
++void fgMoonPosition(time_t ssue, double *lon, double *lat);
++
++
++#endif /* _MOONPOS_H */
--- /dev/null
--- /dev/null
++// sunpos.cxx (adapted from XEarth)
++// kirk johnson
++// july 1993
++//
++// code for calculating the position on the earth's surface for which
++// the sun is directly overhead (adapted from _practical astronomy
++// with your calculator, third edition_, peter duffett-smith,
++// cambridge university press, 1988.)
++//
++// Copyright (C) 1989, 1990, 1993, 1994, 1995 Kirk Lauritz Johnson
++//
++// Parts of the source code (as marked) are:
++// Copyright (C) 1989, 1990, 1991 by Jim Frost
++// Copyright (C) 1992 by Jamie Zawinski <jwz@lucid.com>
++//
++// Permission to use, copy, modify and freely distribute xearth for
++// non-commercial and not-for-profit purposes is hereby granted
++// without fee, provided that both the above copyright notice and this
++// permission notice appear in all copies and in supporting
++// documentation.
++//
++// The author makes no representations about the suitability of this
++// software for any purpose. It is provided "as is" without express or
++// implied warranty.
++//
++// THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++// INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
++// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT
++// OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
++// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
++// NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++//
++// $Id$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#include <Include/compiler.h>
++
++#ifdef FG_HAVE_STD_INCLUDES
++# include <cmath>
++# include <cstdio>
++# include <ctime>
++#else
++# include <math.h>
++# include <stdio.h>
++# include <time.h>
++#endif
++
++#include <Debug/logstream.hxx>
++#include <Astro/solarsystem.hxx>
++#include <Include/fg_constants.h>
++#include <Main/views.hxx>
++#include <Math/fg_geodesy.hxx>
++#include <Math/mat3.h>
++#include <Math/point3d.hxx>
++#include <Math/polar3d.hxx>
++#include <Math/vector.hxx>
++#include <Scenery/scenery.hxx>
++
++#include "fg_time.hxx"
++#include "sunpos.hxx"
++
++extern SolarSystem *solarSystem;
++
++#undef E
++#define MeanObliquity (23.440592*(FG_2PI/360))
++
++static void ecliptic_to_equatorial(double, double, double *, double *);
++static double julian_date(int, int, int);
++static double GST(time_t);
++
++static void ecliptic_to_equatorial(double lambda, double beta,
++ double *alpha, double *delta) {
++ /* double lambda; ecliptic longitude */
++ /* double beta; ecliptic latitude */
++ /* double *alpha; (return) right ascension */
++ /* double *delta; (return) declination */
++
++ double sin_e, cos_e;
++ double sin_l, cos_l;
++
++ sin_e = sin(MeanObliquity);
++ cos_e = cos(MeanObliquity);
++ sin_l = sin(lambda);
++ cos_l = cos(lambda);
++
++ *alpha = atan2(sin_l*cos_e - tan(beta)*sin_e, cos_l);
++ *delta = asin(sin(beta)*cos_e + cos(beta)*sin_e*sin_l);
++}
++
++
++/* computing julian dates (assuming gregorian calendar, thus this is
++ * only valid for dates of 1582 oct 15 or later) (after duffett-smith,
++ * section 4) */
++
++static double julian_date(int y, int m, int d) {
++ /* int y; year (e.g. 19xx) */
++ /* int m; month (jan=1, feb=2, ...) */
++ /* int d; day of month */
++
++ int A, B, C, D;
++ double JD;
++
++ /* lazy test to ensure gregorian calendar */
++ if (y < 1583) {
++ FG_LOG( FG_EVENT, FG_ALERT,
++ "WHOOPS! Julian dates only valid for 1582 oct 15 or later" );
++ }
++
++ if ((m == 1) || (m == 2)) {
++ y -= 1;
++ m += 12;
++ }
++
++ A = y / 100;
++ B = 2 - A + (A / 4);
++ C = (int)(365.25 * y);
++ D = (int)(30.6001 * (m + 1));
++
++ JD = B + C + D + d + 1720994.5;
++
++ return JD;
++}
++
++
++/* compute greenwich mean sidereal time (GST) corresponding to a given
++ * number of seconds since the unix epoch (after duffett-smith,
++ * section 12) */
++static double GST(time_t ssue) {
++ /* time_t ssue; seconds since unix epoch */
++
++ double JD;
++ double T, T0;
++ double UT;
++ struct tm *tm;
++
++ tm = gmtime(&ssue);
++
++ JD = julian_date(tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
++ T = (JD - 2451545) / 36525;
++
++ T0 = ((T + 2.5862e-5) * T + 2400.051336) * T + 6.697374558;
++
++ T0 = fmod(T0, 24.0);
++ if (T0 < 0) T0 += 24;
++
++ UT = tm->tm_hour + (tm->tm_min + tm->tm_sec / 60.0) / 60.0;
++
++ T0 += UT * 1.002737909;
++ T0 = fmod(T0, 24.0);
++ if (T0 < 0) T0 += 24;
++
++ return T0;
++}
++
++
++/* given a particular time (expressed in seconds since the unix
++ * epoch), compute position on the earth (lat, lon) such that sun is
++ * directly overhead. (lat, lon are reported in radians */
++
++void fgSunPosition(time_t ssue, double *lon, double *lat) {
++ /* time_t ssue; seconds since unix epoch */
++ /* double *lat; (return) latitude */
++ /* double *lon; (return) longitude */
++
++ /* double lambda; */
++ double alpha, delta;
++ double tmp;
++
++ /* lambda = sun_ecliptic_longitude(ssue); */
++ /* ecliptic_to_equatorial(lambda, 0.0, &alpha, &delta); */
++ //ecliptic_to_equatorial (solarPosition.lonSun, 0.0, &alpha, &delta);
++
++ /* **********************************************************************
++ * NOTE: in the next function, each time the sun's position is updated, the
++ * the sun's longitude is returned from solarSystem->sun. Note that the
++ * sun's position is updated at a much higher frequency than the rate at
++ * which the solar system's rebuilds occur. This is not a problem, however,
++ * because the fgSunPosition we're talking about here concerns the changing
++ * position of the sun due to the daily rotation of the earth.
++ * The ecliptic longitude, however, represents the position of the sun with
++ * respect to the stars, and completes just one cycle over the course of a
++ * year. Its therefore pretty safe to update the sun's longitude only once
++ * every ten minutes. (Comment added by Durk Talsma).
++ ************************************************************************/
++
++ ecliptic_to_equatorial( SolarSystem::theSolarSystem->getSun()->getLon(),
++ 0.0, &alpha, &delta );
++ tmp = alpha - (FG_2PI/24)*GST(ssue);
++ if (tmp < -FG_PI) {
++ do tmp += FG_2PI;
++ while (tmp < -FG_PI);
++ } else if (tmp > FG_PI) {
++ do tmp -= FG_2PI;
++ while (tmp < -FG_PI);
++ }
++
++ *lon = tmp;
++ *lat = delta;
++}
++
++
++/* given a particular time expressed in side real time at prime
++ * meridian (GST), compute position on the earth (lat, lon) such that
++ * sun is directly overhead. (lat, lon are reported in radians */
++
++static void fgSunPositionGST(double gst, double *lon, double *lat) {
++ /* time_t ssue; seconds since unix epoch */
++ /* double *lat; (return) latitude */
++ /* double *lon; (return) longitude */
++
++ /* double lambda; */
++ double alpha, delta;
++ double tmp;
++
++ /* lambda = sun_ecliptic_longitude(ssue); */
++ /* ecliptic_to_equatorial(lambda, 0.0, &alpha, &delta); */
++ //ecliptic_to_equatorial (solarPosition.lonSun, 0.0, &alpha, &delta);
++ ecliptic_to_equatorial( SolarSystem::theSolarSystem->getSun()->getLon(),
++ SolarSystem::theSolarSystem->getSun()->getLat(),
++ &alpha, &delta );
++
++// tmp = alpha - (FG_2PI/24)*GST(ssue);
++ tmp = alpha - (FG_2PI/24)*gst;
++ if (tmp < -FG_PI) {
++ do tmp += FG_2PI;
++ while (tmp < -FG_PI);
++ } else if (tmp > FG_PI) {
++ do tmp -= FG_2PI;
++ while (tmp < -FG_PI);
++ }
++
++ *lon = tmp;
++ *lat = delta;
++}
++
++
++// update the cur_time_params structure with the current sun position
++void fgUpdateSunPos( void ) {
++ fgLIGHT *l;
++ fgTIME *t;
++ FGView *v;
++ MAT3vec nup, nsun, v0, surface_to_sun;
++ Point3D p, rel_sunpos;
++ double dot, east_dot;
++ double sun_gd_lat, sl_radius;
++ double ntmp;
++
++ l = &cur_light_params;
++ t = &cur_time_params;
++ v = ¤t_view;
++
++ FG_LOG( FG_EVENT, FG_INFO, " Updating Sun position" );
++
++ // (not sure why there was two)
++ // fgSunPosition(t->cur_time, &l->sun_lon, &sun_gd_lat);
++ fgSunPositionGST(t->gst, &l->sun_lon, &sun_gd_lat);
++
++ fgGeodToGeoc(sun_gd_lat, 0.0, &sl_radius, &l->sun_gc_lat);
++
++ p = Point3D( l->sun_lon, l->sun_gc_lat, sl_radius );
++ l->fg_sunpos = fgPolarToCart3d(p);
++
++ FG_LOG( FG_EVENT, FG_INFO, " t->cur_time = " << t->cur_time );
++ FG_LOG( FG_EVENT, FG_INFO,
++ " Sun Geodetic lat = " << sun_gd_lat
++ << " Geocentric lat = " << l->sun_gc_lat );
++
++ // I think this will work better for generating the sun light vector
++ l->sun_vec[0] = l->fg_sunpos.x();
++ l->sun_vec[1] = l->fg_sunpos.y();
++ l->sun_vec[2] = l->fg_sunpos.z();
++ MAT3_NORMALIZE_VEC(l->sun_vec, ntmp);
++ MAT3_SCALE_VEC(l->sun_vec_inv, l->sun_vec, -1.0);
++
++ // make sure these are directional light sources only
++ l->sun_vec[3] = 0.0;
++ l->sun_vec_inv[3] = 0.0;
++
++ // printf(" l->sun_vec = %.2f %.2f %.2f\n", l->sun_vec[0], l->sun_vec[1],
++ // l->sun_vec[2]);
++
++ // calculate the sun's relative angle to local up
++ MAT3_COPY_VEC(nup, v->get_local_up());
++ nsun[0] = l->fg_sunpos.x();
++ nsun[1] = l->fg_sunpos.y();
++ nsun[2] = l->fg_sunpos.z();
++ MAT3_NORMALIZE_VEC(nup, ntmp);
++ MAT3_NORMALIZE_VEC(nsun, ntmp);
++
++ l->sun_angle = acos(MAT3_DOT_PRODUCT(nup, nsun));
++ // printf(" SUN ANGLE relative to current location = %.3f rads.\n",
++ // l->sun_angle);
++
++ // calculate vector to sun's position on the earth's surface
++ rel_sunpos = l->fg_sunpos - (v->get_view_pos() + scenery.center);
++ v->set_to_sun( rel_sunpos.x(), rel_sunpos.y(), rel_sunpos.z() );
++ // printf( "Vector to sun = %.2f %.2f %.2f\n",
++ // v->to_sun[0], v->to_sun[1], v->to_sun[2]);
++
++ // make a vector to the current view position
++ Point3D view_pos = v->get_view_pos();
++ MAT3_SET_VEC(v0, view_pos.x(), view_pos.y(), view_pos.z());
++
++ // Given a vector from the view position to the point on the
++ // earth's surface the sun is directly over, map into onto the
++ // local plane representing "horizontal".
++ map_vec_onto_cur_surface_plane( v->get_local_up(), v0, v->get_to_sun(),
++ surface_to_sun );
++ MAT3_NORMALIZE_VEC(surface_to_sun, ntmp);
++ v->set_surface_to_sun( surface_to_sun[0], surface_to_sun[1],
++ surface_to_sun[2] );
++ // printf("Surface direction to sun is %.2f %.2f %.2f\n",
++ // v->surface_to_sun[0], v->surface_to_sun[1], v->surface_to_sun[2]);
++ // printf("Should be close to zero = %.2f\n",
++ // MAT3_DOT_PRODUCT(v->local_up, v->surface_to_sun));
++
++ // calculate the angle between v->surface_to_sun and
++ // v->surface_east. We do this so we can sort out the acos()
++ // ambiguity. I wish I could think of a more efficient way ... :-(
++ east_dot = MAT3_DOT_PRODUCT( surface_to_sun, v->get_surface_east() );
++ // printf(" East dot product = %.2f\n", east_dot);
++
++ // calculate the angle between v->surface_to_sun and
++ // v->surface_south. this is how much we have to rotate the sky
++ // for it to align with the sun
++ dot = MAT3_DOT_PRODUCT( surface_to_sun, v->get_surface_south() );
++ // printf(" Dot product = %.2f\n", dot);
++ if ( east_dot >= 0 ) {
++ l->sun_rotation = acos(dot);
++ } else {
++ l->sun_rotation = -acos(dot);
++ }
++ // printf(" Sky needs to rotate = %.3f rads = %.1f degrees.\n",
++ // angle, angle * RAD_TO_DEG); */
++}
++
++
++// $Log$
++// Revision 1.21 1999/03/22 02:08:18 curt
++// Changes contributed by Durk Talsma:
++//
++// Here's a few changes I made to fg-0.58 this weekend. Included are the
++// following features:
++// - Sun and moon have a halo
++// - The moon has a light vector, moon_angle, etc. etc. so that we can have
++// some moonlight during the night.
++// - Lot's of small changes tweakes, including some stuff Norman Vine sent
++// me earlier.
++//
++// Revision 1.20 1999/02/26 22:10:11 curt
++// Added initial support for native SGI compilers.
++//
++// Revision 1.19 1999/01/07 20:25:37 curt
++// Portability changes and updates from Bernie Bright.
++//
++// Revision 1.18 1998/12/09 18:50:36 curt
++// Converted "class fgVIEW" to "class FGView" and updated to make data
++// members private and make required accessor functions.
++//
++// Revision 1.17 1998/11/09 23:41:53 curt
++// Log message clean ups.
++//
++// Revision 1.16 1998/11/07 19:07:14 curt
++// Enable release builds using the --without-logging option to the configure
++// script. Also a couple log message cleanups, plus some C to C++ comment
++// conversion.
++//
++// Revision 1.15 1998/10/18 01:17:24 curt
++// Point3D tweaks.
++//
++// Revision 1.14 1998/10/17 01:34:32 curt
++// C++ ifying ...
++//
++// Revision 1.13 1998/10/16 00:56:12 curt
++// Converted to Point3D class.
++//
++// Revision 1.12 1998/09/15 04:27:50 curt
++// Changes for new astro code.
++//
++// Revision 1.11 1998/08/12 21:13:22 curt
++// Optimizations by Norman Vine.
++//
++// Revision 1.10 1998/07/22 21:45:39 curt
++// fg_time.cxx: Removed call to ctime() in a printf() which should be harmless
++// but seems to be triggering a bug.
++// light.cxx: Added code to adjust fog color based on sunrise/sunset effects
++// and view orientation. This is an attempt to match the fog color to the
++// sky color in the center of the screen. You see discrepancies at the
++// edges, but what else can be done?
++// sunpos.cxx: Caculate local direction to sun here. (what compass direction
++// do we need to face to point directly at sun)
++//
++// Revision 1.9 1998/07/08 14:48:39 curt
++// polar3d.h renamed to polar3d.hxx
++//
++// Revision 1.8 1998/05/02 01:53:18 curt
++// Fine tuning mktime() support because of varying behavior on different
++// platforms.
++//
++// Revision 1.7 1998/04/30 12:36:05 curt
++// C++-ifying a couple source files.
++//
++// Revision 1.6 1998/04/28 01:22:18 curt
++// Type-ified fgTIME and fgVIEW.
++//
++// Revision 1.5 1998/04/26 05:10:05 curt
++// "struct fgLIGHT" -> "fgLIGHT" because fgLIGHT is typedef'd.
++//
++// Revision 1.4 1998/04/25 22:06:34 curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.3 1998/04/25 20:24:03 curt
++// Cleaned up initialization sequence to eliminate interdependencies
++// between sun position, lighting, and view position. This creates a
++// valid single pass initialization path.
++//
++// Revision 1.2 1998/04/24 00:52:31 curt
++// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
++// Fog color fixes.
++// Separated out lighting calcs into their own file.
++//
++// Revision 1.1 1998/04/22 13:24:07 curt
++// C++ - ifiing the code a bit.
++// Starting to reorginize some of the lighting calcs to use a table lookup.
++//
++// Revision 1.27 1998/04/03 22:12:57 curt
++// Converting to Gnu autoconf system.
++// Centralized time handling differences.
++//
++// Revision 1.26 1998/02/23 19:08:00 curt
++// Incorporated Durk's Astro/ tweaks. Includes unifying the sun position
++// calculation code between sun display, and other FG sections that use this
++// for things like lighting.
++//
++// Revision 1.25 1998/02/09 15:07:53 curt
++// Minor tweaks.
++//
++// Revision 1.24 1998/01/27 00:48:07 curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.23 1998/01/19 19:27:21 curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.22 1998/01/19 18:40:40 curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.21 1997/12/30 23:10:19 curt
++// Calculate lighting parameters here.
++//
++// Revision 1.20 1997/12/30 22:22:43 curt
++// Further integration of event manager.
++//
++// Revision 1.19 1997/12/30 20:47:59 curt
++// Integrated new event manager with subsystem initializations.
++//
++// Revision 1.18 1997/12/23 04:58:40 curt
++// Tweaked the sky coloring a bit to build in structures to allow finer rgb
++// control.
++//
++// Revision 1.17 1997/12/15 23:55:08 curt
++// Add xgl wrappers for debugging.
++// Generate terrain normals on the fly.
++//
++// Revision 1.16 1997/12/11 04:43:57 curt
++// Fixed sun vector and lighting problems. I thing the moon is now lit
++// correctly.
++//
++// Revision 1.15 1997/12/10 22:37:55 curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.14 1997/12/09 04:25:39 curt
++// Working on adding a global lighting params structure.
++//
++// Revision 1.13 1997/11/25 19:25:42 curt
++// Changes to integrate Durk's moon/sun code updates + clean up.
++//
++// Revision 1.12 1997/11/15 18:15:39 curt
++// Reverse direction of sun vector, so object normals can be more normal.
++//
++// Revision 1.11 1997/10/28 21:07:21 curt
++// Changed GLUT/ -> Main/
++//
++// Revision 1.10 1997/09/13 02:00:09 curt
++// Mostly working on stars and generating sidereal time for accurate star
++// placement.
++//
++// Revision 1.9 1997/09/05 14:17:31 curt
++// More tweaking with stars.
++//
++// Revision 1.8 1997/09/05 01:36:04 curt
++// Working on getting stars right.
++//
++// Revision 1.7 1997/09/04 02:17:40 curt
++// Shufflin' stuff.
++//
++// Revision 1.6 1997/08/27 03:30:37 curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.5 1997/08/22 21:34:41 curt
++// Doing a bit of reorganizing and house cleaning.
++//
++// Revision 1.4 1997/08/19 23:55:09 curt
++// Worked on better simulating real lighting.
++//
++// Revision 1.3 1997/08/13 20:23:49 curt
++// The interface to sunpos now updates a global structure rather than returning
++// current sun position.
++//
++// Revision 1.2 1997/08/06 00:24:32 curt
++// Working on correct real time sun lighting.
++//
++// Revision 1.1 1997/08/01 15:27:56 curt
++// Initial revision.
++//
--- /dev/null
--- /dev/null
++/*
++ * sunpos.hxx (taken from XEarth)
++ * kirk johnson
++ * july 1993
++ *
++ * code for calculating the position on the earth's surface for which
++ * the sun is directly overhead (adapted from _practical astronomy
++ * with your calculator, third edition_, peter duffett-smith,
++ * cambridge university press, 1988.)
++ *
++ * RCS $Id$
++ *
++ * Copyright (C) 1989, 1990, 1993, 1994, 1995 Kirk Lauritz Johnson
++ *
++ * Parts of the source code (as marked) are:
++ * Copyright (C) 1989, 1990, 1991 by Jim Frost
++ * Copyright (C) 1992 by Jamie Zawinski <jwz@lucid.com>
++ *
++ * Permission to use, copy, modify and freely distribute xearth for
++ * non-commercial and not-for-profit purposes is hereby granted
++ * without fee, provided that both the above copyright notice and this
++ * permission notice appear in all copies and in supporting
++ * documentation.
++ *
++ * The author makes no representations about the suitability of this
++ * software for any purpose. It is provided "as is" without express or
++ * implied warranty.
++ *
++ * THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
++ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
++ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT
++ * OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
++ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
++ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++
++#ifndef _SUNPOS_HXX
++#define _SUNPOS_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++#include "Include/compiler.h"
++#ifdef FG_HAVE_STD_INCLUDES
++# include <ctime>
++#else
++# include <time.h>
++#endif
++
++/* update the cur_time_params structure with the current sun position */
++void fgUpdateSunPos( void );
++
++/* update the cur_time_params structure with the current moon position */
++void fgUpdateMoonPos( void );
++
++void fgSunPosition(time_t ssue, double *lon, double *lat);
++
++
++#endif /* _SUNPOS_H */
--- /dev/null
--- /dev/null
++//
++// timestamp.hxx -- class for managing a timestamp (seconds & milliseconds.)
++//
++// Written by Curtis Olson, started December 1998.
++//
++// Copyright (C) 1998 Curtis L. Olson - curt@flightgear.org
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#ifndef _TIMESTAMP_HXX
++#define _TIMESTAMP_HXX
++
++
++#ifndef __cplusplus
++# error This library requires C++
++#endif
++
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++
++#include "Include/compiler.h"
++#ifdef FG_HAVE_STD_INCLUDES
++# include <ctime>
++#else
++# include <time.h>
++#endif
++
++#ifdef HAVE_SYS_TIMEB_H
++# include <sys/timeb.h> // for ftime() and struct timeb
++#endif
++#ifdef HAVE_UNISTD_H
++# include <unistd.h> // for gettimeofday()
++#endif
++#ifdef HAVE_SYS_TIME_H
++# include <sys/time.h> // for get/setitimer, gettimeofday, struct timeval
++#endif
++
++#ifdef WIN32
++# include <windows.h>
++# if defined( __CYGWIN__ ) || defined( __CYGWIN32__ )
++# define NEAR /* */
++# define FAR /* */
++# endif
++# include <mmsystem.h>
++#endif
++
++// MSVC++ 6.0 kuldge - Need forward declaration of friends.
++class FGTimeStamp;
++FGTimeStamp operator + (const FGTimeStamp& t, const long& m);
++long operator - (const FGTimeStamp& a, const FGTimeStamp& b);
++
++class FGTimeStamp {
++
++private:
++
++ long seconds;
++ long usec;
++
++public:
++
++ FGTimeStamp();
++ FGTimeStamp( const long s, const long m );
++ ~FGTimeStamp();
++
++ // Set time to current time
++ void stamp();
++
++ FGTimeStamp& operator = ( const FGTimeStamp& t );
++
++ friend FGTimeStamp operator + (const FGTimeStamp& t, const long& m);
++ friend long operator - (const FGTimeStamp& a, const FGTimeStamp& b);
++
++ inline long get_seconds() const { return seconds; }
++ // inline long get_usec() const { return usec; }
++};
++
++inline FGTimeStamp::FGTimeStamp() {
++}
++
++inline FGTimeStamp::FGTimeStamp( const long s, const long u ) {
++ seconds = s;
++ usec = u;
++}
++
++inline FGTimeStamp::~FGTimeStamp() {
++}
++
++inline FGTimeStamp& FGTimeStamp::operator = (const FGTimeStamp& t)
++{
++ seconds = t.seconds;
++ usec = t.usec;
++ return *this;
++}
++
++inline void FGTimeStamp::stamp() {
++#if defined( WIN32 )
++ unsigned int t;
++ t = timeGetTime();
++ seconds = 0;
++ usec = t * 1000;
++#elif defined( HAVE_GETTIMEOFDAY )
++ struct timeval current;
++ struct timezone tz;
++ // fg_timestamp currtime;
++ gettimeofday(¤t, &tz);
++ seconds = current.tv_sec;
++ usec = current.tv_usec;
++#elif defined( HAVE_GETLOCALTIME )
++ SYSTEMTIME current;
++ GetLocalTime(¤t);
++ seconds = current.wSecond;
++ usec = current.wMilliseconds * 1000;
++#elif defined( HAVE_FTIME )
++ struct timeb current;
++ ftime(¤t);
++ seconds = current.time;
++ usec = current.millitm * 1000;
++#else
++# error Port me
++#endif
++}
++
++// difference between time stamps in microseconds (usec)
++inline FGTimeStamp operator + (const FGTimeStamp& t, const long& m) {
++#ifdef WIN32
++ return FGTimeStamp( 0, t.usec + m );
++#else
++ return FGTimeStamp( t.seconds + ( t.usec + m ) / 1000000,
++ ( t.usec + m ) % 1000000 );
++#endif
++}
++
++// difference between time stamps in microseconds (usec)
++inline long operator - (const FGTimeStamp& a, const FGTimeStamp& b)
++{
++#if defined( WIN32 )
++ return a.usec - b.usec;
++#else
++ return 1000000 * (a.seconds - b.seconds) + (a.usec - b.usec);
++#endif
++}
++
++
++#endif // _TIMESTAMP_HXX
++
++
++// $Log$
++// Revision 1.5 1999/02/02 20:13:43 curt
++// MSVC++ portability changes by Bernie Bright:
++//
++// Lib/Serial/serial.[ch]xx: Initial Windows support - incomplete.
++// Simulator/Astro/stars.cxx: typo? included <stdio> instead of <cstdio>
++// Simulator/Cockpit/hud.cxx: Added Standard headers
++// Simulator/Cockpit/panel.cxx: Redefinition of default parameter
++// Simulator/Flight/flight.cxx: Replaced cout with FG_LOG. Deleted <stdio.h>
++// Simulator/Main/fg_init.cxx:
++// Simulator/Main/GLUTmain.cxx:
++// Simulator/Main/options.hxx: Shuffled <fg_serial.hxx> dependency
++// Simulator/Objects/material.hxx:
++// Simulator/Time/timestamp.hxx: VC++ friend kludge
++// Simulator/Scenery/tile.[ch]xx: Fixed using std::X declarations
++// Simulator/Main/views.hxx: Added a constant
++//
++// Revision 1.4 1999/01/09 13:37:46 curt
++// Convert fgTIMESTAMP to FGTimeStamp which holds usec instead of ms.
++//
++// Revision 1.3 1999/01/07 20:25:39 curt
++// Portability changes and updates from Bernie Bright.
++//
++// Revision 1.2 1998/12/11 20:26:56 curt
++// #include tweaks.
++//
++// Revision 1.1 1998/12/05 14:21:33 curt
++// Moved struct fg_timestamp to class fgTIMESTAMP and moved it's definition
++// to it's own file, timestamp.hxx.
++//
--- /dev/null
--- /dev/null
++# libdir = ${exec_prefix}/lib
++# lib_LTLIBRARIES = libWeather.la
++# libWeather_la_SOURCES = weather.c weather.h
++
++noinst_LIBRARIES = libWeather.a
++
++libWeather_a_SOURCES = weather.cxx weather.hxx
++
++INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib -I$(top_builddir)/Simulator
--- /dev/null
--- /dev/null
++// weather.cxx -- routines to model weather
++//
++// Written by Curtis Olson, started July 1997.
++//
++// Copyright (C) 1997 Curtis L. Olson - curt@me.umn.edu
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++# include <windows.h>
++#endif
++
++#include <GL/glut.h>
++#include <XGL/xgl.h>
++
++#include <math.h>
++
++#include <Aircraft/aircraft.hxx>
++#include <Debug/logstream.hxx>
++#include <Math/fg_random.h>
++#include <Weather/weather.hxx>
++
++
++// This is a record containing current weather info
++FGWeather current_weather;
++
++
++FGWeather::FGWeather() {
++}
++
++
++FGWeather::~FGWeather() {
++}
++
++
++// Initialize the weather modeling subsystem
++void FGWeather::Init( ) {
++ FG_LOG( FG_GENERAL, FG_INFO, "Initializing weather subsystem");
++
++ // Configure some wind
++ // FG_V_north_airmass = 15; // ft/s =~ 10mph
++
++ // set_visibility( 45000.0 ); // in meters
++ set_visibility( 32000.0 ); // about 20 miles (in meters)
++}
++
++
++// Update the weather parameters for the current position
++void FGWeather::Update( void ) {
++ FGInterface *f;
++
++ f = current_aircraft.fdm_state;
++
++ // Add some random turbulence
++ // f->set_U_gust( fg_random() * 5.0 - 2.5 );
++ // f->set_V_gust( fg_random() * 5.0 - 2.5 );
++ // f->set_W_gust( fg_random() * 5.0 - 2.5 );
++}
++
++
++// $Log$
++// Revision 1.6 1999/02/05 21:29:21 curt
++// Modifications to incorporate Jon S. Berndts flight model code.
++//
++// Revision 1.5 1998/12/06 13:51:26 curt
++// Turned "struct fgWEATHER" into "class FGWeather".
++//
++// Revision 1.4 1998/12/05 15:54:31 curt
++// Renamed class fgFLIGHT to class FGState as per request by JSB.
++//
++// Revision 1.3 1998/11/23 21:49:11 curt
++// Borland portability tweaks.
++//
++// Revision 1.2 1998/11/06 21:18:29 curt
++// Converted to new logstream debugging facility. This allows release
++// builds with no messages at all (and no performance impact) by using
++// the -DFG_NDEBUG flag.
++//
++// Revision 1.1 1998/10/17 01:34:36 curt
++// C++ ifying ...
++//
++// Revision 1.18 1998/10/02 12:46:50 curt
++// Added an "auto throttle"
++//
++// Revision 1.17 1998/07/20 12:51:57 curt
++// Default visibility to about 20 miles.
++//
++// Revision 1.16 1998/06/12 01:00:59 curt
++// Build only static libraries.
++// Declare memmove/memset for Sloaris.
++// Added support for exponetial fog, which solves for the proper density to
++// achieve the desired visibility range.
++//
++// Revision 1.15 1998/04/25 22:06:34 curt
++// Edited cvs log messages in source files ... bad bad bad!
++//
++// Revision 1.14 1998/02/09 15:07:54 curt
++// Minor tweaks.
++//
++// Revision 1.13 1998/01/27 00:48:08 curt
++// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
++// system and commandline/config file processing code.
++//
++// Revision 1.12 1998/01/19 19:27:22 curt
++// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
++// This should simplify things tremendously.
++//
++// Revision 1.11 1998/01/19 18:40:41 curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.10 1997/12/30 22:22:46 curt
++// Further integration of event manager.
++//
++// Revision 1.9 1997/12/30 20:48:03 curt
++// Integrated new event manager with subsystem initializations.
++//
++// Revision 1.8 1997/12/11 04:43:58 curt
++// Fixed sun vector and lighting problems. I thing the moon is now lit
++// correctly.
++//
++// Revision 1.7 1997/12/10 22:37:56 curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.6 1997/08/27 03:30:38 curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.5 1997/08/22 21:34:42 curt
++// Doing a bit of reorganizing and house cleaning.
++//
++// Revision 1.4 1997/08/02 16:23:55 curt
++// Misc. tweaks.
++//
++// Revision 1.3 1997/07/31 22:52:41 curt
++// Working on redoing internal coordinate systems & scenery transformations.
++//
++// Revision 1.2 1997/07/30 16:12:44 curt
++// Moved fg_random routines from Util/ to Math/
++//
++// Revision 1.1 1997/07/19 23:03:57 curt
++// Initial revision.
++//
++
--- /dev/null
--- /dev/null
++// weather.hxx -- routines to model weather
++//
++// Written by Curtis Olson, started July 1997.
++//
++// Copyright (C) 1997 Curtis L. Olson - curt@me.umn.edu
++//
++// 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$
++// (Log is kept at end of this file)
++
++
++#ifndef _WEATHER_HXX
++#define _WEATHER_HXX
++
++
++// holds the current weather values
++class FGWeather {
++
++private:
++
++ double visibility;
++ GLfloat fog_exp_density;
++ GLfloat fog_exp2_density;
++
++public:
++
++ FGWeather();
++ ~FGWeather();
++
++ void Init();
++ void Update();
++
++ inline double get_visibility() const { return visibility; }
++
++ inline void set_visibility( double v ) {
++ // in meters
++ visibility = v;
++
++ // for GL_FOG_EXP
++ fog_exp_density = -log(0.01 / visibility);
++
++ // for GL_FOG_EXP2
++ fog_exp2_density = sqrt( -log(0.01) ) / visibility;
++
++ // Set correct opengl fog density
++ xglFogf (GL_FOG_DENSITY, fog_exp2_density);
++
++ // FG_LOG( FG_INPUT, FG_DEBUG, "Fog density = " << w->fog_density );
++ }
++};
++
++extern FGWeather current_weather;
++
++
++#endif // _WEATHER_HXX
++
++
++// $Log$
++// Revision 1.2 1998/12/06 13:51:27 curt
++// Turned "struct fgWEATHER" into "class FGWeather".
++//
++// Revision 1.1 1998/10/17 01:34:37 curt
++// C++ ifying ...
++//
++// Revision 1.10 1998/06/12 01:01:00 curt
++// Build only static libraries.
++// Declare memmove/memset for Sloaris.
++// Added support for exponetial fog, which solves for the proper density to
++// achieve the desired visibility range.
++//
++// Revision 1.9 1998/04/21 17:02:46 curt
++// Prepairing for C++ integration.
++//
++// Revision 1.8 1998/01/22 02:59:44 curt
++// Changed #ifdef FILE_H to #ifdef _FILE_H
++//
++// Revision 1.7 1998/01/19 18:40:41 curt
++// Tons of little changes to clean up the code and to remove fatal errors
++// when building with the c++ compiler.
++//
++// Revision 1.6 1997/12/30 22:22:47 curt
++// Further integration of event manager.
++//
++// Revision 1.5 1997/12/10 22:37:56 curt
++// Prepended "fg" on the name of all global structures that didn't have it yet.
++// i.e. "struct WEATHER {}" became "struct fgWEATHER {}"
++//
++// Revision 1.4 1997/08/27 03:30:39 curt
++// Changed naming scheme of basic shared structures.
++//
++// Revision 1.3 1997/08/22 21:34:43 curt
++// Doing a bit of reorganizing and house cleaning.
++//
++// Revision 1.2 1997/07/23 21:52:30 curt
++// Put comments around the text after an #endif for increased portability.
++//
++// Revision 1.1 1997/07/19 23:03:58 curt
++// Initial revision.
++//
++