1
0
Fork 0

source tree reorganization prior to flightgear 0.7

SimGear and TerraGear appear to have been split off at this time.
This commit is contained in:
Tim Moore 2009-09-14 14:26:20 +02:00
parent 27924da43b
commit c90db01dc8
577 changed files with 0 additions and 89784 deletions

View file

@ -1,206 +0,0 @@
%
% `AltitudeHold.tex' -- describes the FGFS Altitude Hold
%
% Written by Curtis Olson. Started December, 1997.
%
% $Id$
%------------------------------------------------------------------------
\documentclass[12pt]{article}
\usepackage{anysize}
\papersize{11in}{8.5in}
\marginsize{1in}{1in}{1in}{1in}
\usepackage{amsmath}
\usepackage{epsfig}
\usepackage{setspace}
\onehalfspacing
\usepackage{url}
\begin{document}
\title{
Flight Gear Autopilot: \\
Altitude Hold Module
}
\author{
Curtis Olson \\
(\texttt{curt@me.umn.edu})
}
\maketitle
\section{Introduction}
Working on scenery creation was becoming stressful and overwhelming.
I needed to set it aside for a few days to let my mind regroup so I
could mount a fresh attack.
As a side diversion I decided to take a stab at writing an altitude
hold module for the autopilot system and in the process hopefully
learn a bit about control theory.
\section{Control Theory 101}
Before I get too far into this section I should state clearly and up
front that I am not a ``controls'' expert and have no formal training
in this field. What I say here is said \textit{to the best of my
knowledge.} If anything here is mistaken or misleading, I'd
appreciate being corrected. I'd like to credit my boss, Bob Hain, and
my coworker, Rich Kaszeta, for explaining this basic theory to me, and
answering my many questions.
The altitude hold module I developed is an example of a PID
controller. PID stands for proportional, integral, and derivative.
These are three components to the control module that will take our
input variable (error), and calculate the value of the output variable
required to drive our error to zero.
A PID needs an input variable, and an output variable. The input
variable will be the error, or the difference between where we are,
and where we want to be. The output variable is the position of our
control surface.
The proportional component of the PID drives the output variable in
direct proportion to the input variable. If your system is such that
the output variable is zero when the error is zero and things are
mostly linear, you usually can get by with proportional control only.
However, if you do not know in advance what the output variable will
be when error is zero, you will need to add in a measure of integral
control.
The integral component drives the output based on the area under the
curve if we graph our actual position vs. target position over time.
The derivative component is something I haven't dealt with, but is
used to drive you towards your target value more quickly. I'm told
this must be used with caution since it can easily yield an unstable
system if not tuned correctly.
Typically you will take the output of each component of your PID and
combine them in some proportion to produce your final output.
The proportional component quickly stabilizes the system when used by
itself, but the system will typically stabilize to an incorrect value.
The integral component drives you towards the correct value over time,
but you typically oscillate over and under your target and does not
stabilize quickly. However, each of these provides something we want.
When we combine them, they offset each others negatives while
maintaining their desirable qualities yielding a system that does
exactly what we want.
It's actually pretty interesting and amazing when you think about it.
the proportional control gives us stability, but it introduces an
error into the system so we stabilize to the wrong value. The
integral components will continue to increase as the sum of the errors
over time increases. This pushes us back the direction we want to
go. When the system stabilizes out, we find that the integral
component precisely offsets the error introduced by the proportional
control.
The concepts are simple and the code to implement this is simple. I
am still amazed at how such a simple arrangement can so effectively
control a system.
\section{Controlling Rate of Climb}
Before we try to maintain a specific altitude, we need to be able to
control our rate of climb. Our PID controller does this through the
use of proportional and integral components. We do not know in
advance what elevator position will establish the desired rate of
climb. In fact the precise elevator position could vary as external
forces in our system change such as atmospheric density, throttle
settings, aircraft weight, etc. Because an elevator position of zero
will most likely not yield a zero rate of climb, we will need to add
in a measure of integral control to offset the error introduced by the
proportional control.
The input to our PID controller will be the difference (or error)
between our current rate of climb and our target rate of climb. The
output will be the position of the elevator needed to drive us towards
the target rate of climb.
The proportional component simply sets the elevator position in direct
proportion to our error.
\[ \mathbf{prop} = K \cdot \mathbf{error} \]
The integral component sets the elevator position based on the sum of
these errors over time. For a time, $t$
\[ \mathbf{integral} = K \cdot \int_{0}^{t} { \mathbf{error} \cdot \delta t } \]
I do nothing with the derivative component so it is always zero and
can be ignored.
The output variable is just a combination of the proportional and
integral components. $w_{\mathit{prop}}$ and $w_{\mathit{int}}$ are
weighting values. This allows you to control the contribution of each
component to your final output variable. In this case I found that
$w_{\mathit{prop}} = 0.9$ and $w_{\mathit{int}} = 0.1$ seemed to work
quite well. Too much integral control and your system won't
stabilize. Too little integral control and your system takes
excessively long to stabilize.
\[
\mathbf{output} = w_{\mathit{prop}} \cdot \mathbf{prop} +
w_{\mathit{int}} \cdot \mathbf{int}
\]
We are trying to control rate of climb with elevator position, so the
output of the above formula is our elevator position. Using this
formula to set a new elevator position each iteration quickly drives
our climb rate to the desired value.
\section{Controlling Altitude}
Now that we have our rate of climb under control, it is a simple
matter to leverage this ability to control our absolute altitude.
The input to our altitude PID controller is the difference (error)
between our current altitude and our goal altitude. The output is the
rate of climb needed to drive our altitude error to zero.
Clearly, our climb rate will be zero when we stabilize on the target
altitude. Because our output variable will be zero when our error is
zero, we can get by with only a proportional control component.
All we need to do is calculate a desired rate of climb that is
proportional to how far away we are from the target altitude. This is
a simple proportional altitude controller that sits on top of our
slightly more complicated rate of climb controller.
\[
\mathbf{target\_climb\_rate} = K \cdot ( \mathbf{target\_altitude} -
\mathbf{current\_altitude} )
\]
Thus we use the difference in altitude to determine a climb rate and
we use the desired climb rate to determine elevator position.
\section{Parameter Tuning}
I've explained the basics, but there is one more thing that is
important to mention. None of the above theory and math is going to
do you a bit of good for controlling your system if all your
parameters are out of whack. In fact, parameter tuning is often the
trickiest part of the whole process. Expect to spend a good chunk of
your time tweaking function parameters to fine tune the behavior and
effectiveness of your controller.
\end{document}
%------------------------------------------------------------------------

View file

@ -1,26 +0,0 @@
#FIG 3.2
Landscape
Center
Inches
Letter
100.00
Single
-2
1200 2
6 1800 1800 7425 4125
2 1 0 2 0 7 0 0 -1 0.000 0 0 -1 0 0 2
2400 2775 7200 2775
2 1 0 2 0 7 0 0 -1 0.000 0 0 -1 0 0 2
4800 1875 4800 3675
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 4
2400 3375 4350 3375 5250 2175 7200 2175
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
2400 2775 2400 2925
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
7200 2775 7200 2925
4 0 0 0 0 0 14 0.0000 4 150 450 2100 3150 -180\001
4 0 0 0 0 0 14 0.0000 4 150 315 7050 3150 180\001
4 0 0 0 0 0 14 0.0000 4 150 105 4875 3150 0\001
4 0 0 0 0 0 12 1.5708 4 180 1485 1950 3450 Y axist: Target Roll\001
4 0 0 0 0 0 12 0.0000 4 180 1890 3975 4050 X axis: Relative Heading\001
-6

View file

@ -1,103 +0,0 @@
%
% `HeadingHold.tex' -- describes the FGFS Heading Hold
%
% Written by Jeff Goeke-Smith
%
% $Id$
%------------------------------------------------------------------------
\documentclass[12pt]{article}
\usepackage{anysize}
\papersize{11in}{8.5in}
\marginsize{1in}{1in}{1in}{1in}
\usepackage{amsmath}
\usepackage{epsfig}
\usepackage{setspace}
\onehalfspacing
\usepackage{url}
\begin{document}
\title{
Flight Gear Autopilot: \\
Heading Hold Module
}
\author{
Jeff Goeke-Smith \\
(\texttt{jgoeke@voyager.net})
}
\maketitle
\section{Heading Hold}
The first autopilot system implemented was a heading hold system. The
entire point of the system was to hold a single heading by using the
ailerons only. Currently the system does not use the rudder for
heading or side slip control. The system of determining how to
control the ailerons is a fuzzy logic system ( at least according to
the book I borrowed from the local library) .
The first stage of the autopilot system determines the relative
heading by comparing the current heading to the target heading. This
step allows me to determine what direction I should turn.
\begin{figure}[hbt]
\centerline{
\psfig{file=HeadingHold.eps}
}
\caption{Relative heading vs. target roll}
\label{fig:headinghold}
\end{figure}
The next step determines how far I should be rolled and in what
direction. By luck, or maybe by design, If I want to move to a
negative relative heading, I need to have a negative roll. And by even
more luck, To roll in a negative direction, I need to add negative
aileron. Figure \ref{fig:headinghold} shows how I determine how far I
should be rolled. The x-axis represents the relative heading. The
y-axis represents the Target Roll. The specific values where the
graph changes slope is determined by a series of variables in the
Autopilot Structure.
% ___________________________
% /
% /
%0- - - - - - - - - - - - / - - - - - - - - - - - -
% /
%_______________________/
%| | |
%-180 0 180
Now that the we know how far the aircraft should be rolled, we now
determine the Relative roll. This being the current roll compared to
the target roll. Now that we know how far we need to roll, we employ
a near identical copy of the above routine to determine where the
aileron should be by using the x-axis to represent the relative roll
and the y-axis being the aileron setting. The system then sets the
aileron to that setting and finishes the procedure.
If anyone who reads this is interested in more information on how I
built this system, feel free to e-mail me at
\texttt{jgoeke@voyager.net} or read the code yourself.
\end{document}
%------------------------------------------------------------------------

View file

@ -1,99 +0,0 @@
\documentclass[12pt,titlepage]{article}
\usepackage{anysize}
\papersize{11in}{8.5in}
\marginsize{1in}{1in}{1in}{1in}
\begin{document}
Here is my attempt to organize descriptions of the various LaRCsim
files required to implement the equations of flight. 99\% of the
following text is copied straight out of email from Bruce, source code
comments, or the LaRCsim manual.
\section{Core LaRCsim Header Files}
\begin{description}
\item[ls\_generic.h:]1 LaRCSim generic parameters header file. Defines
the ``GENERIC'' structure which holds the current value of the
flight model parameters and states.
\item[ls\_types.h:] LaRCSim type definitions header file. Defines
the following types: SCALAR, VECTOR\_3, and DATA.
\item[ls\_constants.h:] LaRCSim constants definition header file.
Defines various constants and various units conversions.
\item[ls\_sim\_control.h:] LaRCSim simulation control parameters
header file
\end{description}
\section{Core LaRCsim Routines}
The following share the ls\_generic.h, ls\_types.h, and ls\_constants.h
header files.
\begin{description}
\item[ls\_accel.c:] ls\_accel() sums the forces and moments from aero,
engine, gear, transfer them to the center of gravity, and calculate
resulting accelerations.
\item[ls\_step.c:] ls\_step() Integration routine for equations of
motion (vehicle states.) Integrates accels $\rightarrow$
velocities and velocities $\rightarrow$ positions.
\item[ls\_aux.c:] ls\_aux() Takes the new state information
(velocities and positions) and calculates other information, like
Mach, pressures \& temps, alpha, beta, etc. for the new state. It
does this by calling atmos\_62() ls\_geodesy() and ls\_gravity().
\item[atmos\_62.c] atmos\_62() 1962 standard atmosphere table lookups.
\item[ls\_geodesy.c] ls\_geoc\_to\_geod(lat\_geoc, radius, lat\_geod, alt,
sea\_level\_r) ls\_geod\_to\_geoc(lat\_geod, alt, sl\_radius, lat\_geoc)
since vehicle position is in geocentric lat/lon/radius, this
routine calculates geodetic positions lat/lon/alt ls\_gravity -
calculates local gravity, based on latitude \& altitude.
\item[ls\_gravity:] ls\_gravity( SCALAR radius, SCALAR lat, SCALAR
*gravity ) Gravity model for LaRCsim.
\end{description}
\section{Secondary LaRCsim Routines}
The following routines help manage the simulation
\begin{description}
\item[ls\_model.c:] ls\_model() Model loop executive. Calls the user
supplied routines: inertias(), subsystems(), engine(), aero(), and
gear().
\item[default_model_routines.c:] Provides stub routines for the
routines that are normally provided by the user.
\end{description}
\section{Navion Specific Routines}
\begin{description}
\item[ls\_cockpit.h:] Header for cockpit IO. Stores the current
state of all the control inputs.
\item[navion\_aero.c:] aero() Linear aerodynamics model. Initializes
all the specific parameters if not initialized. The expected
outputs from aero() are the aerodynamic forces and moments about
the reference point, in lbs and ft-lbs, respectively, being stored
in the F\_aero\_v and M\_aero\_v vectors.
\item[navion\_engine.c:] engine() Calculate the forces generated by
the engine.
\item[navion\_gear.c:] gear() Landing gear model for example simulation.
\item[navion\_init.c:] model\_init() Initializes navion math model
\end{description}
\end{document}

View file

@ -1,375 +0,0 @@
\documentclass[10pt]{article}
\usepackage{anysize}
\papersize{11in}{8.5in}
\marginsize{0.5in}{0.5in}{0.5in}{0.5in}
\begin{document}
\section{Constants}
\begin{tabular}{|l|p{2.0in}|p{1.0in}|p{1.0in}|l|} \hline
\textbf{Variable Name} & \textbf{Variable Description} & \textbf{Data
type} & \textbf{Sign convention} & \textbf{Units of Measure} \\ \hline
PI & Ratio of circumference to diameter of a circle & Macro definition
& always positive & 3.141593 \\
EQUATORIAL\_RADIUS & Radius of the Earth at the equator & Macro definition & always positive & ft \\
RESQ & Square of radius of the Earth at the equator & Macro definition & always positive & $ft^2$ \\
FP & Flattening parameter of oblate Earth & Macro definition & always positive & 0.003353 \\
INVG & Inverse of sea level acceleration due to gravity & Macro definition & always positive & $sec^2/ft$ \\
OMEGA\_EARTH & Angular rotation velocity of the Earth & Macro definition & always positive & rad/sec \\
DEG\_TO\_RAD & "Conversion factor, degrees to radians" & Macro definition & always positive & deg/rad \\
RAD\_TO\_DEG & "Conversion factor, radians to degrees" & Macro definition & always positive & rad/deg \\
SEA\_LEVEL\_DENSITY & Atmospheric density at sea level at equator &
Macro definition & always positive & $slug/ft^3$ \\
\hline
\end{tabular}
\section{Variables}
\subsection{Time}
\begin{tabular}{|l|p{2.0in}|p{1.0in}|p{1.0in}|l|} \hline
\textbf{Variable Name} & \textbf{Variable Description} & \textbf{Data
type} & \textbf{Sign convention} & \textbf{Units of Measure} \\ \hline
Simtime & Simulated time since beginning of current run & & & sec \\
\hline
\end{tabular}
\subsection{Mass properties and geometry values}
\begin{tabular}{|l|p{2.0in}|p{1.0in}|p{1.0in}|l|} \hline
\textbf{Variable Name} & \textbf{Variable Description} & \textbf{Data
type} & \textbf{Sign convention} & \textbf{Units of Measure} \\ \hline
Mass & Mass of simulated vehicle & Scalar & always positive & slugs \\
I\_xx & Moment of inertia about X-body axis & Scalar & always positive & $slug-ft^2$ \\
I\_yy & Moment of inertia about Y-body axis & Scalar & always positive & $slug-ft^2$ \\
I\_zz & Moment of inertia about Y-body axis & Scalar & always positive & $slug-ft^2$ \\
I\_xz & Second moment of inertia in X-Z plane & Scalar & +Integral(x z dm) & $slug-ft^2$ \\
\hline
D\_pilot\_rp\_body\_v[3] & Pilot offset from ref pt in body axis & 3-element array & - - & ft \\
Dx\_pilot & Pilot offset from ref pt in X body axis & Scalar & forward & ft \\
Dy\_pilot & Pilot offset from ref pt in X body axis & Scalar & right & ft \\
Dz\_pilot & Pilot offset from ref pt in X body axis & Scalar & down & ft \\
\hline
D\_cg\_rp\_body\_v[3] & Center of Gravity offset from ref pt in body axis & 3-element array & - - & ft \\
Dx\_cg & C.G. offset from ref pt in X body axis & Scalar & forward & ft \\
Dy\_cg & C.G. offset from ref pt in Y body axis & Scalar & right & ft \\
Dz\_cg & C.G. offset from ref pt in Z body axis & Scalar & down & ft \\
\hline
\end{tabular}
\subsection{Forces}
\begin{tabular}{|l|p{2.0in}|p{1.0in}|p{1.0in}|l|} \hline
\textbf{Variable Name} & \textbf{Variable Description} & \textbf{Data
type} & \textbf{Sign convention} & \textbf{Units of Measure} \\ \hline
F\_body\_total\_v[3] & Total forces on body at ref pt in body axis & 3-element array & - - & ft \\
F\_X & Force along X-body axis at ref pt & Scalar & forward & ft \\
F\_Y & Force along Y-body axis at ref pt & Scalar & right & ft \\
F\_z & Force along Z-body axis at ref pt & Scalar & down & ft \\
\hline
F\_local\_total\_v[3] & Total forces on body at ref pt in local axis & 3-element array & - - & lbf \\
F\_north & Northward force at ref pt & Scalar & north & lbf \\
F\_east & Eastward force at ref pt & Scalar & east & lbf \\
F\_down & Southward force at ref pt & Scalar & down & lbf \\
\hline
F\_aero\_v[3] & Aerodynamic forces on body at ref pt in body axis & 3-element array & - - & lbf \\
F\_X\_aero & Aero force along X-body axis at ref pt & Scalar & forward & lbf \\
F\_Y\_aero & Aero force along Y-body axis at ref pt & Scalar & right & lbf \\
F\_Z\_aero & Aero force along Z-body axis at ref pt & Scalar & down & lbf \\
\hline
F\_engine\_v[3] & Engine forces on body at ref pt in body axis & 3-element array & - - & lbf \\
F\_X\_engine & Engine force along X-body axis at ref pt & Scalar & forward & lbf \\
F\_Y\_engine & Engine force along Y-body axis at ref pt & Scalar & right & lbf \\
F\_Z\_engine & Engine force along Z-body axis at ref pt & Scalar & down & lbf \\
\hline
F\_gear\_v[3] & Landing gear forces on body at ref pt in body axis & 3-element array & - - & lbf \\
F\_X\_gear & Gear force along X-body axis at ref pt & Scalar & forward & lbf \\
F\_Y\_gear & Gear force along Y-body axis at ref pt & Scalar & right & lbf \\
F\_Z\_gear & Gear force along Z-body axis at ref pt & Scalar & down & lbf \\
\hline
\end{tabular}
\subsection{Moments}
\begin{tabular}{|l|p{2.0in}|p{1.0in}|p{1.0in}|l|} \hline
\textbf{Variable Name} & \textbf{Variable Description} & \textbf{Data
type} & \textbf{Sign convention} & \textbf{Units of Measure} \\ \hline
M\_total\_rp\_v[3] & Total moments on body at ref pt measured around body axes & 3-element array & - - & ft-lb \\
M\_l\_rp & Total moments on body at ref pt about X-body axis & Scalar & right wing down & ft-lb \\
M\_m\_rp & Total moments on body at ref pt about Y-body axis & Scalar & Nose up & ft-lb \\
M\_n\_rp & Total moments on body at ref pt about Z-body axis & Scalar & Nose left & ft-lb \\
\hline
M\_total\_cg\_v[3] & Total moments on body at ref pt measured around body axes & 3-element array & - - & ft-lb \\
M\_l\_cg & Total moments on body at ref pt about X-body axis & Scalar & right wing down & ft-lb \\
M\_m\_cg & Total moments on body at ref pt about Y-body axis & Scalar & Nose up & ft-lb \\
M\_n\_cg & Total moments on body at ref pt about Z-body axis & Scalar & Nose left & ft-lb \\
\hline
M\_aero\_v[3] & Aerodynamic moments on body at ref pt measured around body axes & 3-element array & - - & ft-lb \\
M\_l\_aero & Aerodynamic moments on body at ref pt about X-body axis & Scalar & right wing down & ft-lb \\
M\_m\_aero & Aerodynamic moments on body at ref pt about Y-body axis & Scalar & Nose up & ft-lb \\
M\_n\_aero & Aerodynamic moments on body at ref pt about Z-body axis & Scalar & Nose left & ft-lb \\
\hline
M\_engine\_v[3] & Propulsion system moments on body at ref pt measured around body axes & 3-element array & - - & ft-lb \\
M\_l\_engine & Propulsion system moments on body at ref pt about X-body axis & Scalar & right wing down & ft-lb \\
M\_m\_engine & Propulsion system moments on body at ref pt about Y-body axis & Scalar & Nose up & ft-lb \\
M\_n\_engine & Propulsion system moments on body at ref pt about Z-body axis & Scalar & Nose left & ft-lb \\
\hline
M\_gear\_v[3] & Landing gear moments on body at ref pt measured around body axes & 3-element array & - - & ft-lb \\
M\_l\_gear & Landing gear moments on body at ref pt about X-body axis & Scalar & right wing down & ft-lb \\
M\_m\_gear & Landing gear moments on body at ref pt about Y-body axis & Scalar & Nose up & ft-lb \\
M\_n\_gear & Landing gear moments on body at ref pt about Z-body axis & Scalar & Nose left & ft-lb \\
\hline
\end{tabular}
\subsection{Accelerations}
\begin{tabular}{|l|p{2.0in}|p{1.0in}|p{1.0in}|l|} \hline
\textbf{Variable Name} & \textbf{Variable Description} & \textbf{Data
type} & \textbf{Sign convention} & \textbf{Units of Measure} \\ \hline
V\_dot\_local\_v[3] & Inertial acceleration of center of gravity measured in local axes & 3-element array & - - & $ft/sec^2$ \\
V\_dot\_north & Inertial acceleration of center of gravity measured in local North axis & Scalar & north & $ft/sec^2$ \\
V\_dot\_east & Inertial acceleration of center of gravity measured in local East axis & Scalar & east & $ft/sec^2$ \\
V\_dot\_down & Inertial acceleration of center of gravity measured in local down axis & Scalar & down & $ft/sec^2$ \\
\hline
V\_dot\_body\_v[3] & Inertial acceleration of ?? measured in body axes & 3-element array & - - & $ft/sec^2$ \\
U\_dot\_body & Inertial acceleration of ?? measured in body X axis & Scalar & forward & $ft/sec^2$ \\
V\_dot\_body & Inertial acceleration of ?? measured in body Y axis & Scalar & right & $ft/sec^2$ \\
W\_dot\_body & Inertial acceleration of ?? measured in body Z axis & Scalar & down & $ft/sec^2$ \\
\hline
A\_cg\_body\_v[3] & Inertial acceleration of center of gravity measured in body axes & 3-element array & - - & $ft/sec^2$ \\
A\_X\_cg & Inertial acceleration of center of gravity measured in body X axis & Scalar & forward & $ft/sec^2$ \\
A\_Y\_cg & Inertial acceleration of center of gravity measured in body Y axis & Scalar & right & $ft/sec^2$ \\
A\_Z\_cg & Inertial acceleration of center of gravity measured in body Z axis & Scalar & down & $ft/sec^2$ \\
\hline
A\_pilot\_body\_v[3] & Inertial acceleration of pilot station measured in body axes & 3-element array & - - & $ft/sec^2$ \\
A\_X\_pilot & Inertial acceleration of pilot station measured in body X axis & Scalar & forward & $ft/sec^2$ \\
A\_Y\_pilot & Inertial acceleration of pilot station measured in body Y axis & Scalar & right & $ft/sec^2$ \\
A\_Z\_pilot & Inertial acceleration of pilot station measured in body Z axis & Scalar & down & $ft/sec^2$ \\
\hline
N\_cg\_body\_v[3] & Inertial acceleration of center of gravity measured in body axes & 3-element array & - - & g units \\
N\_X\_cg & Inertial acceleration of center of gravity measured in body X axis & Scalar & forward & g units \\
N\_Y\_cg & Inertial acceleration of center of gravity measured in body Y axis & Scalar & right & g units \\
N\_Z\_cg & Inertial acceleration of center of gravity measured in body Z axis & Scalar & down & g units \\
\hline
N\_pilot\_body\_v[3] & Inertial acceleration of pilot station measured in body axes & 3-element array & - - & g units \\
N\_X\_pilot & Inertial acceleration of pilot station measured in body X axis & Scalar & forward & g units \\
N\_Y\_pilot & Inertial acceleration of pilot station measured in body Y axis & Scalar & right & g units \\
N\_Z\_pilot & Inertial acceleration of pilot station measured in body Z axis & Scalar & down & g units \\
\hline
\end{tabular}
\subsection{Accelerations (Cont.)}
\begin{tabular}{|l|p{2.0in}|p{1.0in}|p{1.0in}|l|} \hline
\textbf{Variable Name} & \textbf{Variable Description} & \textbf{Data
type} & \textbf{Sign convention} & \textbf{Units of Measure} \\ \hline
Omega\_dot\_body\_v[3] & Angular acceleration of vehicle relative to local frame about center of gravity in body axes & 3-element array & - - & $rad/s^2$ \\
P\_dot\_body & Angular acceleration of vehicle relative to local frame about center of gravity in X body axis & Scalar & rt wing down & $rad/s^2$ \\
Q\_dot\_body & Angular acceleration of vehicle relative to local frame about center of gravity in Y body axis & Scalar & nose up & $rad/s^2$ \\
R\_dot\_body & Angular acceleration of vehicle relative to local frame about center of gravity in Z body axis & Scalar & nose right & $rad/s^2$ \\
\hline
\end{tabular}
\subsection{Velocities}
\begin{tabular}{|l|p{2.0in}|p{1.0in}|p{1.0in}|l|} \hline
\textbf{Variable Name} & \textbf{Variable Description} & \textbf{Data
type} & \textbf{Sign convention} & \textbf{Units of Measure} \\ \hline
V\_local\_v[3] & Inertial velocity of center of gravity in local axes & 3-element array & - - & ft/s \\
V\_north & Inertial velocity of center of gravity in local North axis & Scalar & north & ft/s \\
V\_east & Inertial velocity of center of gravity in local East axis & Scalar & east & ft/s \\
V\_down & Inertial velocity of center of gravity in local down axis & Scalar & down & ft/s \\
\hline
V\_local\_rel\_ground\_v[3] & Velocity of center of gravity relative to earth surface in local axes & 3-element array & - - & ft/s \\
V\_north\_rel\_ground & Velocity of center of gravity relative to earth surface in local North axis & Scalar & north & ft/s \\
V\_east\_rel\_ground & Velocity of center of gravity relative to earth surface in local east axis & Scalar & east & ft/s \\
V\_down\_rel\_ground & Velocity of center of gravity relative to earth surface in local down axis & Scalar & down & ft/s \\
\hline
V\_local\_airmass\_v[3] & Inertial steady-state velocity of airmass in local axes & 3-element array & - - & ft/s \\
V\_north\_airmass & Inertial steady-state velocity of airmass in local North axis & Scalar & north & ft/s \\
V\_east\_airmass & Inertial steady-state velocity of airmass in local East axis & Scalar & east & ft/s \\
V\_down\_airmass & Inertial steady-state velocity of airmass in local down axis & Scalar & down & ft/s \\
\hline
V\_local\_rel\_airmass\_v[3] & Velocity of center of gravity relative to local airmass in local axes & 3-element array & - - & ft/s \\
V\_north\_rel\_airmass & Velocity of center of gravity relative to local airmass in local North axis & Scalar & north & ft/s \\
V\_east\_rel\_airmass & Velocity of center of gravity relative to local airmass in local East axis & Scalar & east & ft/s \\
V\_down\_rel\_airmass & Velocity of center of gravity relative to local airmass in local down axis & Scalar & down & ft/s \\
\hline
V\_body\_gust\_v[3] & Gust velocity in body axes & 3-element array & - - & ft/s \\
U\_gust & Gust velocity in X-body axes & Scalar & forward & ft/s \\
V\_gust & Gust velocity in Y-body axes & Scalar & right & ft/s \\
W\_gust & Gust velocity in Z-body axes & Scalar & down & ft/s \\
\hline
\end{tabular}
\subsection{Velocities (Cont.)}
\begin{tabular}{|l|p{2.0in}|p{1.0in}|p{1.0in}|l|} \hline
\textbf{Variable Name} & \textbf{Variable Description} & \textbf{Data
type} & \textbf{Sign convention} & \textbf{Units of Measure} \\ \hline
V\_wind\_body\_v[3] & Velocity of center of gravity relative to local airmass in body axes & 3-element array & - - & ft/s \\
U\_body & Velocity of center of gravity relative to local airmass in X-body axis & Scalar & forward & ft/s \\
V\_body & Velocity of center of gravity relative to local airmass in Y-body axis & Scalar & right & ft/s \\
W\_body & Velocity of center of gravity relative to local airmass in Z-body axis & Scalar & down & ft/s \\
\hline
V\_rel\_wind & Velocity relative to airmass & Scalar & always positive & ft/s \\
V\_true\_knots & True airspeed in knots & Scalar & always positive & nm/hr \\
V\_rel\_ground & Velocity relative to earth's surface & Scalar & always positive & ft/s \\
V\_inertial & Inertial velocity & Scalar & always positive & ft/s \\
V\_ground\_speed & Velocity at right angles to local vertical & Scalar & always positive & ft/s \\
V\_equiv & Equivalent airspeed & Scalar & always positive & ft/s \\
V\_equiv\_kts & "Equivalent airspeed, knots" & Scalar & always positive & nm/hr \\
V\_calibrated & Calibrated airspeed & Scalar & always positive & ft/s \\
V\_calibrated\_kts & "Calibrated airspeed, knots" & Scalar & always positive & nm/hr \\
\hline
Omega\_body\_v[3] & Inertial rotational rate of the body axis frame & 3-element array & - - & rad/s \\
P\_body & Inertial rotational rate of the body X-axis & Scalar & rt wing down & rad/s \\
Q\_body & Inertial rotational rate of the body Y-axis & Scalar & nose up & rad/s \\
R\_body & Inertial rotational rate of the body Z-axis & Scalar & nose right & rad/s \\
\hline
Omega\_local\_v[3] & Inertial rotational rate of the local axis frame & 3-element array & - - & rad/s \\
P\_local & Inertial rotational rate of the local axis frame about the body X-axis & Scalar & rt wing down & rad/s \\
Q\_local & Inertial rotational rate of the local axis frame about the body Y-axis & Scalar & nose up & rad/s \\
R\_local & Inertial rotational rate of the local axis frame about the body Z-axis & Scalar & nose right & rad/s \\
\hline
\end{tabular}
\subsection{Velocities (Cont.)}
\begin{tabular}{|l|p{2.0in}|p{1.0in}|p{1.0in}|l|} \hline
\textbf{Variable Name} & \textbf{Variable Description} & \textbf{Data
type} & \textbf{Sign convention} & \textbf{Units of Measure} \\ \hline
Omega\_total\_v[3] & Rotational rate of the body axis frame relative to the local axis frame & 3-element array & - - & rad/s \\
P\_total & Rotational rate of the body axis frame relative to the local axis frame about the body X-axis & Scalar & rt wing down & rad/s \\
Q\_total & Rotational rate of the body axis frame relative to the local axis frame about the body Y-axis & Scalar & nose up & rad/s \\
R\_total & Rotational rate of the body axis frame relative to the local axis frame about the body Z-axis & Scalar & nose right & rad/s \\
\hline
Euler\_rates\_v[3] & "Rotational rate of the body axis frame relative to the local axis frame, in Euler angles" & 3-element array & - - & rad/s \\
Phi\_dot & Rotational rate of the body axis frame about the local X-axis & Scalar & rt wing down & rad/s \\
Theta\_dot & Rotational rate of the body axis frame about the local Y-axis & Scalar & nose up & rad/s \\
Psi\_dot & Rotational rate of the body axis frame about the local Z-axis & Scalar & nose right & rad/s \\
\hline
Geocentric\_rates\_v[3] & Rotational rate of the body axis frame relative to the inertial frame & 3-element array & - - & - - \\
Latitude\_dot & Rate of change of geocentric latitude angle & Scalar & westward & rad/s \\
Longitude\_dot & Rate of change of geocentric longitude angle & Scalar & northward & rad/s \\
Radius\_dot & Rate of change of radius from center of inertial frame & Scalar & outward & ft/s \\
\hline
\end{tabular}
\subsection{Positions}
\begin{tabular}{|l|p{2.0in}|p{1.0in}|p{1.0in}|l|} \hline
\textbf{Variable Name} & \textbf{Variable Description} & \textbf{Data
type} & \textbf{Sign convention} & \textbf{Units of Measure} \\ \hline
Geocentric\_position\_v[3] & Geocentric position of vehicle's center of gravity & 3-element array & - - & - - \\
Lat\_geocentric & Geocentric latitude of vehicle's center of gravity & Scalar & westward & rad \\
Lon\_geocentric & Geocentric longitude of vehicle's center of gravity & Scalar & northward & rad \\
Radius\_to\_vehicle & Radius to vehicle's center of gravity from inertial frame & Scalar & outward & ft \\
\hline
Geodetic\_position\_v[3] & Geodetic position of vehicle's center of gravity & 3-element array & - - & - - \\
Latitude & Geodetic latitude of vehicle's center of gravity & Scalar & westward & rad \\
Longitude & Geodetic longitude of vehicle's center of gravity & Scalar & northward & rad \\
Altitude & Height of vehicle's center of gravity above reference ellipsoid & Scalar & outward & ft \\
\hline
Euler\_angles\_v[3] & Vehicle's angular attitude relative to local frame & 3-element array & - - & rad \\
Phi & Roll angle & Scalar & rt wing down & rad \\
Theta & Pitch angle & Scalar & nose up & rad \\
Psi & Heading angle & Scalar & nose right & rad \\
\hline
\end{tabular}
\subsection{Miscellaneous Quantities}
\begin{tabular}{|l|p{2.0in}|p{1.0in}|p{1.0in}|l|} \hline
\textbf{Variable Name} & \textbf{Variable Description} & \textbf{Data
type} & \textbf{Sign convention} & \textbf{Units of Measure} \\ \hline
T\_local\_to\_body\_m[3][3] & Transformation matrix L to B & 3 by 3 matrix & - - & - - \\
T\_local\_to\_body\_11 & Transformation matrix element & Scalar & - - & - - \\
T\_local\_to\_body\_12 & Transformation matrix element & Scalar & - - & - - \\
T\_local\_to\_body\_13 & Transformation matrix element & Scalar & - - & - - \\
T\_local\_to\_body\_21 & Transformation matrix element & Scalar & - - & - - \\
T\_local\_to\_body\_22 & Transformation matrix element & Scalar & - - & - - \\
T\_local\_to\_body\_23 & Transformation matrix element & Scalar & - - & - - \\
T\_local\_to\_body\_31 & Transformation matrix element & Scalar & - - & - - \\
T\_local\_to\_body\_32 & Transformation matrix element & Scalar & - - & - - \\
T\_local\_to\_body\_33 & Transformation matrix element & Scalar & - - & - - \\
\hline
Gravity & Acceleration due to earth's gravity & Scalar & down & $ft/s^2$ \\
Centrifugal\_relief & Centrifugal acceleration due to near-orbital speed & Scalar & up & $ft/s^2$ \\
\hline
Alpha & Free-stream angle of attack & Scalar & nose up & rad \\
Beta & Free-stream angle of sideslip & Scalar & nose left & rad \\
Alpha\_dot & Time rate of change of free-stream angle of attack & Scalar & nose up & rad/s \\
Beta\_dot & Time rate of change of free-stream angle of sideslip & Scalar & nose left & rad/s \\
Cos\_alpha & Cosine of free-stream angle of attack & Scalar & nose up & - - \\
Sin\_alpha & Sine of free-stream angle of attack & Scalar & nose up & - - \\
Cos\_beta & Cosine of free-stream angle of sideslip & Scalar & nose left & - - \\
Sin\_beta & Sine of free-stream angle of sideslip & Scalar & nose left & - - \\
\hline
Cos\_phi & Cosine of bank angle & Scalar & rt wing down & - - \\
Sin\_phi & Sine of bank angle & Scalar & rt wing down & - - \\
Cos\_theta & Cosine of pitch angle & Scalar & nose up & - - \\
Sin\_theta & Sine of pitch angle & Scalar & nose up & - - \\
Cos\_psi & Cosine of heading angle & Scalar & nose right & - - \\
Sin\_psi & Sine of heading angle & Scalar & nose right & - - \\
\hline
Gamma\_vert\_rad & Vertical flight path angle in local frame & Scalar & climb & rad \\
Gamma\_horiz\_rad & "Horizontal flight path, or track, angle in local frame" & Scalar & clockwise from north & rad \\
\hline
Sigma & Ratio of free-stream density to sea-level reference density & Scalar & always positive & - - \\
Density & Atmospheric density (free-stream flight conditions) & Scalar & always positive & $slug/ft^3$ \\
V\_sound & Speed of sound (free-stream flight conditions) & Scalar & always positive & ft/s \\
Mach\_number & Free-stream mach number & Scalar & always positive & - - \\
\hline
Static\_pressure & Static pressure & Scalar & always positive & $lb/ft^2$ \\
Total\_pressure & Total pressure & Scalar & always positive & $lb/ft^2$ \\
Impact\_pressure & Impact pressure & Scalar & always positive & $lb/ft^2$ \\
Dynamic\_pressure & Dynamic pressure & Scalar & always positive & $lb/ft^2$ \\
\hline
Static\_temperature & Static temperature & Scalar & always positive &
$^{\circ}$R \\
Total\_temperature & Total temperature & Scalar & always positive &
$^{\circ}$R \\
\hline
\end{tabular}
\subsection{Miscellaneous Quantities (Cont.)}
\begin{tabular}{|l|p{2.0in}|p{1.0in}|p{1.0in}|l|} \hline
\textbf{Variable Name} & \textbf{Variable Description} & \textbf{Data
type} & \textbf{Sign convention} & \textbf{Units of Measure} \\ \hline
Sea\_level\_radius & Radius from earth center to local plumb sea level & Scalar & outward & ft \\
Earth\_position\_angle & Amount of rotation of the earth since reference time & Scalar & from ref time & rad \\
\hline
Runway\_altitude & Height of runway threshold above local plumb sea level (geodetic) & Scalar & up & ft \\
Runway\_latitude & Geodetic latitude of runway threshold & Scalar & northward & rad \\
Runway\_longitude & Geodetic longitude of runway threshold & Scalar & westward & rad \\
Runway\_heading & Runway heading & Scalar & clockwise from north & rad \\
Radius\_to\_rwy & Radius from earth center to runway threshold point & Scalar & outward & ft \\
\hline
D\_cg\_rwy\_local\_v[3]; & Location of center of gravity relative to runway threshold in local frame & 3-element array & - - & ft \\
D\_cg\_north\_of\_rwy & Distance of center of gravity northward from runway threshold & Scalar & northward & ft \\
D\_cg\_east\_of\_rwy & Distance of center of gravity eastward from runway threshold & Scalar & eastward & ft \\
D\_cg\_above\_rwy & Height of center of gravity above runway threshold & Scalar & up & ft \\
\hline
D\_cg\_rwy\_rwy\_v[3] & Location of center of gravity relative to runway threshold in runway frame & 3-element array & - - & ft \\
X\_cg\_rwy & Distance of center of gravity along runway centerline & Scalar & beyond threshold & ft \\
Y\_cg\_rwy & Distance of center of gravity right of runway centerline & Scalar & right of CL & ft \\
H\_cg\_rwy & Height of center of gravity above runway threshold & Scalar & up & ft \\
\hline
D\_pilot\_rwy\_local\_v[3] & Location of pilot's eyepoint relative to runway threshold in local frame & 3-element array & - - & ft \\
D\_pilot\_north\_of\_rwy & Distance of pilot's eyepoint northward form runway threshold & Scalar & northward & ft \\
D\_pilot\_east\_of\_rwy & Distance of pilot's eyepoint eastward from runway threshold & Scalar & eastward & ft \\
D\_pilot\_above\_rwy & Height of pilot's eyepoint above runway threshold & Scalar & up & ft \\
\hline
D\_pilot\_rwy\_rwy\_v[3] & Location of pilot's eyepoint relative to runway threshold in runway frame & 3-element array & - - & ft \\
X\_pilot\_rwy & Distance of pilot's eyepoint along runway centerline & Scalar & beyond threshold & ft \\
Y\_pilot\_rwy & Distance of pilot's eyepoint right of runway centerline & Scalar & right of CL & ft \\
Z\_pilot\_rwy & Height of pilot's eyepoint above runway threshold & Scalar & up & ft \\
\hline
\end{tabular}
\end{document}

Binary file not shown.

Binary file not shown.

View file

@ -1,69 +0,0 @@
From: AJBrent@aol.com
To: x-plane@me.umn.edu
Subject: Airspeed Refresher Training
Date: Fri, 19 Sep 1997 03:28:53 -0400 (EDT)
Excerpts from the book: An Invitation to Fly--Basics for the Private Pilot.
The airspeed indicator registers the total pressure from the pitot head and
subtracts from it the static pressure supplied from the static ports. This
remainder is called dynamic pressure, which is the measure of the airplane's
forward speed. This speed is displayed on the instrument's face on a
graduated scale called indicated airspeed (IAS). Remember that this value
represents the airplane's speed through the air, not necessarily it's speed
across the ground. Why? Once it is airborne, the airplane becomes part of
the local mass of air. If the mass of air is moving (that is, if the wind is
blowing), the airplane will move with the air. While this is an important
consideration during takeoffs and landings (when the airplane is making the
transition between flight and ground operations) and for navigation (the
moving airmass can carry the plane off course, like a ship in ocean
currents), it means very little to the pilot in terms of normal flight
dynamics. The airplane flies because of the speed of the relative wind, and
this is what the airspeed indicator measures, not ground speed.
Types of Airspeed:
--Indicated Airspeed. This is the direct reading of airspeed taken from the
face of the instrument, uncorrected for air density, positional errors due to
the pitot head installation, or internal instrument error.
--Calibrated Airspeed (CAS) is the indicated airspeed corrected for minor
installation and pitot head position error and mechanical losses within the
instrument itself. The manufacturer or instrument repair shop provides these
values on a cockpit reference card or in the Pilot's Operating Handbook.
[In X-Plane, I assume we are provided a perfect airspeed instrument so that
IAS and CAS are the same. CAS is not simulated.]
--Equivalent Airspeed is calibrated airspeed corrected for the
compressibility effects of high-speed flight. Normally this is not relevant
to private pilot flight planning. [And is not simulated in X-Plane as of
ver. 3.4. Equivalent airspeed is also the same as IAS in X-Plane.]
--True Airspeed is equivalent airspeed (or calibrated airspeed if
compressibility effects are negligible) [IAS in X-Plane] corrected for the
effects of less dense air at higher altitudes. For most light airplanes,
true airspeed and calibrated airspeed are very close at sea level, but they
can diverge rapidly after the airplane climbs several thousand feet. Since
true airspeed reflects the actual physical rate at which the aircraft is
moving through the air, it is of key importance in air navigation.
You can easily recall the sequence of airspeed corrections leading to true
airspeed by memorizing the acronym ICE-T, the first letters of the four
airspeeds presented above. [Indicated, calibrated, and equivalent airspeeds
are all the same in X-Plane. So, it's just IT.] Equivalent airspeed is
important only on high-performance, turbine-powered airplanes. True
airspeed, however, must be determined before wind correction angle or ground
speed can be computed for any airplane. To make quick, accurate computations
of wind correction angle, time, distance, ground speed, and true airspeed,
you will need either a flight computer, a kind of circular slide rule, or an
electronic flight calculator, a pocket calculator constructed with special
keys and reference programs for air navigation problems. To determine true
airspeed using the flight computer, you must know the following: pressure
altitude, which may be read from the altimeter in flight with 29.92 set in
the Kollsman window; temerature in degrees Celsius, which may be read in
flight from the OAT gauge [must be converted from Fahrenheit in X-Plane]; and
indicated airspeed, which may be read from the airspeed indicator in flight.
-------
I've tried it on X-Plane using a circular, slide-rule type flight computer
while flying a Beech B99 and the F-86 at various speeds and altitudes; and it
works! My calculated TAS matched X-Plane's displayed TAS to within 2 knots
every time.
Andy Schroeder
ajbrent@aol.com

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 KiB

File diff suppressed because it is too large Load diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

File diff suppressed because it is too large Load diff

View file

@ -1,404 +0,0 @@
%%
%% getstart.tex -- Flight Gear documentation: Installation and Getting Started
%% Chapter file
%%
%% Written by Michael Basler % Bernhard Buckel, starting September 1998.
%%
%% Copyright (C) 1999 Michael Basler (pmb@knUUt.de)
%% & Bernhard Buckel (buckel@wmad95.mathematik.uni-wuerzburg.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: getstart.tex,v 0.20 1999/06/04 michael
%% (Log is kept at end of this file)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{Building the plane: Compiling\index{compiling} the program\label{building}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\markboth{\thechapter.\hspace*{1mm} BUILDING THE
PLANE}{\thesection\hspace*{1mm} COMPILING UNDER LINUX}
This central Chapter describes how to build \FlightGear on several systems. In case you
are on a Win32 (i.\,e. Windows 98 or Windows NT) platform you may not want to go though
that potentially troublesome process but instead skip that Chapter and straightly go to
the next one. (Not everyone wants to build his or her plane himself or herself, right?)
However, there may be good reason at least to try building the simulator:
\begin{itemize}
\item In case you are on a \Index{UNIX}/\Index{Linux} platform there are supposedly no
pre-compiled binaries\index{binaries, pre-compiled} available for your system. We do not
see any reason why the distribution of pre-compiled binaries (with statically linked
libraries) should not be possible for \Index{UNIX} systems in principle as well, but in
practice it is common to install programs like this one on \Index{UNIX} systems by
recompiling them.
\item There are several options you can set only during
compile time. One such option is the decision to compile with
hardware or software \Index{OpenGL} rendering enabled. A more
complete list goes beyond this \textit{Installation and Getting
Started} and should be included in a future
\textit{\Index{\FlightGear Programmer's Guide}}.
\item You may be proud you did.
\end{itemize}
On the other hand, compiling \FlightGear is not a task for novice users. Thus, if you're
a beginner (we all were once) we recommend postponing this and just starting with the
binary distribution to get you flying.
Besides, there have been two branches of code starting from version 0.6. For more
details, see Section \ref{branches}. This description generally refers to the stable,
even-numbered branch. It is almost certain, that odd-numbered versions require
modifications to that.
As you will note, this Chapter is far from being complete. Basically, we describe
compiling for two operating systems only, \Index{Windows 98/NT} and \Index{Linux}. There
is a simple explanation for this: These are just the systems we are working on. We hope
to be able to provide descriptions for more systems based on contributions written by
others.
\section{Compiling\index{compiling!Linux} under \Index{Linux}}
If you are running Linux you probably have to build your own
\Index{binaries}. The following is one way to do so.
\begin{enumerate}
%%Bernhard 25.06.1999
\item \FlightGear needs some supplementary libraries which are usually
not contained in any distribution we know of. These are:
\begin{itemize}
\item{{\em plib}} which is absolutely essential for the building
process. Get the latest version of {\em plib} at
\web{http://www.woodsoup.org/projs/plib/} and follow the
instructions contained in README.plib.
\item{{\em gfc}} is only needed if you want to build the scenery
generation tools but it doesn't hurt to have it installed. It can
be found along with the building instructions at
\web{http://www.geog.psu.edu/~qian/gfc/index.html}.
\item{{\em gpc}} which is also needed for the scenery generation
tools. Get it from
\web{http://www.cs.man.ac.uk/aig/staff/alan/software/}, building
instructions can be found in README.gpc in your \FlightGear source
directory.
\end{itemize}
Now you are ready to proceed to the task of getting, compiling and installing \FlightGear itself:
\item Get the file \texttt{FlightGear-x.xx.tar.gz} from the
\texttt{source} subdirectory under
\web{ftp://ftp.flightgear.org/pub/fgfs/Source/}
\noindent
\item Unpack it using :
\texttt{tar xvfz FlightGear-x.xx.tar.gz}.
\item \texttt{cd} into \texttt{FlightGear-x.xx}. Run:
\texttt{./configure}
\noindent
and wait a few minutes. \Index{configure} knows about a lot of
options. Have a look at the file \texttt{INSTALL} in the
\FlightGear source directory to learn about them. If run without
options, configure assumes that you will install the data files
under \texttt{/usr/local/lib/FlightGear}.
\item Assuming configure finished successfully, simply run
\texttt{make}
\noindent
and wait for the make process to finish.
\item Now become root (for example by using the su command) and
type
\texttt{make install}.
\noindent
This will install the \Index{binaries} in \texttt{/usr/local/bin}.
There is a problem concerning permissions under Linux/Glide. All programs accessing the
accelerator board need root permissions. The solution is either to play as root (this is
{\em bad} practice and not always possible) or make the \texttt{/usr/local/bin/fgfs}
binary \texttt{setuid root}, i.e. when this binary is run root privileges are given. Do
this by issuing (as root)
\texttt{chmod +s /usr/local/bin/fgfs}.
\noindent
Again, this is a quick and dirty hack. The perfect solution for this
problem is using a kernel module called {\em 3dfx.o}. It is available
along with documentation at \web{http://www.xs4all.nl/~carlo17/3dfx/index.html}
and it might be a good idea to read some of the Quake-related links there!
To install this kernel module, just download it, become root and
issue the following commands:
\texttt{mkdir dev3dfx}
\texttt{cd dev3dfx}
\texttt{tar xvfz ../Dev3Dfx-2.7.tar.gz}
\texttt{make}
\texttt{cp 3dfx.o /lib/modules/`uname -r`/misc}
\texttt{mknod /dev/3dfx c 107 0}
\texttt{insmod 3dfx}
It is a good idea to put the last line into one of your bootup scripts! After having
installed this module, you can even go ahead and remove the S-bit from {\em all} programs
that need access to your 3D hardware.
\end{enumerate}
\section{Compiling\index{compiling!Windows 98/NT} under \Index{Windows 98/NT}}
\begin{enumerate}
\item Windows, contrary to Linux which brings its own compiler, comes
not equipped with developmental tools. Several compilers have been shown to work for
compiling {\FlightGear}, including the \Index{Cygnus Win32 port of GNU C}++ and the
\Index{MS Visual C} compiler. Given that the project will be a free one we prefer the
Cygnus Compiler as it provides a free development environment. However, we will be happy
to include a proper description in case those who worked out how to compile with MSVC or
other Compilers provide one.
\item Install and configure the \Index{Cygnus} Gnu-Win32 development
environment. The latest version is Beta 20. The main
Cygnus Gnu-Win32 page is at:
\web{http://sourceware.cygnus.com/cygwin/}.
\noindent
You can download the complete Cygnus Gnu-Win32 compiler from:
\web{ftp://go.cygnus.com/pub/sourceware.cygnus.com/cygwin/latest/full.exe}.
Be sure to read this package's README files to be found under the main page, first.
\noindent
To install the compiler, just run \texttt{full.exe} by double-clicking in
Windows explorer. After doing so you'll find a program group called
\texttt{Cygnus Solutions} in your Start menu. Do not forget making a copy of the
shell under c:/bin, as detailed in the docs.
\item Open the Cygnus shell via its entry in the Start menu.
Mount the drive where you want to build \FlightGear as follows
(assuming your \FlightGear drive is \texttt{d:}):
\texttt{mkdir /mnt}\\
\texttt{mount d: /mnt}
\noindent
You only have to do this once. The drive stays mounted (until you
umount it) even through reboots and switching off the machine.
\item Before actually being able to compile \FlightGear you have to install a hand full
of support libraries required for building the simulator itself. Those go usually into
\texttt{c:/usr/local} and it is highly recommended to choose just that place.
First, you have to install the free \Index{win32 api library} (the latest
version being 0.1.5). Get the package \texttt{win32api-0.1.5.tar.gz} from:
\web{http://www.acc.umu.se/~anorland/gnu-win32/w32api.html}
Conveniently you may unpack the package just onto you \FlightGear drive. Copy the file to
the named drive, open the Cygnus shell via the Start menu entry and change to the
previously mounted drive with
\texttt{cd /mnt}
Now, you can unpack the distribution with
\texttt{gzip -d win32api-0.1.5.tar.gz}\\
\texttt{tar xvf win32api-0.1.5.tar}
This provides you with a directory containing the named libraries. For installing them,
change to that directory with
\texttt{cd win32api-0.1.5}
and type
\texttt{make}\\
\texttt{make install}
This installs the libraries to their default locations under \texttt{c:/usr/local}
\item To proceed, you need the \Index{glut libraries}. Get these from the same site named
above
\web{http://www.acc.umu.se/~anorland/gnu-win32/w32api.html}
as \texttt{glutlibs-3.7beta.tar.gz}. Just copy the package to your \FlightGear drive and
unpack it in the same way as describes above. There is no need to run \texttt{make} here.
Instead, just copy the two libraries \texttt{libglut.a} and \texttt{libglut32.a} to
\texttt{c:/usr/local/lib}. There is no need for the two accompanying \texttt{*.def} files
here.
\item Next, get the \Index{Glut header files}, for instance, from
\web{ftp:://ftp.flightgear.org/pub/fgfs/Win32/Mesa-3.0-includes.zip}
Unpack these as usual with \texttt{unzip -d} and copy the contents of the resulting
directory \texttt{/gl} to \texttt{c:/usr/local/include/gl}
\item Finally, you need Steve Backer's \Index{PLIB} being one of the key libraries for \FlightGear\hspace{-1mm}.
Get the most recent version \texttt{plib-X.X.tar.gz} from
\web{http://www.woodsoup.org/projs/plib/}
(There are mirrors, but make sure they contain the most recent version!). Copy it to your
\FlightGear drive, open the Cygnus shell and unpack the library as described above.
Next, change into \Index{PLIB}'s directory. It is recommended to configure \Index{PLIB}
with the following command line (you can make a script as I did if it hurts)
\begin{ttfamily}
CFLAGS="-O2 -Wall" CXXFLAGS="-O2 -Wall"\\ CPPFLAGS=-I/usr/local/include
LDFLAGS=-L/usr/local/lib ./configure
--prefix=/usr/local\\
--includedir=/usr/local/include/plib
\end{ttfamily}
You must write all this \textbf{on one line} without any line breaks in between!
Finally, build \Index{PLIB} with
\texttt{make}\\
\texttt{make install}
\item Now, you're finally prepared to build \FlightGear itself.
Fetch the \FlightGear code and special \Index{Win32 libraries}. These
can be found at:
\web{ftp://ftp.flightgear.org/pub/fgfs/Source/}
\noindent
Grab the latest \texttt{FlightGear-X.XX.zip} and
\texttt{win32-libs-X.XX.zip} files.
(It you're really into adventures, you can try one of the recent snapshots instead.)
\item Unpack the \FlightGear source code via
\texttt{pkunzip -d FlightGear-X.XX.zip}.
\noindent
\item Change to the newly created \texttt{FlightGear-X.XX directory} with e.\,g.
\texttt{cd //D/FlightGear-X.XX}
and unpack the Win32 libraries there:
\texttt{pkunzip -d win32-libs-X.XX.zip}.
\item You will find a file called \texttt{install.exe} in the Win32
directory after unzipping \texttt{win32-libs-X.XX.zip}. This
version of \texttt{install.exe} should replace the one in your
$\backslash$\texttt{H-i386-cygwin32$\backslash$bin} directory --
it's sole claim to fame is that it understands that when many
calls to it say \texttt{install foo} they mean \texttt{install
foo.exe}. If you skip this step and attempt an install with the
older version present \texttt{make install} will fail.
Side Note: We need to make a distinction between the
\texttt{\Index{build tree}} and the \texttt{\Index{install tree}}.
The \texttt{build tree} is what we've been talking about up until
this point. This is where the source code lives and all the
compiling takes place. Once the executables are built, they need
to be installed someplace. We shall call this install location
the \texttt{install tree}. This is where the executables, the
scenery, the textures, and any other run-time files will be
located.
\item \Index{Configure} the make system for your environment and your
\texttt{install tree}. Tell the configure script where you would like to install the
\Index{binaries} and all the \Index{scenery} and \Index{textures} by using the
\texttt{-$\!$-prefix} option. In the following example the base of the \texttt{install
tree} is \texttt{FlightGear}. Make sure you are within \FlightGear's \texttt{build tree}
root directory.
\item Run:\index{configure}
\texttt{./configure -$\!$-prefix=/mnt/FlightGear}.
\noindent
Side note: The make procedure is designed to link against opengl32.dll, glu32.dll, and
glut32.dll which most accelerated boards require. If this does not apply to yours or if
you installed SGI's \Index{software rendering} as mentioned in Subsection \ref{softrend}
you may have to change these to opengl.dll, glu.dll, and glut.dll. (In case you're in
doubt check your \texttt{$\backslash$windows$\backslash$system} directory what you've
got.)
If this is the case for your \Index{video card}, you can edit
\texttt{.../Simulator/Main/ Makefile} and rename these three libraries to
their "non-32" counterparts. There is only one place in this
\texttt{Makefile} where these files are listed.
\item Build the executable. Run:
\texttt{make}.
Assuming you have installed the updated version of \texttt{install.exe} (see earlier
instructions) you can now create and populate the \texttt{install tree}. Run:
\texttt{make install}.
You can save a significant amount of space by stripping all the
debugging symbols off of the executable. To do this, change to the
directory in the \texttt{install tree} where your binary lives and run:
\texttt{strip fgfs.exe} resp. \texttt{strip fgfs-sgi.exe}.
\end{enumerate}
%% Revision 0.00 1998/09/08 michael
%% Initial revision for version 0.53.
%% employing redame.win32/readame.linux
%% by c. olson , b. buckel
%% Revision 0.01 1998/09/20 michael
%% several extensions and corrections
%% revision 0.10 1998/10/01 michael
%% final proofreading for release
%% revision 0.11 1998/11/01 michael
%% deleted some obsolete stuff from the Linux Section
%% revision 0.12 1999/03/07 michael
%% changed Windows to Cygnus b20
%% revision 0.20 1999/06/04 michael
%% complete rewrite of the windows build Section exploiting Curt's README.win32
%% revision 0.21 1999/06/30 bernhard
%% complete rewrite of Linux build Section

View file

@ -1,332 +0,0 @@
%%
%% getstart.tex -- Flight Gear documentation: Installation and Getting Started
%% Chapter file
%%
%% Written by Michael Basler, started September 1998.
%%
%% Copyright (C) 1999 Michael Basler (pmb@knUUt.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: getstart.tex,v 0.20 1999/06/04 michael
%% (Log is kept at end of this file)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{Flight: All about instruments, keystrokes and menus\label{flight}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\markboth{\thechapter.\hspace*{1mm} FLIGHT}{\thesection\hspace*{1mm} KEYBOARD COMMANDS}
This is a description of the main systems for controlling the program and piloting the
plane: Historically, keyboard controls were developed first, and you can still control
most of the simulator via the keyboard alone. Recently, they are becoming supplemented by
several menu entries, making the interface more accessible, particularly for beginners,
and providing additional functionality. A joysticks provides a more realistic alternative
for actual piloting of the plane. Concerning instruments, there are again two
alternatives: You can use the rather advanced HUD or the emerging panel.
\section{Keyboard commands}
While \Index{joystick}s or \Index{yoke}s are supported as are rudder pedals, you can fly
\FlightGear using the keyboard alone. For proper controlling via keyboard (i) the
\texttt{\Index{NumLock}} key must be switched on (ii) the \FlightGear window must have
focus (if not, click with the mouse on the graphics window). Some of the keyboard
controls might be helpful even in case you use a joystick.
After activating \texttt{NumLock} the following \Index{keyboard commands} should work:
\eject
\noindent
Tab.\,1: \textit{Main \Index{keyboard commands} for \FlightGear}.
\medskip
\centerline{
\begin{tabular}{|l|l|}\hline
Key & Action\\\hline
Pg Up/Pg Dn & Throttle\\
Left Arrow/Right Arrow & Aileron\\
Up Arrow/Down Arrow & Elevator\\
Ins/Enter & Rudder\\
5 & Center aileron/elevator/rudder\\
Home/End & Elevator trim\\\hline
\end{tabular}
}
\vskip5mm
For changing views you have to de-activate \texttt{NumLock}. Now
\texttt{Shift} + $<$\texttt{Numeric Keypad Key}$>$ changes the
view as follows:
\noindent
Tab.\,2: \textit{View directions\index{view directions}
accessible after de-activating \texttt{NumLock}.}
\medskip
\centerline{
\begin{tabular}{|c|l|}\hline
Numeric Key & View direction\\\hline
Shift-8 & forward\\
Shift-7 & left/forward\\
Shift-4 & left\\
Shift-1 & left/back\\
Shift-2 & back\\
Shift-3 & right/back\\
Shift-6 & right\\
Shift-9 & right/forward\\\hline
\end{tabular}
}
\vskip5mm
The \Index{autopilot} is controlled via the following controls:
\medskip
\noindent
Tab.\,3: \textit{Autopilot controls.\index{autopilot controls}}
\medskip
\centerline{
\begin{tabular}{|l|l|}\hline
Key & Action\\\hline
Ctrl + A & Altitude hold toggle on/off\\
Ctrl + H & Heading hold toggle on/off\\
Ctrl + S & Autothrottle toggle on/off\\
Ctrl + T & Terrain follow toggle on/off\\
F11 & Set target altitude\\
F12 & Set target heading\\ \hline
\end{tabular}
}
\medskip
The last one is especially interesting as it makes your \Index{Navion} behave like a
cruise missile.
Besides these basic keys there are some more special ones; most of these you'll probably
not want to try during your first flight: \eject
\noindent Tab.\,4: \textit{More control commands.}
\medskip
\centerline{
\begin{tabular}{|l|l|}\hline
Key & Action\\\hline
H/h & Change color of HUD/toggle HUD off forward/backward \\
i/I & Minimize/maximize HUD \\
m/M & Change time offset (warp) used by t/T forward/backward \\
P & Toggles panel on/off \\
t/T & Time speed up/slow down forward/backward \\
x/X & Zoom in/out\\
z/Z & Change visibility (fog) forward/backward \\
b & Toggle brakes on/off\\
p & Toggle pause on/off\\
W & Toggle fullscreen mode on/off (Mesa/3dfx/Glide only)\\
F2& Refresh Scenery tile cache\\
F8 & Toggle fog on/off\\
F9 & Toggle texturing on/off\\
F10 & Toggle menu on/off\\
F11 & Sets heading in autopilot\\
F12 & Sets altitude in autopilot\\
ESC & Exit program\\\hline
\end{tabular}
}
\section{\Index{Menu entries}}
Albeit the menu being not yet fully operational it provides several useful functions. At
present, the following ones are implemented.
\begin{itemize}
\item \textbf{File}
\begin{itemize}
\item \textbf{Reset} Resets you to the selected starting position. Comes handy in case you got
lost or something went wrong.
\item \textbf{Save} Not yet operational.
\item \textbf{Print} Not yet operational.
\item \textbf{Close} Removes the menu. (Can be re-activated by hitting F10.)
\item \textbf{Exit} Exits the program.
\end{itemize}
\item \textbf{Edit}
\begin{itemize}
\item \textbf{Edit text} Not yet operational.
\end{itemize}
\item \textbf{View}
\begin{itemize}
\item \textbf{Toggle Panel} Toggles \Index{panel} on/off.
\item \textbf{View} Not yet operational.
\item \textbf{Cockpit View} Not yet operational.
\end{itemize}
\item \textbf{Aircraft}
\begin{itemize}
\item \textbf{Communication} Not yet operational.
\item \textbf{Navigation} Not yet operational.
\item \textbf{Altitude} Not yet operational.
\item \textbf{Autopilot} Sliders for setting limiting values for the autopilot.
\end{itemize}
\item \textbf{Environment}
\begin{itemize}
\item \textbf{Weather} Not yet operational.
\item \textbf{Terrain} Not yet operational.
\item \textbf{Airport} Typing in an \Index{airport id} beams you to that airport's position.
\FlightGear comes with an extended list of airport ids to be found under
/FlightGear/Aircraft/apt\underline{~}full.gz which you can unpack with gzip -d.
\end{itemize}
\item \textbf{Options}
\begin{itemize}
\item \textbf{Realism \& Reliability} Not yet operational.
\item \textbf{Preferences} Not yet operational.
\end{itemize}
\item \textbf{Help}
\begin{itemize}
\item \textbf{Help} Should bring up this \Index{Getting Started Guide}. At present not yet fully
implemented. Under windows you can get it working by placing a file called \textbf{webrun.bat}
like
\begin{texttt}
c:$\backslash$programme$\backslash$netscape$\backslash$communicator$\backslash$program$\backslash$netscape.exe\\
d:$\backslash$Flightgear$\backslash$docs$\backslash$installguide$\backslash$html$\backslash$getstart.html
\end{texttt}
(you may have to substitute your path/browser) somewhere in your path. Under UNIX a
comparable shell script might do. Requires \texttt{fgfs-manual-X.XX.exe} being properly
installed.
\item \textbf{About...} Not yet operational.
\end{itemize}
\end{itemize}
\section{The head up display\index{head up display}}
At current, you have two options for reading off the main flight parameters of the plane:
The \Index{HUD} (\textbf{H}ead \textbf{U}p \textbf{D}isplay \index{head up display} and
the panel. Neither are \Index{HUD}s used in usual general aviation planes nor in civilian
ones. Rather they belong to the equipment of modern military jets. However, in view of
the fact that the \Index{panel} despite recent progress is not yet complete the
\Index{HUD} may well serve as a main instrument for controlling the plane. Besides, it
might be easier to fly using this one than exploiting the \Index{panel} and several of
the real pilots might prefer it because of combining the readouts of critical parameters
with an outside view onto the real world. (Several \Index{Cessna} pilots might love to
have one, but technology is simply too expensive for implementing HUDs in general
aviation aircrafts.)
\medskip
\centerline{
\includegraphics[clip,width=12.5cm]{hud.eps}
}
\smallskip
\noindent
Fig.\,3: \textit{The HUD, or head up display.}
\medskip
The \Index{HUD} shown in Fig.\,3 displays all main flight parameters of the plane. In
the center you find the \Index{pitch indicator} (in degrees) with the \Index{aileron
indicator} above and the \Index{rudder indicator} below. A corresponding scale for the
elevation\index{elevation indicator} can be found to the left of the pitch scale. On the
bottom there is a simple \Index{turn indicator}.
There are two scales at the extreme left: The inner one displays the \Index{speed} (in
kts) while the outer one indicates position of the \Index{throttle}. You may recall the
\Index{Navion} taking off at a speed of 100 kts. The two scales on the extreme r.h.s
display your \Index{height}, i.\,e. the left one shows the height above ground while the
right of it gives that above zero, both being displayed in feet.
Besides this, the \Index{HUD} displays some additions information. On the upper right you
find date and time. Below, you see \Index{latitude} and \Index{longitude} of your current
position on the l.h.s and r.h.s, resp. In the lower left corner there is a number
indicating the \Index{frame rate}, i.e. the number of times the picture being re-drawn
each second.
You can change color of the \textbf{HUD} using the ''H'' key. Pressing it several times
minimizes the HUD.
\section{The Panel\index{panel}}
Besides the \Index{HUD}, \FlightGear has a \Index{panel} which can be activated by
pressing the ''P'' key. (It is recommended disabling the HUD then by pressing ''H''
several times.) While the panel is not yet fully complete the basic five \Index{flight
instruments} to scan are present and working.
\medskip
\centerline{
\includegraphics[clip,width=12.5cm]{panel.eps}
}
\smallskip
\noindent
Fig.\,4: \textit{The panel.}
\medskip
In the center you find the \Index{artificial horizon} (attitude indicator) displaying
pitch and bank of your plane. It has pitch marks (hard to be seen in this version) as
well as bank marks at 10, 20, 30, 60, and 90 degrees.
Left to the artificial horizon, you'll see the \Index{airspeed indicator}. Not only does
it have a speed indication in knots (recall: The Navion takes off at 100 kts) but also
several arcs showing characteristic \Index{velocity rages} you have to consider. At
first, there is a green arc indicating the normal operating range of speed with the flaps
(net yet being implemented in \FlightGear) fully retracted. The white arc indicates the
range of speed with flaps in action. The tiny yellow arc shows a range, which should only
be used in smooth air. The upper end of it has a red radial indicating the speed never to
be exceeded.
Below the airspeed indicator you can find the \Index{turn indicator}. The airplane in the
middle indicates the roll of your plane. If the left or right wing of the plane is
aligned with one of the marks this indicates a standard turn, in which you make a full
360 degrees turn in exactly two minutes.
Below the plane, still in the turn indicator, is another instrument, called
\Index{inclinometer}. It indicates if \Index{rudder} and \Index{ailerons} are
coordinated. During turns, you always have to operate aileron and rudder in such a way
that the ball in the tube remains centered; otherwise the plane is skidding.
To the right of the artificial horizon you find the \Index{altimeter} showing the height
above sea level (not ground!). At present it is not yet working in
\FlightGear\hspace{-1mm}. Below the altimeter is the \Index{vertical speed indicator}
which, on the other hand, is operational. It indicates the rate of climbing or sinking of
your plane in hundreds of feet per minute.
There is one more instrument working in the panel, i.e. the second one in the column on
the r.h.s. indicating position of \Index{throttle}.
This completes description of the present main \FlightGear instruments. If you are
looking for some interesting places to discover with \FlightGear (which may or may not
require downloading additional scenery) you may want to check
\web{http://www.flightgear.org/Downloads/Places}.
There is now a menu entry for entering directly the \Index{airport code} of the airport
you want to start from.
Finally, if you're done and are about to leave the plane, just hit the ESC key or use the
corresponding menu entry to exit the program.
%% Revision 0.00 1998/09/08 michael
%% Initial revision for version 0.53.
%% Revision 0.01 1998/09/20 michael
%% several extensions and corrections, added Fig.1.
%% revision 0.10 1998/10/01 michael
%% final proofreading for release
%% revision 0.11 1998/11/01 michael
%% Complete revision of keyborad controls, interesting places
%% revision 0.12 1999/03/07 michael
%% Corrected rudder key
%% revision 0.20 1999/06/04 michael
%% HUD completely rewritten, added panel section with picture, and menu section
%% updated keystrokes

View file

@ -1,456 +0,0 @@
%%
%% getstart.tex -- Flight Gear documentation: Installation and Getting Started
%% Chapter file
%%
%% Written by Michael Basler, started September 1998.
%%
%% Copyright (C) 1999 Michael Basler (pmb@knUUt.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: getstart.tex,v 0.20 1999/06/04 michael
%% (Log is kept at end of this file)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{Want to have a free flight? Take {\FlightGear}!\label{free}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Yet another Flight Simulator?}
\markboth{\thechapter.\hspace*{1mm} WANT TO HAVE A FREE
FLIGHT?}{\thesection\hspace*{1mm} YET ANOTHER FLIGHT SIMULATOR?}
Did you ever want to fly a plane yourself, but lacked the money or
skills to do so? Do you belong to those real pilots, who want to
improve their skills without having to take off? Do you want to
try some dangerous maneuvers without risking your life? Or do you
just want to have fun with a more serious game not killing any
people? If any of these questions applies, PC flight simulators
are just for you.
If you are reading this you might have got already some experience either using
\Index{Microsoft}'s {\copyright} \Index{FS98}, \Index{Looking Glass}' {\copyright}
\Index{Flight Unlimited II} or any other of the commercially available PC flight
simulators. As the price tag of those is usually within the 50\$ range buying one of them
should not be a serious problem given the fact, that running any serious PC flight
simulator requires a hardware within the 1500\$ range, despite dropping prices, at least.
Why then that effort of spending hundreds or thousands of hours of
programming to build a free simulator? Obviously there must be
good reason to do so:
\begin{itemize}
\item All of the commercial programs have a serious drawback: They are made
by a small group of developers defining their properties - often
quite inert and not listening too much to the customer.
Anyone ever trying to contact \Index{Microsoft} will
immediately agree.
\item Commercial PC flight simulators usually try to cover a market
segment as broad as possible. For obvious reason, most of them want
to serve the serious pilot as well as the beginner and the gamer.
The result are compromises. As \FlightGear is free, there is no need
for such compromises; it just can be given the properties its users
want. It defines itself via building.
\item Building a flight simulator is a challenge to the art of
programming. Contributing to that project makes you belong to
those being able to contribute to serious, ambitious and
advanced software projects.
\item It is fun. Not only is it fun to write the code (\ldots or
documentation\ldots) but also to belong to that -- temporarily changing
-- club of clever people on the net having discussed, struggled and finally
succeeded in creating that project. Even reading the \FlightGear
mailing lists is informative and fun for itself.
\end{itemize}
The above-mentioned points make \FlightGear different from its competitors in several
respect. \FlightGear aims to be a civilian,\index{Flight simulator!civilian}
multi-platform,\index{Flight simulator!multi-platform} open,\index{Flight simulator!open}
user-supported,\index{Flight simulator!user-sported} user-extensible\index{Flight
simulator!user-extensible} simulator.
\begin{itemize}
\item \textbf{Civilian:}\index{Flight simulator!civilian} The
project is primarily aimed to civilian flight simulation.
It should be appropriate for simulating
general aviation as well as civilian aircraft. However, according to
the open concept of development that sure does not exclude someone
taking the code and integrating \Index{military components}.
\item\textbf{Multi-platform:}\index{Flight simulator!multi-platform} The
developers are attempting to keep the code as platform-independent
as possible. This is based on their observation that
people interested in flight simulations run quite
a variety of computer hardware and operating systems. The present code
supports the following \Index{Operating Systems}:
\begin{itemize}
\item\Index{Linux} (any platform),
\item\Index{Windows NT} (i86 platform),
\item\Index{Windows 98(95)},
\item\Index{BSD UNIX},
\item\Index{SGI IRIX},
\item\Index{SunOS},
\item{MacIntosh (experimental).}
\end{itemize}
There is no known flight simulator, neither commercially nor free, supporting such a
broad range of platforms.
\item\textbf{Open:}\index{Flight simulator!open} The project is not
restricted to a closed club of developers. Anyone who feels he or she
being able to contribute is highly welcome.
The code (including documentation) is copyrighted under the
terms of the \Index{Gnu Public License}.
The Gnu Public License is often misunderstood. In simple terms it
states that you can copy and freely distribute the program(s) licensed
to it. You can modify them, if you like. You are even allowed to charge
as much money for the distribution of the modified or original program as you want.
However, you must distribute it complete with the entire source code
and it must retain the original copyrights. In short:
\medskip
\centerline{\textit{''You can do anything with the software except
making it non-free''}.}
The full text of the \Index{Gnu Public License} can be obtained from
\web{http://www.gnu.org/copyleft/gpl.html}.
\item\textbf{User-supported, user-extensible:}\index{Flight simulator!user-supported}
\index{Flight simulator!user-extensible} Contrary to various
commercial simulators available, scenery and aircraft format,
internal variables, etc. are user accessible and documented
from the beginning. Even without an explicit developmental \Index{documentation},
which sure has to be written at some point, this is guaranteed by supplying the
\Index{source code}. It is the goal of the developers to build a basic
engine to which scenery designers, panel engineers, maybe adventure
or ATC routine writers, sound capturers and others can (and are asked to)
add. It is our hope, that the project will finally gain from the creativeness
and ideas of the hundreds of talented simmers across the world.
\end{itemize}
Without doubt, the success of the \Index{Linux} project initiated by Linus
Torvalds\index{Torvalds, Linus} inspired several of the developers.
Not only has it shown that distributed development of even highly sophisticated
software projects over the Internet is possible. It led to a product which,
in several respect, is better than its commercial competitors.
\section{A short \Index{history} of \FlightGear}
This project goes back to a discussion of a group of net-citizens in 1996 resulting in a
proposal written by David Murr\index{Murr, David} who, unfortunately, dropped out from
the project (as well as the net) later. The original \Index{proposal} is still available
from the \FlightGear web site and can be found under
\web{http://www.flightgear.org/proposal-3.0.1}
Although the names of the people and several of the details
naturally changed in time, the spirit of that proposal was clearly
retained up to the present status of the project.
Actual coding started in summer 1996 and by the end of that year essential graphics
routines were completed. At that time, programming was mainly done and coordinated by
Eric Korpela\index{Korpela, Eric} from Berkeley University
(\mail{korpela@ssl.Berkeley.EDU}). Early code was running under \Index{Linux} as well as
under \Index{DOS}, \Index{OS/2}, \Index{Windows 95/NT}, and \Index{Sun-OS}. This was
quite an ambitious project, as it involved, among others, writing all the \Index{graphics
routines} in a system-independent way just from scratch.
Development slowed down and finally stopped at the beginning of 1997 when Eric had to
complete his thesis. At this point, the project seemed to be dead and traffic on the
mailing list went down to nearly nothing.
It was Curt Olson\index{Olson, Curt} from the University of Minnesota
(\mail{curt@flightgear.org}) who re-started the project in the middle of 1997. His idea
was as simple as successful: Why invent the wheel a second time? There have been several
free flight simulators\index{Flight simulator!free} available running on
\Index{workstation}s under different flavors of \Index{UNIX}. One of these,
\Index{LaRCsim}, having been developed by Bruce Jackson\index{Jackson, Bruce} from NASA
(\mail{jackson@larc.nasa.gov}) seemed to be well-adapted for the present approach. Curt
took this one apart and re-wrote several of the routines in a way making them build-able
as well as run-able on the intended target platforms. The key idea in doing so was
selecting a system-independent graphics platform, i.\,e. \Index{OpenGL}, for the basic
\Index{graphics routines}.
\medskip
\centerline{
\includegraphics[clip,width=12.5cm]{navion.eps}
}
\smallskip
\noindent
Fig.\,1: \textit{The \Index{Navion} flight model is one of the features \FlightGear
inherited from \Index{LaRCsim}. Until now it is the only one plane being fully realized
in \FlightGear\hspace{-1mm}.}
\medskip
In addition, a clever decision on the selection of the basic \Index{scenery} data was
already made in this very first version. \FlightGear Scenery is created based on
satellite data published by the \Index{U.\,S. Geological Survey}. These terrain data are
available for the whole world over the Internet for free from
\web{http://edcwww.cr.usgs.gov/doc/edchome/ndcdb/ndcdb.html}
\noindent
for the US resp.
\web{http://edcwww.cr.usgs.gov/landdaac/gtopo30/gtopo30.html}
\noindent
for other countries. Those freely accessible scenery data in
conjunction with scenery building tools provided with
\FlightGear are an important prerequisite enabling anyone to
create his or her own scenery, at least in principle.
This new \FlightGear code - still largely being based on original \Index{LaRCsim} code -
was released in July 1997. From that moment the project gained momentum again. Here are
some milestones from the more recent history of development:
\begin{itemize}
\item Sun, moon and stars are a field where PC flight simulators
have been notoriously weak for ages. It is one of the great
achievements of \FlightGear that it includes accurate sun (watch, Microsoft!),
moon, and planets, being moreover placed on their proper positions.
The corresponding \Index{astronomy code} was implemented in fall 1997 by Durk
Talsma\index{Talsma, Durk}
(\href{mailto:pn_talsma@macmail.psy.uva.nl}{pn\_talsma@macmail.psy.uva.nl}).
\item Texture support\index{textures} was added by Curt
Olson\index{Olson, Curt}
(\mail{curt@flightgear.org}) in spring 1998. This marked a
significant improvement in terms of reality. You may recall: MSFS had
untextured scenery up to version 4.0. For this purpose, some high-quality
textures were submitted by Eric Mitchell\index{Mitchell, Eric}
(\href{mailto:mitchell@mars.ark.com}{mitchell@mars. ark.com}.
\item A \Index{HUD} (\Index{head up display}) was added based on code
provided by Michele America\index{America, Michele}
(\mail{nomimarketing@mail.telepac.pt}) and
Charlie Hotch\-kiss\index{Hotchkiss, Charlie}
(\href{mailto:chotchkiss@namg.us.anritsu.com}{chotch kiss@namg.us.anritsu.com})
in fall 1997 and continuously improved later, mainly by Norman Vine
(\mail{nhv@laserplot.com}).
While being probably not a substitute for a \Index{panel} and moreover
possibly being a bit odd in that tiny \Index{Navion}, this \Index{HUD} has proven
extremely useful in navigation until now.
\item After improving scenery\index{scenery} and
texture\index{textures} support and adding some more
features there was a disappointing side-effect in spring 1998: Frame
rates\index{frame rate} dropped down to a point where \FlightGear became inflyable. There
were two main achievements overcoming this problem. First, with the advent
of hardware \Index{OpenGL} support and corresponding drivers for most of
the graphics cards these features could be exploited in
\FlightGear as well, leading to a \Index{frame rate} boost by a
factor up to 10. Second, Curt Olson\index{Olson, Curt} (\mail{curt@flightgear.org})
implemented so-called \Index{view frustrum culling} (a procedure to except part of
the scenery not required from rendering) which gave another 20\% or so of
frame rate boost in May 1998.
With these two achievements \FlightGear became flyable again even on weaker
machines as long as they included a 3D graphics board with
hardware \Index{OpenGL} support. With respect to this point one should keep in mind that code
at present is in no way optimized leaving a lot of room for further
improvements of frame rate.
\item A rudimentary \Index{autopilot} implementing heading hold was
contributed by Jeff Goeke-Smith\index{Goeke-Smith, Jeff} (\mail{jgoeke@voyager.net}) in
April 1998. The autopilot was improved, included adding an altitude hold and a terrain
follow switch, in October 1998.
\item The basics for selectable \Index{menu}s were laid based on Steve Baker's\index{Baker, Steve}
(\mail{sjbaker@ hti.com}) portable library \Index{PLIB} in June 1998. After having been idle for a
long time, first working menu entries came to life in spring 1999.
\item Friedemann Reinhard \index{Reinhard, Friedemann}
(\mail{mpt218@faupt212.physik.uni-erlangen.de})
developed early \Index{panel code}, including a working \Index{airspeed
indicator}, which was added in June 1998 and has been considerably improved until today.
\item There was basic \Index{audio support}, i.\,e. an audio library and some basic background engine sound, contributed by Steve
Baker (\mail{sjbaker@hti.com})\index{Baker, Steve} in Summer 1998. Today, the audio
library is part of Steves's above-mentioned portable library \Index{PLIB}. This same
library was extended to support joystick /yoke/rudder later which brought \FlightGear
joystick support in October 1989, again marking a huge improvement in terms of realism.
\item In September 1998 Curt Olson\index{Olson, Curt}
(\mail{curt@flightgear.org}) succeeded in creating first complete terrain Scenery for the
USA, which is available for download from
\web{ftp://ftp.kingmont.com/pub/kingmont/}
Scenery was further improved by Curt via adding features like lakes, rivers, coastlines
and the like in spring 1999.
\item In June 1999 there was a split of the source tree into a stable and a developmental
branch. Even version numbers as 0.6, 0.8, and (hopefully) 1.0 refer to stable versions
being intended for general use while odd versions as 0.7 and so on refer to developmental
versions. Policy is to do only bug fixes in the even versions, while new features are
generally added to odd-numbered versions, which finally after things stabilized will turn
into the next stable version by adding 0.1. At present (and probably in the future), this
guide refers to the stable branch. \label{branches}
\end{itemize}
\longpage
This is by no way a complete history and a lot of people making even important
contributions were left out here. Besides the named achievements being more on the
surface there was a lot of work done concerning the internal structure, by Steve
Baker\index{Baker, Steve} (\mail{sjbaker@hti.com})\index{Baker, Steve}, Norman
Vine\index{Vine, Norman} (\mail{nhv@laserplot.com}), Gary R. Van Sickle\index{Van Sickle,
Gary, R.} (\mail{tiberius@braemarinc.com}), and others. A more complete list of
contributors to the project can be found in \textit{Landing: Some further thoughts before
leaving the plane}, Chapter \ref{landing}, as well as in the file \texttt{Thanks}
provided with the code. Moreover, the \Index{\FlightGear Website} contains a detailed
history of all of the development under
\web{http://www.flightgear.org/News/}
\section{System requirements}\index{system requirements}
Compared to other recent flight simulators the system requirements
for \FlightGear are rather decent. A P100 is already sufficient,
given you have a proper 3D graphics card, but of course for
getting good performance we recommend a P200 or better, if you run
it on a PC. On the other hand, any not too ancient \Index{UNIX}
\Index{workstation} will run \FlightGear as well.
While in principle you can run \FlightGear on 3D boards without OpenGL support or even on
systems without 3D graphics hardware at all, missing hardware OpenGL support can force
even the fastest PIII to its knees (\Index{frame rate}s typically below 1 fps). Any cheap
3D graphics card will do as long as it features hardware \Index{OpenGL} support. For
\Index{Windows 98/NT} drivers, you may contact the home page of the manufacturer.
Moreover, you should have in mind that several OpenGL drivers\index{OpenGL!drivers} are
still marked as beta and moreover, and sometimes these drivers are provided by the makers
of the graphics chip instead of the makers of the board. More detail on OpenGL drivers
can be found under
\web{http://www.x-plane.com/v4ibm.html}
\noindent
as well as under
\web{http://www.flightgear.org/Hardware}.
Next, you need around 16MB of free disk space for installing the executable including
basic scenery. In case you want to compile the program yourself you need around 50MB for
the source code and for temporary files created during compilation, independent of the
operating system.
If you want to hear the \Index{sound effects} any decent \Index{sound card} should serve.
Besides, \FlightGear supports a \Index{joystick} or \Index{yoke} as well as \Index{rudder
pedals} under \Index{Linux} as well as under \Index{Windows}.
With respect to operating systems, \FlightGear is being primarily developed under
\Index{Linux}, a free UNIX clone developed cooperatively over the net in much the same
way as the \FlightGear project itself. Moreover, \FlightGear runs under \Index{Windows
95}, \Index{Windows 98} and \Index{Windows NT} and given you have a proper
\Index{compiler} installed can be build under all of these platforms as well. The primary
compiler for all platforms is the free \Index{GNU C++} (i.\,e. the \Index{Cygnus}
compiler under Win32), however there is some support for \Index{MSVC} as well. Moreover,
\FlightGear runs and can be build on several \Index{UNIX}/X11 platforms with GNU C++
installed.
\section{Whom this guide is addressed to and how it is organized}
At first: There is not much of the material in this Guide being originally invented by
ourself. You could even say with Montaigne that we ''merely gathered here a big bunch of
other men's flowers, having furnished nothing of my own but the strip to hold them
together''. Most (but fortunately not all) of the information can as well be grabbed from
the \Index{\FlightGear home page} being situated at
\web{http://www.flightgear.org/}
\noindent
and its various sub pages. However, there still seems to
be a small group of people preferring neatly printed manuals over
loosely scattered Readmes and those may acknowledge our effort.
This \textit{Installation and Getting Started} is intended as being a first step towards
a more complete \Index{\FlightGear documentation} (with the other parts, supposedly, to
be written by others). Its main addressee is the end-user who is not interested in the
internal workings of \Index{OpenGL} or in building his or her own scenery, for instance.
It is our hope, that sometime there will be an accompanying \textit{\Index{\FlightGear
Programmer's Guide}}, which could be based on some of the documentation under
\web{http://www.flightgear.org/Docs},
\noindent
a \textit{\Index{\FlightGear Scenery Design Guide}}, and a
\textit{\Index{\FlightGear Flight School}}, at least.
This \textit{Installation and Getting Started} is organized as
follows:
The first Chapter \ref{opengl}, \textit{Getting the engine: Installing OpenGL graphics
drivers}, describes how to prepare the computer for handling \FlightGear's graphics
routines. \FlightGear is based on a graphics library called OpenGL, thus you must install
either hardware or software OpenGL support for your graphics board (except, you did so
before).
Chapter \ref{building}, \textit{Building the plane: Compiling the program}, explains how
to build, i.\,e. compile the simulator. Depending on your platform this may or may not be
required for you. There will at least be binaries available for those working on a Win32
(i.\,e. Windows 98 {\copyright} or Windows NT {\copyright}) platform. For those on such
systems, who want to take off immediately without going through the potentially
troublesome process of compiling, we recommend just skipping that Chapter and going
directly to the next one.
In Chapter \ref{prefligh}, \textit{Preflight: Installing \FlightGear}, you find
instructions for installing the binaries in case you did not so by building them in the
previous Chapter. Moreover, you'll have to install scenery and texture files, which will
be described there, too.
The following Chapter \ref{takeoff}, \textit{Takeoff: How to start the program},
describes how to start the program including an overview on the command line options.
Chapter \ref{flight}, \textit{Flight: All about instruments, keystrokes and menus},
describes how to operate the program, i.\,e. to actually fly with
\FlightGear\hspace{-1mm}. This includes a (hopefully) complete list of key strokes, an
overview on the menu entries, as well as a detailed description of the HUD (head up
display) and the panel.
In Chapter \ref{landing}, \textit{Landing: Some further thoughts before leaving the
plane}, we would like to give credits to those who did the hard work, and give an outlook
on what remains to be done.
Finally: \textbf{We kindly ask others to help us improving this document by submitting
corrections, improvements, and more. Notably, we invite others to contribute descriptions
referring to alternative setups (graphics cards, operating systems, and compilers etc.).
We will be more than happy to include those into forthcoming versions of this
\textit{Installation and Getting Started} (of course not without giving credit to the
authors).}
We hope to continuously maintain this document at least for a foreseeable future, but
probably will not be able to produce a new one for any single release of {\FlightGear}.
While we are both watching the mailing lists, it might help, if developers adding new
functionality could send us a short note.
%% Revision 0.00 1998/09/08 michael
%% Initial revision for version 0.53.
%% Revision 0.01 1998/09/20 michael
%% several extensions and corrections
%% revision 0.10 1998/10/01 michael
%% final proofreading for release
%% revision 0.11 1998/11/01 michael
%% minor corrections on platforms, satellite data, OpenGL (S. Baker)
%% added Navion pic
%% revision 0.12 1999/03/07 michael
%% update on recent development
%% revision 0.20 1999/06/04 michael
%% updates on recent development, corrections of links

View file

@ -1,83 +0,0 @@
%%
%% getstart.tex -- Flight Gear documentation: Installation and Getting Started
%% Master file
%%
%% Written by Michael Basler % Bernhard Buckel, starting September 1998.
%%
%% Copyright (C) 1999 Michael Basler (pmb@knUUt.de)
%% & Bernhard Buckel (buckel@wmad95.mathematik.uni-wuerzburg.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: getstart.tex,v 0.20 1999/06/04 michael
%% (Log is kept at end of this file)
\documentclass[11pt,openany]{book}
\usepackage{makeidx}
\usepackage[dvips]{graphicx}
\usepackage{times}
\usepackage{hyperref}
\newcommand{\Index}[1]{#1\index{#1}}
\newcommand{\FlightGear}{{\itshape FlightGear }}
\newcommand{\web}[1]{\href{#1}{#1}}
\newcommand{\mail}[1]{\href{mailto:#1}{#1}}
\newcommand{\longpage}{\enlargethispage{\baselineskip}}
\newcommand{\shortpage}{\enlargethispage{-\baselineskip}}
\makeindex
\begin{document}
\include{title}
\include{free}
\include{opengl}
\include{building}
\include{prefligh}
\include{takeoff}
\include{flight}
\include{landing}
\include{missed}
\include{index}
\end{document}
%% Revision 0.00 1998/09/08 michael
%% Initial revision for version 0.53.
%% incl. Linux stuff from b buckel
%% Revision 0.01 1998/09/20 michael
%% several extensions and corrections, added Fig.1.
%% Revision 0.02 1998/09/29 michael
%% added Chapter takeoff from b buckel
%% revision 0.10 1998/10/01 michael
%% added Chapter missed approach from b buckel
%% inclusion file splitting
%% final proofreading for release
%% revision 0.11 1998/11/01 michael
%% corrected ~, _ ind URLs
%% revision 0.12 1999/03/07 michael
%% changed Font to Times in print version
%% dropped .ps file
%% working URLs in .html version
%% corrected misspellings
%% revision 0.20 1999/06/04 michael
%% updated for fgfs 0.6
%% added sections on menu and panel
%% smaller and updated pix for faster download
%% revision 0.21 1999/06/30 michael
%% Linux update by Bernhard

File diff suppressed because it is too large Load diff

View file

@ -1,37 +0,0 @@
%%
%% getstart.tex -- Flight Gear documentation: Installation and Getting Started
%% Chapter file
%%
%% Written by Michael Basler, started September 1998.
%%
%% Copyright (C) 1999 Michael Basler (pmb@knUUt.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: getstart.tex,v 0.20 1999/06/04 michael
%% (Log is kept at end of this file)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\eject
\addcontentsline{toc}{chapter}{\protect Index}
{\footnotesize
\printindex
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Revision 0.00 1998/09/08 michael
%% Initial revision for version 0.53.

View file

@ -1,390 +0,0 @@
%%
%% getstart.tex -- Flight Gear documentation: Installation and Getting Started
%% Chapter file
%%
%% Written by Michael Basler, started September 1998.
%%
%% Copyright (C) 1999 Michael Basler (pmb@knUUt.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: getstart.tex,v 0.20 1999/06/04 michael
%% (Log is kept at end of this file)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{Landing: Some further thoughts before leaving the plane\label{landing}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\markboth{\thechapter.\hspace*{1mm}
LANDING}{\thesection\hspace*{1mm} THOSE, WHO DID THE WORK}
\section{Those, who did the work}
Did you enjoy the flight? In case you did, don't forget those who devoted hundreds of
hours to that project. All of this work is done on a voluntary basis within spare time,
thus bare with the \Index{programmers} in case something does not work the way you want
it to. Instead, sit down and write them a kind (!) letter proposing what to change.
Alternatively, you can subscribe to the \FlightGear \Index{mailing lists} and contribute
your thoughts there. Instructions to do so can be found under
\web{http://www.flightgear.org/mail.html}.
Essentially there are two lists, one of which being mainly for the developers and the
other one for end users.
\medskip
\noindent
These are the people who did the job (This information was
essentially taken from the file \texttt{Thanks} accompanying the
code):
\medskip
\noindent Raul Alonzo\index{Alonzo, Raul} (\mail{amil@las.es})\\ Author of Ssystem and
moon texture.
\medskip
\noindent Michele America\index{America, Michele}
(\mail{nomimarketing@mail.telepac.pt})\\
Contributed to the \Index{HUD} code.
\medskip
\noindent Steve Baker\index{Baker, Steve} (\mail{sjbaker@hti.com})\\
Author of \Index{PLIB}, a graphics/audio/joystick interface written entirely on top of
\Index{OpenGL}/\-\Index{GLUT} used in \FlightGear. An immense amount of coaching and tutelage,
both on the subjects of flight simulation and \Index{OpenGL}. It has been
his comments and thoughts that have prompted the implementation of
most of the more sophisticated features of \FlightGear{\hspace{-2mm}}.
\medskip
\noindent Michael Basler\index{Basler, Michael} (\mail{pmb@knUUt.de})\\
Coauthor of Installation and Getting Started (together with Bernhard
Buckel).
\medskip
\noindent John S. Berndt\index{Berndt, John, S.} (\mail{jsb@hal-pc.org})\\
Working on a complete C++rewrite/reimplimentation of the core FDM.
Initially he is using X15 data to test his code, but once things are
all in place we should be able to simulator arbitrary aircraft.
\medskip
\noindent Paul Bleisch\index{Bleisch, Paul} (\mail{pbleisch@acm.org})\\
Redid the debug system so that it would be much more
flexible, so it could be easily disabled for production system, and
so that messages for certain subsystems could be selectively
enabled.
Also contributed a first stab at a config file/command line parsing
system.
\medskip
\noindent Jim Brennan\index{Brennan, Jim} (\mail{jjb@foothill.net})\\
Provided a big chunk of online space to store USA scenery for Flight Gear.
\medskip
\noindent Bernie Bright\index{Bright, Bernie} (\mail{bbright@c031.aone.net.au})\\
Many C++ style, usage, and implementation improvements, STL
portability and much, much more.
\medskip
\noindent Bernhard H. Buckel\index{Buckel, Bernhard H.}
(\mail{buckel@wmad95.mathematik.uni-wuerzburg.de})\\
Contributed the README.Linux. Coauthor of Installation
and Getting Started (together with Michael Basler).
\medskip
\noindent Gene Buckle\index{Buckle, Gene} (\mail{geneb@nwlink.com})\\
A lot of work getting \FlightGear to compile with the \Index{MSVC}++
compiler. Numerous hints on detailed improvements.
\medskip
\noindent Oliver Delise \index{Delise, Oliver} (\mail{delise@rp-plus.de})\\
FAQ Maintainer.
\medskip
\noindent Didier Chauveau\index{Chauveau, Didier} (\mail{chauveau@math.univ-mlv.fr})\\
Provided some initial code to parse the 30 arcsec DEM files found at:
\web{http://edcwww.cr.usgs.gov/landdaac/gtopo30/gtopo30.html}.
\medskip
\noindent Jean-Francois Doue\index{Doue, Jean-Francois}\\
Vector 2D, 3D, 4D and Matrix 3D and 4D inlined C++ classes. (Based on
Graphics Gems IV ed. Paul S. Heckbert)
\href{http://www.animats.com/simpleppp/ftp/public_html/topics/developers.html}{http://www.animats.com/simpleppp/ftp/public\_html/topics/developers.html}.
\medskip
\noindent Francine Evans\index{Evans, Francine} (\mail{evans@cs.sunysb.edu})
\href{http://www.cs.sunysb.edu/~evans/stripe.html}{http://www.cs.sunysb.edu/\~{}evans/stripe.html}
\noindent
Wrote the GPL'd tri-striper.
\medskip
\noindent Oscar Everitt\index{Everitt, Oscar} (\mail{bigoc@premier.net})\\
Created single engine piston engine sounds as part of an F4U package
for \Index{FS98}. They are pretty cool and Oscar was happy to contribute
them to our little project.
\medskip
\noindent Jean-loup Gailly\index{Gailly, Jean-loup} and Mark Adler\index{Adler, Mark}
(\mail{zlib@quest.jpl.nasa.gov})\\
Authors of the \Index{zlib library}. Used for on-the-fly compression and
decompression routines,
\web{http://www.cdrom.com/pub/infozip/zlib/}.
\medskip
\noindent Thomas Gellekum\index{Gellekum, Thomas} (\mail{tg@ihf.rwth-aachen.de})\\
Changes and updates for compiling on \Index{FreeBSD}.
\medskip
\noindent Jeff Goeke-Smith\index{Goeke-Smith, Jeff} (\mail{jgoeke@voyager.net})\\
Contributed our first \Index{autopilot} (Heading Hold).
Better autoconf check for external timezone/daylight variables.
\medskip
\noindent Michael I. Gold\index{Gold, Michael, I.} (\mail{gold@puck.asd.sgi.com})\\
Patiently answered questions on \Index{OpenGL}.
\medskip
\noindent Charlie Hotchkiss\index{Hotchkiss, Charlie}
(\mail{chotchkiss@namg.us.anritsu.com})\\ Worked on improving and enhancing the
\Index{HUD} code. Lots of code style tips and code tweaks\ldots
\medskip
\noindent Bruce Jackson\index{Jackson, Bruce} (NASA) (\mail{e.b.jackson@larc.nasa.gov})
\web{http://agcbwww.larc.nasa.gov/People/ebj.html}
\noindent
Developed the \Index{LaRCsim} code under funding by NASA which we use to provide the
flight model. Bruce has patiently answered many, many questions.
\medskip
\noindent Tom Knienieder\index{Knienieder, Tom} (\mail{knienieder@ms.netwing.at})\\
Ported Steve Bakers's audio library\index{audio library} to Win32.
\medskip
\noindent Reto Koradi\index{Koradi, Reto} (\mail{kor@mol.biol.ethz.ch})
\href{\web{http://www.mol.biol.ethz.ch/~kor}}{\web{http://www.mol.biol.ethz.ch/\~{}kor}}
\noindent
Helped with setting up \Index{fog effects}.
\medskip
\noindent Bob Kuehne\index{Kuehne, Bob} (\mail{rpk@sgi.com})\\
Redid the Makefile system so it is simpler and more robust.
\medskip
\noindent Vasily Lewis\index{Lewis, Vasily} (\mail{vlewis@woodsoup.org})
\web{http://www.woodsoup.org}
\noindent
Provided computing resources and services so that the Flight Gear
project could have real home. This includes web services, ftp
services, shell accounts, email lists, dns services, etc.
\medskip
\noindent Christian Mayer\index{Mayer, Christian} (\mail{Vader@t-online.de})\\
Working on multi-lingual conversion tools for fgfs.\\
Contributed code to read msfs scenery textures.
\medskip
\noindent Eric Mitchell\index{Mitchell, Eric} (\mail{mitchell@mars.ark.com})\\
Contributed some topnotch scenery \Index{textures}.
\medskip
\noindent Anders Morken\index{Morken, Anders} (\mail{amrken@online.no})\\
Maintains the European mirror of the \FlightGear web pages.
\medskip
\noindent Alan Murta\index{Murta, Alan} (\mail{amurta@cs.man.ac.uk})
\web{http://www.cs.man.ac.uk/aig/staff/alan/software/}
\noindent
Created the Generic Polygon Clipping library.
\medskip
\noindent Curt Olson\index{Olson, Curt} (\mail{curt@flightgear.org})\\
Primary organization of the project. First implementation
and modifications based on \Index{LaRCsim}. Besides putting together all
the pieces provided by others mainly concentrating on the \Index{scenery
engine} as well as the graphics stuff.
\medskip
\noindent Robin Peel\index{Peel, Robin} (\mail{robinp@mindspring.com})\\
Maintains worldwide airport and runway database for \FlightGear as we as X-Plane.
\medskip
\noindent Friedemann Reinhard\index{Reinhard, Friedemann}
(\mail{mpt218@faupt212.physik.uni-erlangen.de})\\
Development of textured instrument \Index{panel}.
\medskip
\noindent Petter Reinholdtsen\index{Reinholdtsen, Petter} (\mail{pere@games.no})\\
Incorporated the Gnu automake/autoconf system (with libtool).
This should streamline and standardize the build process for all
UNIX-like platforms. It should have little effect on IDE type
environments since they don't use the UNIX make system.
\medskip
\noindent William Riley\index{Riley, William} (\mail{riley@technologist.com})\\
Contributed code to add ''brakes''.
\medskip
\noindent Paul Schlyter\index{Schlyter, Paul} (\mail{pausch@saaf.se})\\
Provided Durk Talsma with all the information he needed to write the astro code.
\medskip
\noindent Chris Schoeneman\index{Schoenemann, Chris} (\mail{crs@millpond.engr.sgi.com})\\
Contributed ideas on audio support.
\medskip
\noindent Jonathan R Shewchuk\index{Shewchuk, Jonathan}
(\mail{Jonathan\_R\_Shewchuk@ux4.sp.cs.cmu.edu})\\
Author of the Triangle\index{triangle program} program. Triangle
is used to calculate the Delauney triangulation of our irregular terrain.
\medskip
\noindent Gordan Sikic\index{Sikic, Gordan} (\mail{gsikic@public.srce.hr})\\
Contributed a \Index{Cherokee flight model} for \Index{LaRCsim}. Currently is not
working and needs to be debugged. Use configure
\texttt{-$\!$-with-flight-model=cherokee}
to build the cherokee instead of the \Index{Navion}.
\medskip
\noindent Michael Smith\index{Smith, Michael} (\mail{msmith99@flash.net})\\
Contributed cockpit graphics, 3d models, logos, and other images.
Project Bonanza
\web{http://members.xoom.com/ConceptSim/index.html}.
\medskip
\noindent
\Index{U.\,S. Geological Survey}
\web{http://edcwww.cr.usgs.gov/doc/edchome/ndcdb/ndcdb.html}
\noindent
Provided geographic data used by this project.
\medskip
\noindent Durk Talsma\index{Talsma, Durk} (\mail{pn\_talsma@macmail.psy.uva.nl})\\
Accurate Sun, Moon, and Planets. Sun changes color based on
position in sky. Moon has correct phase and blends well into the
sky. Planets are correctly positioned and have proper magnitude. help with time
functions, GUI, and other things.
\medskip
\noindent Gary R. Van Sickle\index{van Sickle, Gary R.}
(\mail{tiberius@braemarinc.com})\\
Contributed some initial \Index{GameGLUT} support and other fixes.
\medskip
\noindent Norman Vine\index{Vine, Norman} (\mail{nhv@laserplot.com})\\
Many performance optimizations throughout the code. Many contributions
and much advice for the scenery generation section. Lots of Windows
related contributions. Improved \Index{HUD}.
\medskip
\noindent Roland Voegtli\index{Voegtli, Roland} (\mail{webmaster@sanw.unibe.ch})\\
Contributed great photorealistic textures.
\medskip
\noindent Carmelo Volpe\index{Volpe, Carmelo} (\mail{carmelo.volpe@csb.ki.se})\\
Porting \FlightGear to the \Index{Metro Works} development environment
(PC/Mac).
\medskip
\noindent Darrell Walisser\index{Walisser, Darrell} (\mail{dwaliss1@purdue.edu})\\
Contributed a large number of changes to porting \FlightGear to the Metro Works
development environment (PC/Mac). Finally produced the first MacIntosh port.
\medskip
\noindent Robert Allan Zeh\index{Zeh, Allan} (\mail{raz@cmg.FCNBD.COM})\\
Helped tremendously in figuring out the \Index{Cygnus} Win32 compiler and
how to link with .dll's. Without him the first run-able Win32
version of \FlightGear would have been impossible.
\section{What remains to be done}
At first: If you read (and, maybe, followed) this guide until this
point you may probably agree that \FlightGear\hspace{-2mm}, even
in its present state, is not at all for the birds. It is already a
flight simulator which has a flight model, a plane, terrain
scenery, texturing and simple controls.
Despite, \FlightGear needs -- and gets -- further development. Except internal tweakings,
there are several fields where \FlightGear needs basics improvement and development.
A first direction is adding \Index{airports}, streets, and more things bringing Scenery
to real life.
Second, the \Index{panel} needs further improvement including more working gauges.
Besides, there should be support for adding more \Index{planes} and for implementing
corresponding flight models differing from the \Index{Navion}.
Another task is further implementation of the \Index{menu system}, which should not be
too hard with the basics being working now.
A main stream of active development concerns weather. At present there is simply none: no
clouds, no rain, no wind. But there sure will be.
There are already people working in all of these directions. If you're a programmer and
think you can contribute, you are invited to do so.
\subsection*{Achnowledgements}
Obviously this document could not have been written without all
those contributors mentioned above making \FlightGear a reality.
Beyond this we would like to say special thanks to Curt
Olson,\index{Olson, Curt} whose numerous scattered Readmes,
Thanks, Webpages, and personal eMails were of special help to us
and were freely exploited in the making of this booklet.
Next, we gained a lot of help and support from Steve Baker \index{Baker, Steve} and
Norman Vine\index{Vine, Norman}. Moreover, we would like to thank Steve
Baker\index{Baker, Steve} for a careful reading and for numerous hints on the first draft
of this guide.
Further, we would like to thank Kai Troester\index{Troester, Kai} for donating the
solution of some of his compile problems to Chapter \ref{missed}.
%% Revision 0.00 1998/09/08 michael
%% Initial revision for version 0.53.
%% Revision 0.01 1998/09/20 michael
%% several extensions and corrections
%% revision 0.10 1998/10/01 michael
%% final proofreading for release
%% revision 0.11 1998/11/01 michael
%% corrections on audio library, getting started
%% revision 0.12 1999/03/07 michael
%% Updated Credits
%% revision 0.20 1999/06/04 michael
%% added O. Delise, Ch. Mayer, R. Peel, R. Voegtli, several updates

View file

@ -1,234 +0,0 @@
%%
%% getstart.tex -- Flight Gear documentation: Installation and Getting Started
%% Chapter file
%%
%% Written by Michael Basler % Bernhard Buckel, starting September 1998.
%%
%% Copyright (C) 1999 Michael Basler (pmb@knUUt.de)
%% & Bernhard Buckel (buckel@wmad95.mathematik.uni-wuerzburg.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: getstart.tex,v 0.20 1999/06/04 michael
%% (Log is kept at end of this file)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{Missed approach: If anything refuses to work\label{missed}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\markboth{\thechapter.\hspace*{1mm} MISSED APPROACH
}{\thesection\hspace*{1mm} ???}
We tried to sort \Index{problems} according to operating system to a certain extent , but
if you encounter a problem it may be a wise idea to look beyond ''your'' operating system
-- just in case. Besides, if anything fails, it is definitely a good idea to check
the FAQ maintained by Oliver Delise (\mail{delise@rp-plus.de}) being distributed
along with the source code.
\section{General problems}
\begin{itemize}
\item{\FlightGear runs SOOO slow}\\
If the \Index{HUD} indicates you are getting something like 1\,fps
(frame per second) or below you typically don't have working hardware
\Index{OpenGL} support. There may be several reasons for this. First,
there may be no OpenGL hardware drivers available for older
cards. In this case it is highly recommended to get a new board.
Second, check if your drivers are properly installed. Several
cards need additional OpenGL support drivers besides the
''native'' windows ones. For more detail check Chapter
\ref{opengl}.
Third, check if your hardware driver is called \texttt{opengl32.dll}
or just merely \texttt{opengl.dll}. By the default compilation, binaries are linked against
\texttt{open} \texttt{gl32.dll}. If you require the non-32 version,
consider rebuilding \FlightGear with the libraries \texttt{opengl32.dll},
\texttt{glut32.dll}, and \texttt{glu32.dll} replaced by their
non-32 counterparts. For more details check Chapter
\ref{building}.
If you installed the pre-compiled binaries \texttt{runfgfs.bat} invokes
\texttt{fgfs.exe} while \texttt{runfgfs.sgi.bat} invokes
\texttt{fgfs.sgi.exe} with the first ones being linked against the 32-versions.
Usually, hardware accelerated drivers use the 32-libraries.
\end{itemize}
\section{Potential problems under Linux}
Since we don't have access to all possible flavors of Linux distributions, here are some
thoughts on possible causes of problems. (This Section includes contributions by Kai
Troester \mail{Kai.Troester@rz.tu-ilmenau.de}.)
\begin{itemize}
\item{Wrong library versions}\\
This is a rather common cause of grief especially when you prefer to
install the libraries needed by \FlightGear by hand. Be sure that
especially the Mesa library contains support for the \Index{3DFX
board} and that \Index{Glide} libraries are installed and can be
found. If a \texttt{ldd `which fgfs`} complains about missing
libraries you are in trouble.
You should also be sure to keep \em{always} the \em{latest} version
of Steve's plib on your system. Lots of people (including me) have
failed miserably to compile \FlightGear just because of an outdated
plib.
\item{Missing \Index{permissions}}\\
\FlightGear needs to be setuid root in order to be capable of
accessing the accelerator board (or a special kernel module as
described earlier in this document). So you can either issue a
\texttt{chown root.root /usr/local/bin/fgfs ;}\\
\texttt{chmod 4755 /usr/local/bin/fgfs}
to give the \FlightGear binary the proper rights or install the 3DFX module. The latter is the ``clean''
solution and strongly recommended!
\item{Non-default install options}\\
\FlightGear will display a lot of diagnostics when being started up.
If it complains about bad looking or missing files, check that you
installed them in the way they are supposed to be, i.e. latest
version and proper location. The canonical location \FlightGear
wants its data files under \texttt{/usr/local/lib}. Be sure to
grab the latest versions of everything that might be needed!
\item{Compile problems}\\
Check as far as you can, as a last resort (and a great information
source, too) there are mailing lists for which information can be
gotten at
\web{http://www.flightgear.org/mail.html}.
This will give you direct contact to the developers.
\item{Configure could not find Mesa and Glut though they are
installed}
If the configure script could not find your Mesa and Glut libraries you should add the
Mesa library-path (i.e. \texttt{/usr/local/Mesa}) to the EXTRA\_DIRS variable in the file
configure.in (i.e. \texttt{EXTRA\_DIRS=''/usr/local/usr/}
\texttt{X11R6/usr/local/Mesa''}). After this you have to run autoconf. (Please read
README.autoconf for running autoconf )
\item{SuSE Distribution}
\begin{itemize}
\item If you have a SuSE distribution use the egcs compiler instead
of the compiler delivered with SuSE. Grab it at
\web{http://egcs.cygnus.com}
\item SuSE 6.0 users should also use the Glide,
Mesa and Glut Libraries delivered with the distribution
\item A known problem of Flight Gear until version Version 0.57 with SuSE concerns
\texttt{acconfig.h}. If 'make' stops and reports an error in relation with acconfig.h
insert the following lines to \texttt{/usr/share/autoconf/} \texttt{acconfig.h}:
\texttt{/* needed to compile fgfs properly*/}\\
\texttt{{\#}undef FG\_NDEBUG}\\
\texttt{{\#}undef PACKAGE}\\
\texttt{{\#}undef VERSION}\\
\texttt{{\#}undef WIN32a}
(a solution for this problem is coming soon )
\end{itemize}
%%B.B. 21.2.99
Additionally there are two versions of the GNU C compiler around:
egcs and gcc (the classic one). gcc seems to have its own notion of
some C++ constructs, so updating to egcs won't hurt and maybe help
to compile the program.
%%
\end{itemize}
\section{Potential problems under Windows 98/NT}
\begin{itemize}
\item{The executable refuses to run.}\\
You may have tried to start the executable directly either by
double-clicking \texttt{fgfs.exe} in Windows explorer or by invoking it
in a MS-DOS shell. Double-clicking via explorer does never work
(except you set the environment variable \texttt{FG\_ROOT}
in the autoexec.bat or otherwise). Rather double-click \texttt{runfgfs.bat} or
\texttt{runfgfs-sgi.bat} For more detail, check Chapter \ref{takeoff}.
Another potential problem might be you did not download the
most recent versions of scenery and textures required by \FlightGear, or
you did not load any scenery or texture at all. Have a close look
at this, as the scenery/texture format is still under development and may
change frequently. For more detail, check Chapter \ref{prefligh}.
A further potential source of trouble are so-called
\Index{mini-OpenGL} drivers provided by some manufacturers. In this case,
{\FlightGear}'s typically hangs while opening the graphics window.
In this case, either replace the \Index{mini-OpenGL} driver by a
full OpenGL driver or or in case such is not available install
software OpenGL support (see Section \ref{softrend}).
\item{\FlightGear ignores the command line parameters.}\\
There is a problem with passing command line options containing a
''='' to windows batch files. Instead, include the options into
\texttt{runfgfs.bat}.
\item{While compiling with the Cygnus Compiler \texttt{Configure}
complains not to find \texttt{glu32.dll}}.
Make sure you change to the Main FlightGear directory, e.\,g. with
\texttt{cd //D/FlightGear-X.XX}
before running \texttt{Configure} and \texttt{Make}. Do not forget the win32 library
package.
\item{I am unable to build \FlightGear under \Index{MSVC}/\Index{MS DevStudio}}\\
By default, \FlightGear is build with GNU C++, i.\,e. the
\Index{Cygnus} compiler for Win32. For hints or Makefiles
required for MSVC for MSC DevStudio have a look into
\web{http://www.flightgear.org/Downloads/Source}.
In principle, \FlightGear should be buildable with the project files provided.
\item{Compilation of \FlightGear dies not finding \texttt{gfc}}.
The library \texttt{gfc} cannot be build with the Cygnus compiler at present. It us
supposed to be substituted by something else in the future.
As the simulator is already built at this point, you simply can forget about that problem
as long as you don't intend to build the \Index{scenery creation tools}. Just go on with
\texttt{make install}.
\end{itemize}
%% revision 0.10 1998/10/01 bernhard
%% added win stuff michael
%% final proofreading for release
%% revision 0.11 1998/11/01 michael
%% Remark on mini-OpenGL drivers, new general Section
%% Access violation error under win32 added
%% Command line problem in win32 added
%% revision 0.12 1999/03/07 bernhard
%% Remark on EGCS compiler
%% revision 0.12 1999/03/07 michael
%% Added Contribution by Kai Troester
%% Reworked Win32 Stuff
%% revision 0.20 1999/06/04 michael
%% added hint to FAQ, gfc problem

View file

@ -1,924 +0,0 @@
%!PS-Adobe-3.0 EPSF-3.0
%%Creator: jpeg2ps V1.5 by Thomas Merz
%%Title: navion.jpg
%%CreationDate: Wed Jun 02 03:07:19 1999
%%BoundingBox: 20 20 470 262
%%DocumentData: Clean7Bit
%%LanguageLevel: 2
%%EndComments
%%BeginProlog
%%EndProlog
%%Page: 1 1
/languagelevel where {pop languagelevel 2 lt}{true} ifelse {
(JPEG file 'navion.jpg' needs PostScript Level 2!\n) dup print flush
/Helvetica findfont 20 scalefont setfont 100 100 moveto show showpage stop
} if
save
/RawData currentfile /ASCIIHexDecode filter def
/Data RawData << >> /DCTDecode filter def
20 20 translate
450.00 242.00 scale
/DeviceRGB setcolorspace
{ << /ImageType 1
/Width 450
/Height 242
/ImageMatrix [ 450 0 0 -242 0 242 ]
/DataSource Data
/BitsPerComponent 8
/Decode [0 1 0 1 0 1]
>> image
Data closefile
RawData flushfile
showpage
restore
} exec
FFD8FFE000104A46494600010100000100010000FFDB00430003020203020203
03030304030304050805050404050A070706080C0A0C0C0B0A0B0B0D0E12100D
0E110E0B0B1016101113141515150C0F171816141812141514FFDB0043010304
0405040509050509140D0B0D1414141414141414141414141414141414141414
141414141414141414141414141414141414141414141414141414141414FFC0
00110800F201C203012200021101031101FFC4001F0000010501010101010100
000000000000000102030405060708090A0BFFC400B510000201030302040305
0504040000017D01020300041105122131410613516107227114328191A10823
42B1C11552D1F02433627282090A161718191A25262728292A3435363738393A
434445464748494A535455565758595A636465666768696A737475767778797A
838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7
B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE1E2E3E4E5E6E7E8E9EAF1
F2F3F4F5F6F7F8F9FAFFC4001F01000301010101010101010100000000000001
02030405060708090A0BFFC400B5110002010204040304070504040001027700
0102031104052131061241510761711322328108144291A1B1C109233352F015
6272D10A162434E125F11718191A262728292A35363738393A43444546474849
4A535455565758595A636465666768696A737475767778797A82838485868788
898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4
C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE2E3E4E5E6E7E8E9EAF2F3F4F5F6F7F8F9
FAFFDA000C03010002110311003F00EA28A29645DA88E0E067E6AFD6CFCE84A2
91810A31C9EF4F31FCE555B2476340586D15165D7A9CE738F6C538890124E106
380DC0A0761F45204940C90720E08ED4A6270A189EA7A50160A2906E2320719C
83D7229A1594E19C9CF20E3B50161F45330EDD187E1E9EB461BBB103D46280B0
FA2A206452771079E08C629F8628181FAD0161D45478918704861C91C520F333
827AF2280B12D15048F246BD0B37E1D3D69332AA0258E4B606718A02C58A2ABC
6D2BB2904ECFE23C7BD319E6DDB55FF12074F5A2C162DD155774DB47CC4B67E6
0A0714D124EC061F1C7600FE3D28B058B94567FDA27E99272719C0E29DE6DC11
C1C9FC281F297A8ACF6B89B93BD860818C0FF0A413CF86CB9183C703D3814EC1
CACD1A2B37ED33850CCC4023D00C522DD4EFD25CF38FBA28B072B34E8AC93777
1BBFD61C671C28FF000A0DDDC8CE64C76E83FC29F2872B35A8AC87BDB8E48930
3FDD1ED4BF6DB80C72E481D7E51FE14AC1CACD6A2B264B9B9DBF2C8437FBA0E3
F4A6FDB6E48C890E07FB23FC28B072B3628AC417D79BC0DE4839C7CABCF14EFB
45F93F7CAFB6D5CD20E566CD1588D777AA4EE94003FD9152453DF48BF2C8198F
41B46696C1CACD7A2B166BBBD80619F0C064F00D56FED5BAC7139CE7FBABFE15
495C563A3A2B9DFED2BD2322718FF7568FED6BC080EFCF6FBA3FC29F2B0B1D15
15CFB6AB741B6F98777A055A6B6A77DBC8127008CFCABFE14B95858E8A8AE6C6
AD7A4FFADC0F5DABFE1436A77C9C194E48E3E45FF0A7CA163A4A2B99FED8BC24
012F3DFE51FE14BFDAF7A48025C939E028FF000A395858E968AE63FB5EFB8FDE
F5FF00657FC2946AF7B8CF9DC63FBABFE1472B0B1D3515CD1D52FC283E6F07FD
95FF000A51AA5F3722538CE3945FF0A395858E928AE6BFB5AF49C79DCF4FBABF
E14BFDAB7B80C25CAF4CED53FD28E56163A4A2B9DFED4BCC67CE18FA2FF85745
49AB0828A28A401565541823257A64E7D79AAD5A96716EB54247041EBF5A893B
2B8D1565B618601B6827A81D6944246373EC6EC0719AD3308914838393C7B535
A2F31F3807B12474ACBDA176337C8DE31C97C0CB734DFB382B8C9FAB7F3AD130
062DB97907AF3CD0907CC0B004E3181D2ABDA20B19AB0B023A824678E6811025
8E1880A7E519AD36B712678E31D3A546B6E154800807AF627FCFAD1ED1058A46
10C8AE3EF672723A8FA531ADF7B2839C7F21E95A622C0193923A1A12D403BBF9
738A3DA20B19820DA461430C63078E94E58490414EBD0EDE7F2AD1680B02AD82
477028DA1E5DA09760304D2F6816330DA82847627F88FD39FE74DF2486CE3037
1FBBDF9AD4687682C41E99FF003C50600197E5C8761F31A1541F299DE4EE988C
8031EBC0A6BDB80471818EB8EBCD69ADA3610140431E1BB3530AE5B181B73DF9
A3DA0F94A524048DCA327390775446D097C84F987B66B4FCA6DA76AF1D8D4461
650067FA1A39C39519F1C011B711BB8039E0D364B5C7396653D148276FE35A45
40071D70063DE925B7CF0467774C76A7CE3E54508A0D8A5C0CBE7A0350B5B82C
30BF893D3FCE6B51E338F949C03914D7B5CA7395F53F8D1CE1633D6D8AB0000E
BCB62944040D84004F439AD2F27919230C307DA91EDF6005B3CF4E2973858CB6
88FDD25B6E318C506DF6B8C9DDCF076E6B4CC4082A54E3A67F9D47E57CE00181
9C2FA1FA50A616331E1704011F07BF5A8C5BE14E4103D4D6B9876ED0CB9E3381
4C3161461385F55E9FAD1CE163285BEC5C952DBBA76C534DA3AAFCAA7713C81D
AB55E0F3B6B0E0739047E14050AC54824938C8E94FDA31D8CD16870015F98819
C8EA29A2D8EF50570A39CE31C56A4B6CCCA1828E38C13DA98D6A0E320E08E003
4732158CC680066CAE40C8C76EB44681A4476C375F949E3EB5A09160B0C63E5F
C734AB17967EEAAE472071439E8348A2ECC58E506573B481D3F1A9E08E220872
37F5073803E829E6D1E4940023C31C64F27F956BC3E11568E37371112C79DAC7
22B96AD58535AC8DA10949E8848F41D3FC8691A41C71B40186F7A23D1AC2E202
207456C81C801B938A98E93024BB26B90A41C654E41A9A6D32CA1877C571BE42
3A28CE4F4E7FC9AF2675EDB4DDCEE8D3EE8C29FC2B711A962A08C673B87F5ACD
5B05573BB907BE6BA992DD25B71B2E9BCCCF240E3A74AC5BAB2685B965231D89
EB5DF87AF29AF799CD569A8BD119EDA6C3B49DDC0F9983739A865B548DC2AF2B
CE369AB6B1ABEF2412C0E39E8293CADDB4ED1D0E31D47D6BBA32F339DAF233DE
CC123CB5618E09148F6E17232588EA7F9568889A38F0D8E4F5271485042580C7
DE038E7DEAA3395C4D23305A976215431C9EA09AB83C3376F18CC691823392C3
8FF0A9819227CFCA41EA718C1F5A26B99994EE6E070D8EF44A551BF74128DB53
3A6D3DEDE42A577107AA9CE2A1684E59C8E0F4F635A8606DA0F5461CF3D07BD3
24880439521735A466DEE4B5D8CC1164E0AE73D79A9122F9D80518C800919156
FC85691005E4F6A9563D87681B73C127915A29136339EDB6EDC64803807914B1
42AD1E4BEE19FBA38ABE837A766EC3071914C110039C739EDCD5A7726C51F231
B8152791C9EA38A5F2CB0DA5B20739FEB57FECF907F8415C8CF5A8A3844AFBC4
A32BC08C0E838E73EE73C7A5272498EC462CE6530968F7895378C8E7A91FD2BA
0AAF790955B377C82223CA9C9FBEFC558ACD4B995C99AB30A28A299015D06970
EED3E3E012C18E0FB135CFD75DA1444E930B63AE4F03AFCC6B97112E58A6694D
5D91889B6104283FDDCD2BDB26FC7CD8C7F1568F9472481F538A468C951D413C
74AE0F686FCA508E00E0EE0460609028FB29CB38031D8AF7ABA909F2F18C641E
697C8C9C105BDCD1ED0394A5F65E0216E7AED03FAD27D97CB40B923820127B56
9A44A060E42E06588E69C2D9036EDE00CFF10A87547CA630B7183B986338F7A7
0B6DAEA547C99258E79AD45B53E670876F6207F3A749004E06481C1C0C1A6EB0
B94CC16E5870381D7914A6D377CA321BA820723EB5A18DB80403ED8C67F1A604
F98F1CE39A7ED18EC8A50DBA81BF1B881F2E3A73F5A6FD9DC10C4633C63F9568
C711908C8F97D693C8DA0A9F9C3720F719E723F3A5ED42C654B6EC54952006C6
E3FD29EF17032303B115A42D8EE010061D723FCFAD35AD406E54600E9DAA9554
2E53305A98BE65DC3BE3D699B1C6485C3120107040E3B56A6D554C6D18FEE814
F4B5DA9C039FF7707F4A3DB0729930C1B187C8002793F8523DB299D411943C64
F3CD6A2DBF9CB820C83D0F7FC29B25B79CBB48E31C155008A7ED6CC394CD16CD
221270011D0738A6FD9F24AA9DC47F0918CFA9AD7F23F7380B81DDB3C9E6A392
0C6005C05FE1E306A7DB0F90CD7B6CA670476DA0FF00F5A9C2201B2719E46307
19AD0FB29C6E524027919EB4CFB3EE43C90ADEBCD3F6B70E5466181D1940F419
C521B70181539624641AD378C48C73C01C803D2945A28627D7183E9F9D4AAAC7
6465B5A316246003C8DA320D31601BD400ACCCD9391CF4FF00EB56BB400ED523
27A96A4112A92428299EADC53F6AC2C632DB3976DC0A838C9C74A3C82FF331E3
A9E9E86B45EDC821957712C4E723F03482D589DA773609F99BE9FE453F69E616
325E0CB8246D380000727F4A431805982AAE383F4AD79AC90824288C9E576E3D
AA29212A1F203E01624F5CF5E29AA9E616335E32CAC769C75056A35832091823
AE76E735AA6D9FCBD8C7818CFB7351B42CC490BBB07A77269F3DFA8198D0E082
14670452C82473B01603B007FA5681B6E0385651FDDC72476A8D97F76A0024E7
241041EFEB43927B94AEB629A46CD203C961C0ED5ABA5F87E4BEC8699608C105
9C827BD43E4CC5848B1336F3B41ED9F5A9ECAEEE2D246063CB0278663F9579D8
9AF51271A5B9DB46941EB5362E7FC21BE5B663B88DCAE083B4FF0080AA975E16
6B7505274959F808A39FD7EBDAB5CEA770BB4AE0E7AF5040C551D4CF9CC8DF6A
11903A8E33EDDBA57934F138B53FDE4AC7A12A14397DD5718DE0A50A0A5DABC8
C394DA46D38F5AA63C28500F3240B83C11C8E86B42D3578ECA25427CE18C64BF
23DF1EF5613C551468AA628F713C64824FB566F1F8A83693BFC8AFAA5192BEC7
36744916429B894EA4A8FD47155FFB2447FBDE5803D4746FAD7656FE21864676
16EA093C900367F4AD1B6D51A68BE55548DB19CE003FA54BCEEBC3474F51FF00
66D396D33CE6DB44B9BB942C703CBBF8555191F85413E99241215954A38ED9E9
5EA29AC243958AE14630088C8C8CD51D46DADB5A285FE6908C0652371FEB5D94
73AAB29AE7A765DCC2A65D18C5F2CAE79AC96E70C1885078523BF1CD385AB175
C3363AF2A7FC2BA94D3D2D2F1E336ACD183B77B0247F2F7AB1716507D8F70888
0BF2E53A939AF63FB420AD6EA79FF569BB9C5F932229C904F6E29C6D4C809C1F
941EDD6BD0F4AF0F5ACB11597C9959C70760C8E7FCFEB4D93C29243E66C314A8
8C3647B707B9E2B059CD1E670D99A3C0544B9BA1C17F67CCA9B8C6C80F1D3FCF
7A68B73BD801B8E76903B715DB595BC3E5949AD4B36385E847B7D2AB3E8E46E9
3C811AF1C4684FF2AE88E651FB464F092E87282C1C0CECE9EA3A9A618632E63D
80CA146588E075231F9FEB5D80B37B2DA0C12391F75C8F4F6ACF8EFEDF50F10C
FA7CF6F2412430248647C6D6FBDF2F38EC47D323D69BCC55EF612C33D9B31A30
F744038C44762E074EFF00CC9A4AE9ADACACA79AEE3597698A41182C07CC0229
CFF3FCAB99AEFC2621578B695AC71E229FB36936145145779CA15DE785EDC49A
25B72324B609EDF31AE0EBD33C1F086F0E59B77F9CF233FC6D5E6E3E5CB493F3
FF00337A2AF21E9605D8AC60151C8527DC77A47B470C01219179C0EB5AA60F35
98FCA4AE3D7F5A96483E7072194F523FCFD2BC1F6A767298BF64DC3191F2FDEF
A52A5AFEF1F9CAF4008C62B51A01B5972547B7A7BD312D9FCD2C47C9C0C679A7
ED03951416D543918CF4E4F4EF4FF21109CA7A63238EBCE38AD38AC9514BA866
1EFCE2836BBCF25897E073FE7150EAA6351B1951DA973BB615C75DC7041F4A43
65B9CED2A4F7CB56BC768136AE7E553B4331E09A6B59C857322854EEB814BDAE
B6B8F94C836B920E02E3AE4E7205322B13E60E9CAF248E9FAD6C0B51B428CB1E
D8F5A05B157DC0F1D3E957ED7CC9E546479040704E173C8F5E948F6B82BC6064
E719FCAB5E4B565657032067191D7B5312D99B2A5B1F53EBD29FB41D8CC58002
594052A785CF6A592DE4DC32A08EA768AD2166CE0E01F97A963CE29F25A6F04A
03950724F2307B9A5ED3CC76317EC60FCC832339639E69CD6DCEF24AC67A62B5
A3B40B1AABB31C67EEF048CD2A5B80BB554093AB51ED42C8C586D5A23B9B0483
C9538C52988275187E47E15AE2DF76492413F2800D21B20CCC4E3382A30DD4D2
755751A8998601E50253009EC73CD432C202B1032D9E09AD892D360C9565071D
0F7FC29D1DB0036F2B8ED9EBE8297B645723325AD1DC065200033D3AE2986D84
4016538E80639F5AD76B360320372D92076A78B6255786663C924E454FB71721
8CB641796550C783B0E7FCF5A63599DCFC1CE3807B56D4B0052DB8E38C531EDB
7AEDDADB0F424F5F5A1571FB33256D0BC00AA0084FF11C13518B525586DC60E3
0067B75E7EB5B8D016DBD49EC6A210B12083DFA1A9F6EC1D3313EC6DBC03823F
2A4FB383D9581E32A738F7AD7960F97E61D09C3120D31ACFCEC6D0DBB3D15801
5A7B7D352790C86B125B047D09A3EC6B1B924A9DFD71DF1DAB5A4B4692464914
8C81819F7E94E92110100A05F9790718A5F584F663F66D743125B4DB9CED27B8
1D6A216EA640DBB3D42B8E807D3BFF00F5EB5268BCC4C2A051904B1EA3B7F5A4
16C30C0FA60FAE726AD57D2F717B3D4C736CC6556DE3009A47B50C72DF3B1C67
19E78F5AD77842FF000F99EB8382077FC7AD3A3811E4DE0EE8FA12C01391FF00
EAA4F1565765469393D0C4F21860295F2F192093F9D433DBC80348396539DC32
7F4EF5B8D625508116100195041EF518104320DE8C8ADFF3D1872D9E9C5613C6
525AC8EA861EABD8CC866956024FEF58F5ED9151BD82C8E64752727A2926BA58
2CAD25C91200C0608FBD9A51A4C0C486971CF5E7A7AF4AE15986153BA3A9E171
2D58E48D881230319C0F7A7FF6582A0ED039EA5F822BA16D31229591A40632D8
52A3AFBD3C6990820237CC47DE23EF0AEAFAFE1A5B3460F0D884614365F673BD
46D19C1C8ED52CA66704B14DA17017D463B715AC6C02A1C39F42181C5559ED8A
36DF970481D7B5542AD2AAEE853855A6B52A43612346D711346AA31C13C90699
0DCCD6F751C892F3FEEF03AFF8D4C6D2552CF180580C124F6A70B26C9241C633
9EF5B68F732E66B62A4B753976FDE6E0ED9E4631CFB54900695416F93070D8E6
AD3C20EDC30E3DB9A6C9017846DCA1DDDBA74F5ACE74A13566542BCA2C6C777F
62B95521C2B77DBC1A926D66775D88C4A8CE39000FEB51B42D2E412DC007AE45
1F65562D91CB1C0E7D6A2386A49A6D6A54B1336AC98905F5CC7333BED2071F74
1C9FCEAFAEBA4E4347B08F5DBFE154CC4C931248C638200E7934F4B625431040
CF3B4F07F1EBDAB6786A5377946E62B13522AC9FE04C3C4122FCE918DCA39240
C138AE5ACEEA6BCF19DFDF9566F3A18D01C27979C609001CE7E507FC9AE8D88E
1828DDD4EEEF5C928B7975AF3BF764EF450CB9CF2644C74E7F87F2143A54A9D9
A875EE5C6ACEA5EEFA16B4A81A2D42E558B933B7980BB7031D7183EE2B2EB534
2B18A2BC45568F76E3192AAD96FDD86E491EA2B2EBE8F05CAA2D47FADCF2B12D
B96A1451457A472057AEF8163127852C030CF1273FF6D1ABC8ABDAFE1D448FE0
DD3C95049F33FF0046357859C4B96845F9FE8CECC22BCDFA1A420561C220CF4C
8A568159C16500F7C8AD26855F92B919C9A71507AF7EB5F21ED4F5794C896C7C
D4180147B2F5A68B558D597073C6430CE3FCE6B5BC950005E051E4A93C8C8F7A
7ED5DAC2E55B99896A8BF388D57B0181FE7FFD75235B06C6501E3008AD14880C
018FE54AD0853CAE2A7DAEA5729982D82A828AB9071C01D2905AB1C312DB8719
AD211E334189490714BDAA4F529536F548CC164BE617D99E771C8A55872EB8F9
643F789EF5A2D0A92381EBD697CA5F4E7D68F6CBB8FD94BB1910D918D0336E04
64649E6964B6120DA06598004B0CD6A9881209E714A23033C0C9EF47B75DC3D9
4BB19417CC895193764743DEA29A0067400153E98FF3FA56C1B7046071C63818
C51F67518C76E84F26855907B36B731DED8162CAAC841008F4E7AF4A516C007C
6186EE1B6F18F7F7AD56B60EA430CF39EB49E418E3C2E303B51ED9771FB29763
1FEC009C63248DDC2F6A3C854201E73800569B2F041EF81C1ED4DD8A318046DC
E39A5EDEE3F64CCEFB2100B2E42F51C7029E96AD1AB8505B9E98E9F85681450A
5402547DDCD009073DEA7DBDC7EC9994D678638720F7E2836C048BB7EE77535A
65573C819F7A605507A0C74FAD275D0FD93335EDC13C776EC3A52342AAC4019F
AD697920F718273C0A4F21771ED8FD6A5D64D0D5395CCB11039007E0293CA030
00C0073EB5A2D6EAA870DB475A8992355DE59768E3239ACFDBC7B97ECA5D8CF3
6B19C9603B9248AAFE5297CAAA8F755E9576E2EEDE075CC831FC583D2A17D56D
1118EC7183D4900543C4C36E62E387A8F5B10EC667C904B7439CD31E15DC7728
3C63914E975AB62DF212B918F53555F5D8D8ED2A5D73C638AC9E2E9C7A9AAC2D
4913496F85DAA8A768E171D29B2223A0DD1AC448F4E959B75AAC8EC7626C031C
16AA9F6D9D98191F763A0DD9E2878B4ACD16B0B75691ADE42E09568CB804EEC6
707FC33552E62B90CCCB30D9D400BD2AAFF6A0424799C1EA157B7A66AB4FAB4B
0CA5234F3091D3AE3F2AA862D4DEB135FAB4A0B463D6DAECB126ED910F3B9BAF
FF005A91ED176235C4924C064AF39AA4FAC4EF1E1A3079EB8A06A3FBAE54F99E
9DAA67524DDE113551B6EC788A51810C53C5907FBDC568E9FA7CFF002BB4CE5B
07E5DDE958ABAADCBB6E0CCC01CE32055CB5BDBD571BDD187F74119FCEB9EAD6
8F489AC60FB9AB35886072CCA7192DD7F3A9E0B65D8AACC5DF39DCDC9AA914F3
29CB2819EB8C1CD4F09910E160DEDDBB1AC6389B68A286E92BDDB2CF92449876
240E7D69A2DD64918B27CA0AE06DEB52456B73C96099F5DDD47E02ACC16C507C
F8271D413C57A34715187D9382B527513F78CF4B36C9C467DD8F04FD7D69D1DA
85FBCBB01E0E17DB26AF85915BE6C11EA29E31B4E403F5FA1AF46388BEA7993A
2E3A5CA11C2307E5C6792D9EFDF34C3691C847CA0F19C63040CF635A69182ADC
00BFC5EF436C257E4C60F383D6B55885D4C9D27D0CD1080E0F9587E71C6285B6
0AAC9B461860ED1CF4AD48E332C8081C0EBCD27D98E588C8CE4E48E87A56AAB4
5F521D36662400B215006D27393D79AF0CF8A1FB49C5F0FBC5D2E8716991DFAC
11234938B82BB2420FC9B00C1C7CBDF3CFB57D09F66755508CA0746DDD4D7C05
F19FC3F6707C53F12AA89886BC773BE766E5BE6383E9F363F0ACB138A95382E5
674E16846727CE8EEF51FDAFAF9C23586916D1B3125DA60C413D88E71EB5C8CB
FB5378A1AE258D2CB4C8E3F2C282B0BF3839FEFF00A935E6575A459431CB2B44
CDB14B11E63738FC7DAB1DE7B154F3174F6643D0990FF8D707D6AAC959499EA4
70F4A2F48A3D5A2FDA83C7175712B9BEB7810BEE0AB0AF1F9D7D435F065B4B6D
E7C49F60450C40C0624F2715F79D7D5E45394FDA7336F6FD4F0B358463C9CAAD
BFE81451457D59E0857BB7C34902F8274D1CFF00CB4FFD1AF5E135EE1F0DE353
E0BD3891CFEF3FF46357CAF11CF930916FF997E4CF5B2C873D66BCBF547585D1
88C8FCE808858F43ED8AAC62014E324FD69E8850FDE26BF3C58848FA37876C94
47193D3269FB14127039EB50E68DDEF47D65770FAB327C81C7148CCA7838350E
EF7A072703926A3EB112BEAEFB92065518518A6AA46739148AA5891D08EB9E31
4DC8A9FAD2E9F997F577DC7B2C63385C9FAD4476EEC77A76451B85278A1AC3F9
8985F6FCE9768349BA90CAA3BD4AC5A2BEAEFA31DB40047AD34A818E09FA501F
A71807A529619C77AAFAD760FABDB71B941D491EC6860ABEA4FB520931819FCE
9A642E464E07D2A7EB8CAFAB798C95830E1738E99A8E4F9178407DEA61721980
0C84D327BD82DA37799D522452CCE4E1540EA4F60060E4D258A6D87B0B15E4DD
1ED071B7B0A7C6819725707D8D7203E36781E7D5134DB6F13E97777AEFE5AC10
5C23B16C670319C9AC2D77F693F86BE1DBE305D78B6C0B80430B326E1073FDE8
C30EDFCAB39629C745177368615CF56D1E94F1FEF146383511248C0048CE702B
CEB43FDA33E1A6BB71B62F19D8A7CD8CDDAB43C7D5C01DBFCE6BBFF0FF00893C
35E2CB811E8BE2BD1B57B8C1222B3BB8E5931FEEAB67BD73BCC147E38346DF51
97D96993B905418F2CA0F5F7A80C87E60C7662BA17D0E429F3303EE17047E66B
3AEB49BA855B36E70BD5C2F27F1A16614A6959932C1558BD5194D6D12AEE00FB
66AA5C461000A09CE739C60D68BC055D8329461D41E31ED4CC2B67047070715A
2AF1BDD18FB392DCC7FB22AAF11A0CE48C8E334C96D56E2209731ABAE7380091
5B413079A3CB55F402B4FAC5B627D99C8FF62DA246DFBA42FB801D463F3A89EC
D6156D90286EDCF06BB2FB3A0278C76AAD36950CC7E65C8FAD4BAAA7BB355789
C4CDA6B4B1AE0C39539C963C565DC5CDD4320CC431EABCE6BD066D22DE119C80
BFDDF5A8FC31A6E99A9F89ED6D9A00CA4B078F670C0293CFE559CF12A307A6C6
D4E9F3C92B9C00D410FCB2A37AE0F18A79B9B768B3B5000701829C9E2BD07C7F
E10D3F43D97769B155DCA9B700109C0C639ED9AE3230CAC02429C74200FA7A54
D2C429C79E26F3A4E0F96463C3009E50AD1C8BB8F451C62AE1D276C8D857C2F4
0D9AE8A133318F65B05E7E52481FD2B46DE79D64D8FE5804A82CF8F96A5E25AD
913ECCE621D144A14184E587F0AFFF005AB521F0FC9190CB6EAAC40F97005756
92C06300C96FDC90AE298752B14E3ED317A70E0D5C6AAB184B99BD11956FA4CE
ABF32A27B0ABE903E36E00FA2E053BFB5EC727FD214E3D29BFDB360491F69008
EF83FE15AAA8D74326A72D09AD412D1EE5519CF3D0E31FAD2CB661276646C679
208FE5FE45675CEBC88DB506D3DB71A48B5C32B3642638FE239FE55D1F599463
BD8C1E1F99EC69C368429C6007C86E3A0FCFF9545059995DC3614A01C6323F9D
469768CA36101CF70793549AFE7008C2F5E70739FD6B65899357447D5D75342E
61915CC60FC83A6005151411E58B67628FBCD8CE2AB45773C818C8A9E5E78F9B
007E18A6ADE066552A17D4934D5793DD89E1D25B16E573B86C7CE3D0714A92ED
0370249EA6AB5D5C18AD99A3914007273F43FF00D7AF306F889FD81AADDCBAB4
9E445E53BDA279B959B030540C704610E3E6386F638D7EB72891F554D5CF59F3
46460153FDE3CD7C09F196F60BEF89BE219EDD8B29B92096040DC300E2BACBBF
DAF759B3F185F4B1D832D88DF8B19AEB7AC608503070391B73D07DE35E2116A9
25F4ACF73334D72FF33C8EFB99CF739FAE6B5739D55AA2A1455363EF5C359DCE
4E488D8F1DB8358D6DF623E12D4FCE937DF2CB00813318C8F9836727767E9DB9
3EB5B13BEE523EF03C11C1C8AA7F65B4DA3FD1E2CFAEC1FE15515646F636344B
BD11FE1F5E44F248DAC1BD8DA10248F6940D17F0FDECF2DCE6BEC8AF88249EDE
D0E0F968D8FBA1466BEDFAFB2E1FFF0097AFFC3FA9F399BAB727CFF40A28A2BE
BCF9E0AF6BF8797091F8334E04F399011E9FBC6AF14AE7B51FDAA1BE1ADCDFF8
7E6D1D6F5ACD905B48B26CCABA0918B7AFCCF80076AF8AE2C8CE5828282BBE75
F948FA0C9397EB12E67F65FE68FA4FC53E3FD1BC1F6D2CDA95CF90A919930719
61900639E4E4FF00FAEAF697E29D3F59B46B9B2B98EE21590C4CE8E0A8707057
EB923F3AFCDDF8A1F160FC51D5BFB56EECACECEFCEC0E6D0B8F31426D1B83139
231C1E98FC2B0F46F8837FA4E8B71A5457321B59675BA548FE5C4ABB7072067A
01F903D6BF31584C472F32D1F63EC94E937668FD4D7BB08D874656EE29FE6831
960410064E2BE5AF84FF00B5BE95A95925878A563D32E61F2A286E215778E652
31B9CF383C0E49C726BD521F8F5E04BAB5B5B95F1159243720B46ACECB200339
DCA4657953D40FCC8AE16EAC1FBF16747B384BE191E926F72385C50B7CCA73B7
F5AE6B4CF1669BAE3C91D86A16B76F1852C2190363232BD3D455B79977904E3F
5AE775A46CB0E6B1BD9013F38407F2A8D6FDDCF127E95C878BFC6FA478134C8E
FF005CBCFB15ACB208919919B7BE09DA0283CE01FCAB92D13F688F017882FA0B
2B4D742DD4CDB1639ADA54CB75FBC571DBD7145EA35CCAF62953A77E5BEA7AE7
F68B038F33F4A61BE120C3B6E1E86B37CE4651C8C63A8EF503EA102C72482556
5405890C318A9F6922BD8C0DAFED150DC64ED1D334C7BE04E77103B8CF4AF3FD
2FE2CF83B5A9D2DECBC416334CCEC8104983B81C11CE3BE3F3ADFD335FB1D581
5B3B986E7CA3C98DC1C73DF1EE31F8512A93EA35461D0E80EA3B402CCDF41CD3
4EA6CD83BB03BF43543CB6DDB829556F5352436B21C6230EA4D2E797461ECA0B
72DAEA2C0649FC73C534EA4E0B05E5BB0269469933B0022CE4F7238AB4BE1791
DB3FBCE3AA8007E79A8755AFB45FB18BE851371BE32500DDDBD2B85F1B7884DE
A49A6D938B895D1D658600CE58E3007CBC80738F7AF5687C2D94C14ED8209069
EBE0E48F7346A10B7DE11A85FCF15A4318E9EB1D5A23EAB193B49591F9B1F64B
4F873AACBA1C124D63E3095CC77F7D0BF990C10C8B916D0F51BD94A169060AE3
682413BABCBF0CB40B8B72DE57CDB5898D2497728009CE071DBFC7BD7E9847E0
D8F76F2650FCFF00CB4F7CF4AA5AE7C23F0E7896030EA9A5DBDE0910C65A58C6
F20F3C300187E06BAD66AD34DAF531965F7BF2CBD0F827F674FD912DFE31E937
7AA6A5AFDE69B14322B4705AC699789F7E0EF63C74F435EDBE23FD89345F03F8
6F55D7BC2FAFEB9FDB9A65ABDDDAE6E1097641B8AB05404E4023EF771D4707E8
4F877F07348F8632DC9D0DEEE1B596311A594D3078A3505880B950DC6E3D4B1E
9E95CC7C65F8BB71F0B7C3F797DA87872696C997ECE1BCC51BDD87CA46D04633
D7241E3A1AE59E331188AB6527CADEDFA1D71A14E953BDB54B73E7DFDA53E22F
8A3C4BF0B7C11E3AD1358BCD36DA6DF617F05BCAD095B9FBC1B0B8C8215867B6
38EB5E31E09FDA47E276837F0BDBF88EF6F2389D6496DEE7132C880F2ADB813B
48E0F4EF5EC36FE2D5F893FB257C48892C9A1B8B3BDB7B84843972177DB6F6C9
007DD53D31D4FD6BE48B6D5E27FB8C44910E64191C8EF8C7B57B997D384E8CA9
4E0B9933CDC5CA51A8A70968F63ED8F1A7ED43E23F0EF892D752BAD0E1D57C2B
AAD8C577656EA4453C3F2ED98348B9E56549320E40C8E474AED7C33F18F4BF1E
69D73A868177731476EE124B2D41516E6307F88282C1939C6ECF507818E7E668
FC4ADAA7ECA7A0DECB12C9A8E87E219B4D8DC16DAD14C8F396207BA8E3B5796F
80BC51ACE99AFDA3DBE612932C914D1862C0F4CA8CF7048391CD674B0F4F91BD
138B69EA67567539B5574CFBFD7C733A91BA5DD83CE5073F95491F8DE79D7253
2A08E02E0FE79AE1B5FF0010691E12F0B68BACF88EEE4D35F51B732F97240E0B
488AA64555C762EB8E7A115C7693F1E3C05AA5F5ADBC5A9DD79B72088A216CC5
C3E4055380465B3C63F1C54274E517257B2DCAE492925A6A7BE45E2E964883BC
6029381B7DAAE5BF8A2DE52AAE9221CFA039F6AF1ED37E30F8175FBB305AF885
55618F205C44F0E5464E72CA01EB9EB93EF8AE37E227ED1DE1FF000B5B598D03
5183579E473E6810B954518CF1F29C9EDF4359AA6A5EEC6E54B4D647D36DAA59
4E060B3F3D49E95B9E0CB68A6D6D67870DE4A31DDDF2463F91AF927C05FB5278
5AE346B293C4BAA4361AACC24332DB59CCD1438930832031C95C9EF8DA6BEABF
817E24D1BC61E1DBED6743BD1A85A9B936C2E044D18250027018027EFF005E95
C78AA73A4ACEFA9D386E59CB434BC71671DC5CDBA48BB8B96FC7A5732FA3418F
DDA0500E4AE78A9BE3178E34AF09EA9A25AEA57C9652DFF9CB034A0ED665084F
38C0C03DF1D6B80BAF8CFE17B3D5AE348B8F11D95B6A51005E3964DA17E50792
4019E7D6B9B0F19B82E5D4DF11CAA7AF91DB2E8714602AC87681DBFF00AF50CF
A1EE0DB266008E41EF5C7CDF1BBC1161629732F8B2C2485E4F2D5E29378DF8DD
B7099EC0D644FF00B4DFC3BB598472789E121C120AC3330C74C642753E95D3CB
55BF859CFEE773D0A2D0E54721A6241FC71FA53A4D160524B293923906BCAFC4
3FB577C3ED034FFB5C5AE1D4723F776F670C8CED93D79518FC4FB75AC4BBFDB3
7C0074BB89EDDB5269902EC84DA1DD264F2579C71EE47515B429D76EEA2CCE6E
9EDCC7AECF656B1895BCC6550864E5C01C103BFD457845FF00ED6FE02B093C98
2D35CB878E40ACC90C40631C904C9DB815E13F1B7F685D5BC77ACDCC1A6EA32C
5E1FB8836AD83129B3728C86C6373065E09C81D3D6BC5238E6794BBB0DADFA9F
A57B987C1B6AF559C33ABAFBA7E83FC33F8EFE1CF89BAB4D61670DFDADE450BC
E5AE953CB28A547DE563C9DC38C56C6A5F16FC27A7EA22C8EB903CCDB4288FE6
07774E4715F9FDA25FD9E9D67A9C73CF750EA0F6E12DDA1601589619DE7AE319
C63D6ABCBAABA4641930D2005B031D0F1926B4583F79D9E847B56D799FA53A5F
89F4FD52731596B56B74E1777911BAB301EBF419E7D2AD6A1ACC3A3D85C5DDD5
D0FB3C392645427819CF4CF3C0E3DEBF3A7C13E3CD43C16D7B71A75EFD9AEE68
0DA872A4B221209C7B90B8CFB93D79AC9D4FC69AA6B9788F7DA85D5DB06248B9
90BF5FA9E99ED52B0936FE2D06EA2B6C7DD337ED2DE11B4FECF12B5FA8BDDDB4
F971811856C12DF3F1D7B66BB4D0BE21699AFE956FA969C6496D6704C6EC9827
048E87DC57E764FE299AF92C61B864912CD0AC4A53A65F7373DC96C9AF4AD0FF
006A1D63C23A659E9B67A3E9B3DB408CA259C4864662492480CAA393D31D2AE7
8769592B99C5EBA9F5E78B7C477979A25C41A5C456F651B51DC8014E7393C118
C67B7A0AF92BE30788F58F0E4B69673DCDD19416759253E684620072A59475C9
E0E791D6BB0D07F6BEB5D424587C47A4BC43CC03ED1A7A95083B82AC58B73EFD
0D71DF19FC6FE19F8890DBC9A36AB2C7751C0E8C9770150C472393FC5807F31D
EA211926A3281524B7E63C46693E57903E431FE2E73FCEB5EC432431B6F3BF6B
0186E3A57313AA25CBAA4BE6460F1201C1ADCD3A6C69CA3AFBE3EB5EB190935F
38B553F6B984A57A103693F5AB29697735BC328B975046483FFEAAC1763B339E
9C559D39B6B121BAE38A00D358E081B7A82D20FE2724FF005AFBDABF3F2E270E
02E719391C7515FA075F5D907FCBDF97EA7CE671FF002EFE7FA0514515F5A7CE
857C8DF1DDE53F15F5C8E37DC0883E53D17F711D7D735E35F11346D0EEFC5979
25F59C524EFB3748F26C27F76A077F4C57C7714E2D60B050A8E2DDE4969E92FF
0023E9320C3BC4E2A504D2F75BD7D51F3A5941332EC91563039CE0124D4EF68D
BD7323EE1D33923F035EB975A0F8626C09A042318012E5803F5DADD69F67E1ED
06C9E396DAC9E37EA1965623A707AD7E5DFDB949ABFB395FFAF33EEFFB2EAA7F
1C6DEBFF0000F25920BA91142207E9CE70473DFD6886DEFA7B99736F728C4704
A363207B57B0CA9A7C8FB58177E461A46C8FCAAACBA7E992BF97F64B81D0E4CA
E47E5935CFFDB9DE99BACA25FF003F11E4BA6EBBE20F0EDEA5C5B5DDF69D740E
E46595E139E9D723D4D77763F18BE24C92A5C1F14DEEF898B6C9F50F958139C1
0C70C38E86B4F5AF09681A9824D95C45295DAB2C6D20DBEF83907F106B8BBCF8
73AAC0EC34DBB335BF2424D03838F4CED20F7F4AEBA39861312BF791B3F4392B
60B1141FBAEE8D5F17F8D3E2078F6649F52BBBDD4E2F302A5AC171E7468D8C61
634380707AE33CF5E6B97B6BED47C373A4F3DA5D595D44E7CB926428CACA7B67
91D6BA1B6F86DE2ED27469B57BB8ADEC2082EA3B6CBCBB65769236752A147236
AB1CF1C63D78B8BE24D4342D39F75FCB3411B8630B0CA39C8EA0E72381D7D2BD
25530CD7242CEFD8F35C6B45DDAD495BF690F1DEBE61B35D7AE613E62ED6B76D
923306CAE4A8C9C927BE38E7AD769E09F879F103C58B7576926BBA8A5EC656E0
DAC92246FE80B670C0301C7B015E149E289EC75E5D5238EDA29924F31152DE3D
80E73F736ED3F88C57D5DF0A3F6ECD5346D363B4D66DA3BD8D14802DEDA28F9D
D9CFCB8F7ED5862A3F574A54E95CDE9275DDA53B1C6DEF80E5F855AC09F52D13
65C242B73289E049D62477DAA4472361D890FF002856C005BD0D7AC8FDADBC29
E0DF0ED959687E0EB692F5A20B74F6CB1D924B2003E62A88C79249C1C63B579E
7C5CF8E363F17B5682EE491EC6D9AD96DE7DD1C61A30A58ABAE383CBB0C1EC47
3C570BA07C0EF1378AEEE0BAD2F53D265B27C3A3DD48F1B48016E368563FC3FC
3D322BC07258AAB7AEF94F5E349E1E9FEE9731E89E25FDB2FC57AB064D2F4DB0
D214B6E1B63F35C01EEDF8F38AE22E7F68EF1F5F10C7C4BA8C59258793318FBF
418EDCF4AF48D07F617F17EA724535DEB3A1C56921242DB4D336013C0198BFAD
7D37F0CBF663F077C3DB349E4D26D750D61650E2F6E0349B7EE81B431C0C609C
E07DEA8AD3C2D2568FBCCAA6AB49DDAB23C8FE145EFC4DF19F85BC217B136B8D
35BEB0A6F24BA95E34B8B3930DB99DBEF2AF3C0CF5E9D2BEC5B2B6686DA2494E
F90280C7D4E292DE14B74544C0550000071533498200AF2F4BB676CA4DA5142E
D45CF03E94A36918FD2A22D8A10D2BEB622C076AB118A4122961C66984FEF0F3
48839CD4736A55B41ECE370FE554B5AD16C3C4561258EA7656BA959C98DF6F77
0ACB1B11D32ADC1E6AC9397C7BD4B8DC791823B8A6A4FA09A4F4678E7843F665
F0BF81B43F1968FA6497A961E248DA278E693CCFB3A142B84CFA16279CF000CF
4AF17D27FE09BDA27DB925D6BC5F7B7B6AB9020B0B14B66396CFCCE5DFB71D3F
C2BECBDBC8A7119AE9A789AF4EFCB2B5CC674A9CEDCCB63CEFC1DF01FC0FE09F
06B786ACFC3F6B73A53CA27922D4A25B912C8070CDBF3923B7A76AE834DF0078
73460069DA1E9BA7A860DB6CECE3897208C1C2A8AE85B3802819009AE6727277
93364947639DF12F81B43F1859476BADE9D67AAC313178A2BCB5499118F53B5C
1C74EA39AE0AF7F660F87ED7F777F67E1DB3B0BC96DA5B659AC6211346AEB82C
8A3081FB0623804D7AD1E003DF3419303D2AA352515CA9D909C232776B53E29D
4FFE09C36B3DF3BD9F8CEF6D6D390B0BDA09180F66DEBC7E0298DFF04D7B5993
E6F8832C7B47F1E8C38FC7CE02BED87B98E1DA247552DD371C7B9FD3348F751A
B6DDCA483861BBEEF4EBF81AED58EC42D54CC5E1E9356713E25FF87644092195
3E21965ED19D1B81F95C57D4BF02BE195AFC20F87D0F85ADEE85E3DADC4AD35D
FD9C43E73B9DD9DA09E8A54753D2BAAD464FB469D751C5335AC8E8D1A4C8E159
4E0E4A93D08EBF8679AFCF9F8C7F19FE33FC12F1149A3DE78EAFA6B96512C522
58DBBC5329240F99972A703A60F63DC56B0A95F1F254A53FBFFE18CE50A7868F
3A89DD7FC1496ECD9DBF830C6A5D9DAF159949040C438E7F3AF87AD3CDD4B561
0451CA2E09CF2F92001EFED5D3FC48F8F1E37F8AF6B671F8AB587D592D5A436F
E6DAC49B09DBBB05547A2F73F8570B6DADDCC177F6A59317000FDE8500F6FC3B
57D560B0F3C3E1FD9DD736A78F5EAC6AD5E6D6C6B5DE853C7A519EE2468DA300
E367079C63B639AC8BE86680C0E5FF00D6807E56E320E0E4FD7F9D3AE3C41757
50795239727EF924E1BF0AA8F792158D73911E4AE467938C9FD0577C2334BDFD
CE6938B6F9763DBF48FD9875AF11FC2D83C616DAD27D9E4D36EF509ADE6B6654
892DE568CA090139270587CA0751F5F0F0ED9237ED5CE081DBBF4FC4D7A5E8FF
00B4778EF43F017FC21F6BAC98F40FB3CB682D8DB40408A42CD22EE285B92EC7
AE79EB5E6F0C6D2B96FB2B3EEF4520138ACB0F1C44652F6CEE9EDE85D4952697
22F5F521918EF3F31A962B9911783D7B575BE15F0ED8EA704EBA95ADC413AB29
462E114A9C8EFDF38AD59FC2DE1A8C7CF3490E7A1F373FA00694B10A33E5E57F
77FC112A778F35D1C4DBE5E45F3303031BB3525DAC6CDFBB1B9300631DEBA7B8
B4F0DD8B6D170F74A073B0B7F80A8FEDBE138C00F1DE396C6E58F1C7E25BFA55
AACDED07F77FC12396DD4E49A3318665C81D339A7AC227F9C8E71804735D026B
5E19888DDA65C4D1E7255A623B7D7D6AB49AFE8C0916FA32AA7F0EF9E4257FF1
EC568A77DE2D12F4D8C459CDAEF1B4316E3E6E3155DE766EAE7F0AD59351B691
B747630A8CFF00164FF5A89755683E611C48474C44BFE15A5C45288CCE0ED0ED
F4E6A416178C07FA34E73C8FDD9E7F4AB327882FA41B7ED0553D1540A892F25B
CB98567B89766E505802C546704819E7E948633FB36E9177B5A4C17A731914E4
BA6863D9B882BD56ACA6A31DA44162DCCBDCCAA0E7DB6F4A8F56D72E3595B659
D2DD16DD3CA8FC8B68E23B7FDA28A0B1F76C9A1B7D00AEF73BF20E06EEA053AD
DB0E70707155861880454913E48E7F1C5302705B7019DDCF35FA235F9DF18DCE
3A649ED5FA215F5D907FCBDF97EA7CE671FF002EFE7FA0514515F5A7CE8578FF
00C4079FFE129D415217650A84326067F76BDEBD82BCDFC5F1A9F115D133321F
9380D81F7057E77C733E4CB69BB5FDF5FF00A4C8FB3E14A7ED31B349DBDC7F9C
4E0D8EA018F97B142FF13039C63AF18EF50B9D5A460B0471BB93CEEDC01E3B73
5D2CC92723CED87B93263FA5465A278CAB5EA8CF7F341FF0AFC3D57ED147EABF
56EF26738D1EBB0AAB793091DFEF0C7E66A499B59873B515D7036B0C81CFFC0A
BA38E18D93E5B90CA78255BAFEB4E636FB87F193D0EFCE7F5A5F587D914F0B07
D59C9B5C6AFB499204EBD43023F5714AB3EA0A84B411A6470C5C007F0DDFD6BA
AFF4666FB831D324D56F2962E15601B89259A3AAFAC37F649FAAC57533F5BD6F
5ED7F44934CB8903594B7115D105C16F312331A9249C1F94E38F415CBB7849EE
15A2996231B0C162E33F860D769342B2464848707B0CFF0051510B2825667620
FB1039FD2AE38B9C36D052C1529AD55CF2E9BE0E0903B5B5EAA11901659339F4
E02FF5AE5F55F026ADE1D2C6709E4B48B1A4C0F19CF423A8E327A76AFA063548
D5553851D8639ACDD67438757B79EDDD8A472F382DF75BB1C1E9F857AB87CE71
1195A6F43CFAF94D1E5E682D4E1B4AF866D67A7DC4FAC4CB6D345BD2348320B4
A0855524E703A9FC315DD7C3FB5D3D3C51E16925CDACD16B166CA230415C4E99
191CFDD9BF4CD62DCF8CE0D4B4C974ED5122D2F558EE04844F380261E6125977
632086FF00C77BE78F3CF147C467FEDFB69B497DA74EBDFB5C1708C06F70230A
7A0E07979C1E39FAD75469E2F1F3FDE3FF00238A53C36112F67F3EE7EC4E90AB
6508887CC5470D8C1353DD5D83244BBB93F363E9DFF5AF8C7E077EDD9A56AB67
0699E2D8E2D36E618F6ADDBDC6164230392DD38F53D8F24902BEAAF0FF008CF4
5F16D9C375A56A96D7D14C3E4F2E4049E32463AF15E1D6A35683E5A8AC7A3094
2AFBD0674F0DDAB839E31C1C822A513C6467703F9D634C206641308C9270A1C0
E7E99A9CB71DB3F415CEA4D1A3A6AE68C5751CC06C6C86190477A56B948D954B
60B6703D71D6B26DA0B5925DC5623B4ED27038F6A278A1DE4ED42B1F21B030BE
E3F2A7CCF723915EC6B238663CE69C4FA71546D9C200001C0E953C73EE6181F5
239A6A5DC970B6C58E011EA6A4DE327DA991A190838E2B9CF1EFC46F0CFC33D3
3EDBE20D5ADB4E889DAAB2C8033F5E83A9E9DAB68C5BD8C5B5D4E97CC1C7BD3C
0DDD0E3EB5F1B78C7FE0A31A569F73243A0F867EDCABD2E6EAEB6061EBB0213F
9915E6BAB7FC1473C6571262C347D22D031E0B06723F322BD2A780C4CD5D474F
B8E696229474723F44DB68E3BD33EF7435F9BD6DFB79788AC4C92EA924FABCEE
A17CBB4BB4B5850647DD0AACC4F1D491D4F15475AFF8284F8CEEE02BA759DBE9
D23673249334DB7E8303DFAE69ACB715276E40FACD04AFCE7E9548D818EA7935
04B2051972B1AF5CB103F9D7E496B3FB5DFC50D6A697CDF166A114721276DB4D
E5633D86DC607D2B93D4BE35F8E3550E2EBC4DAB4DB8E5BCEBE958FB7F1576D3
C92B4BF8B24BF139E78F847E0573F4CBE2DF882CA2F16E977B737F0358E9D66F
730A457291B4D316538C9CE14848D7278FDE9EBC63C7BC41F16FC29617D09B87
F0F6B91436B73A82CAF296696FAE1E569ED8615D96265982E0F5F28292706BE0
6BBF10EA57FCDC5F4D39030374849C5516BC9A4FBD33919EEE48AED8E4B4E295
E6CC1E6551ED147E82699F1F7E1259F89EFE79E7B0D1EC9248C47268DA7CCBF6
8558D4ED933180AA1C90173D17A10C2A97C70FDA6FE0EFC48F0ADF68370BA95C
A4E5655BAB3B758E45914E4105FF002391C83EA063E033297382C587B9A50247
200427E82BAE39461E2D4EEF431963EB4938E9A9EB7AA78B7C0771E15B1D1251
E20BBB7B09A7B9B778EE238C1795514E54A380B88D7807279F5C0F3CBAB8D237
6EB686E88C7DC9E45C9FC978ACC16374C46DB77607A1DA69CDA75C6EDAE04647
F788CD7AD4E9AA7B33CF6EFB977FB5ACD0A98B4F42C3B48CCDFD6A43E269171E
55B5BC78EA04759FFD96EA397C93FDD5278FC288F4C949C1591476246335A7A9
25D7F14DF36EDB285CFA0FFEBD539B5ABC6041B8701BA8048CD4CBA510C37EE5
5EE7AFF855B7D1ECDD0ECB80ADFF005C8E7F9D2D101866EA490732641A32ED90
3247A83D2B674DF0C4FA8DBDD34126F6815A49005CE1077EBFA55D874AD3946E
96E5A57C0043305DC781C0A8E78DDAEA5B8E9739AFDE718CFBE694C6E7A8F4EF
5DCDB41A5403023B693DD886CFEBC55A8EEAC55C058AD213D06C5503F3C5613A
938FC30B94A29F5B1E7F1DA4F20042C9D71900E2B522F0AEA6FB77DB32863805
980AED0DD59DC10BBE36EFB4B0C7E549F6DB693E559D0EEE31BC0AE49E2AAA8D
E30B16A10BEB23924F08DEF0595402467F7838ABC9E0EDB12B4B711C649E147F
9E95D289A3E8B22820FF007C1A5FDDB001A61853DBD3F3AE4FADE21BB3D3E46E
E9D3B68CE5E4F06AEF016E8007A965CE3F0150C9E0CBA8E42629A29137751C6E
19EFF85752F0C441FB991C1C819147947670E47FC078AEB8D7A8F5E6FC19CCE2
91CB3784AEBCE9413148C57276B7DD3DBA545FF0875FB1242AB31E000C2BA931
30031B58A8E3229E04A1001B4907A91DBFCE6B55526DE925F77FC1159763916F
085FA152A2324F6DE38A7A7856F4A61846B8E40DC33F8D75122B71B8286CF55A
9D148192A3711CFBD6F7A896E88BAB9CB5B7862F5E40008F71390322BEF8AF8C
5230A721471D4E3A57D9D5F5DC3739CA5594FA72FF00EDC7CEE716FDDFCFF40A
28A2BEDCF9B0AF2CF1BCAC3C497A001C6CEB8FEE2D7A9D790F8FF5BB0B3F155E
C32DC2C72831E57927EE29E807A57E73C749BCB69D97FCBC5FFA4C8FB6E11696
3A777F61FF00E95132667B958B740914B29E5448FB47E62B95D5358F15583334
5A55A4AAA701A390B67F956E4BE26B08E2F31A66DA393B6373FD2B9FB8F8A9A0
2A9633BC8578DA22604FAF515F8DE169D46FDDA3CDF7FE87E99899D34ACEAF2F
DC7377FF0011B5DB466379A142983825E36E7D79AA47E2B4CD84934D4455FF00
9E73956152EADF19A646234DB58D50E70F283F860022B8FD6BC6FA96B6ACB70D
1119E8A8057D561F02A6AF5A828FCD9F3B5B1728694AB367736BF166CDD4A4D6
77D82792B71BBF2C9E2A7B9F8B7A6C76F27D98EA493E385976301C7AF35E43E6
B9C74FA1A42CC4E738FA0AEBFEC8C2B77E539D663894ADCC77EBF16F55F34957
8F1FED0FF0C520F8B7AD9C05B8B707FDC27F9D70041E48CE7EB4D25B1C9C574F
F67E17FE7DA3258DC47F3B3D09FE2A6B63E6692DD8FAED3FD0D489F176FD1F73
4314847A647F5AF37299F7A78508723823BD1FD9F85FF9F683EBB88BDF9D9D7F
887C711F886DD92E6C635955488A65660C9E98E79E7D6B8E66390CB83F5A76D0
73DE8DA077C62BAE9518508F2C1591CD52A4AACB9A5B88B294E9FA5751E11F8A
5E27F03165D1758B9B08DCE5A38DF28C718E54FCA7F115CC8001CE0520192455
4E11A8B966AE898CA507CD17667D0BE11FDB73E227872030CF731EAD11508CD7
6832A074C11C77EE08F6AF44B6FF00828BEB6B2299F424D9DC6F53FC947F3AF9
A3E1378227F1AF8CB4DB14B569AC1EEA08AEDB3C451BC81377247A9C7D2BB5FD
A73E10F87FE10F8A6DF4AD3EF657D465B4B7B8B8B191495859D5B76D62391951
C649F98FA5785530B8175D5070F79F63D58E2314A97B4E6D363E8FD2BFE0A33A
2A220BBD0AF828397DA1246FA026419FC6BAB5FDB52DBC77E10F113F82BC31AA
5D6BDA7D935F133245E522823965F332C31BB217278F7E3F37238895248C91D3
DAAD595FDC59976825788C88636D8C4654F514E793E1ED786FEA42CC6AED2DBD
0FBCBC3FFF000514D160D02DD357D06F0EB0322516FB4C4707820960471ED57E
3FF828EF857F77BFC3FAAC60E7790A9C63A63E7E7F4C57E7BAE571C9FC2886CE
69E4DB0AB3BF5C0E73552C9F08BDE77FBC16615DFBAADF71FA4D27FC1487C129
A72345A46B3E71438DD6D1ED040FFAEC33CD7C5DF1C7F680D5BE33F8AEE354B9
7921B3E05BD997044402E3A8C64E73F9D709A6783754D54BAC516D58C82E64E3
19AEAF4EF85F6AEA4DE5F4AB26CCFEEB681D7A60F359C6380C0CF99CAEFB6E69
6C5E2A3CB18DBF03CFA4BE77E7A7B0A8833F0C78FAD7A9FF00C2BCD0D60937CB
3AB85C87F306073FE7F314DFF841F41B544668669B2320B4D82DF419C13F4AE8
FED6C3F44FEE23FB32BA5776FBCF2DDCCC71BB271CE2936966DA481CFE75E9C9
A169119F262D236E410EEE47CA3D4127B66A95E6936F0DE8BBB58D52E635DBB3
1F230208208C7047D7D2B4598D39351B35732782A89395D3B1C7DF59D9476160
F6EF7724CC8E6E51A101131D0A10C723079242E38EB52699A1DC5E5BABC768F2
A924EE000E3EB5F53FC42D1EC6D7E0D7C2D85EE61502D1E05B4932D92C6DDA41
B812233FBC39DF8046380735E35A978621F03EB52C415750D02E6668ACAFB71F
BEA482BC636F4CE1867183EB9E68665ED22E297BDD3CCD25827092727A753981
E0C9A0406E2D163DEB952F21DBF98AA9A8783EF163F36158F6C7D6352C49FA64
57A5AD9C0D0B08E2302370C7CD6193F4CF3F954336829BC08C4B93F7809700E4
738C8EB5C11CDA69EAADF23B5E57A5D33CEFC3BA17DBE495C4A514328C1400F2
B9C73DEB66DF42B15F9892FCE066439FC8574CBA30B57DD149769C862A1C3162
381C91E9534D75759C4B7724B85FB93057217F11FCA9D5CC27564F91E842C028
47DF5A984BA7582AAB2ED0C87E612EEE0FB1CD39EDA0909610C2A3EF066E73F5
AD44BBB8240DF6DE48C61840A1B1EFEB50CF2CAC061E062411B84446467B807F
9573AAD26FDE97E253A165EEC4CFF2E231E447183CF419E3F2A0C3032202AADC
6471D2A6585A15F9A4898E33805B07DB9E942A8DCBB0B3EDC31111CED39F5C7F
5ADE357ECDCE795096FCA65B5BC6AE63312151DB04629CB6F66586D8D473EA45
694B0150CEAAEA43630D1939F6E3BFF85470CC2538552C33FDD35E8FD6128ADF
EF385D395F629B5C269513ADB031C974444DC9C32E46475A8DB4EB2888728486
E8B927DFA629DA85A497177693EC2B042ECCE4A9CF6E31F9D59F3958EEDD8E3E
61B4820FE35B29C2E9DF57B93CB26ACD6C50FECFB591DB68DB185CED627AD31B
4BB7DD1F0D20638CAFFF00AEB49E680112ACA0B301C7207F2A7796B285FDE45B
49276B377FC6B5FAC429E8D93ECA525A23326D115612D17CB93CF522A21A1BF9
44EE55619F90B6327BF6AD94824071B4371C6D93231EBC9A7AC19C3007E5E391
D6A9E263749C912A9BB6C6247A2CA594ABE0601C83D3EB4268372020494AAB12
5B39E315D1C96328B68E605486041C2F5C718354C40577001571C657D2A63895
36ECD14E9B4B532A3D27507E56E3E6C0EB9E69ADA7EA41B69B803B7DE38AD77B
7C3963B91CF23E94D12157542D9C8EB9EFED56ABDDDEE9A25C6C65AC5AA63709
C1E09C83E9F514917F69BB49B25CBEE03939EC4FA56A185965DC03A8C72DB80C
FE153A85DAE4962C4F03AE2875A30B5968C5CB739D3777C086327DE6FE24CFF4
A905FDFB16563CAE0B00A2B785A195D5914B313D7603CFA53A4F32067054A8DD
B7952714DE2232D236FBC391AD598F69A95D4AE3E4DC7A01B6BEE6AF8BE1C34F
F74139C066C7F5AFB42BEDB87A5795656FE5FF00DB8F99CE17F0FE7FA0514515
F667CE05795F8D746B6B9F13DECB3119631B7A60844FF0AF54AF2FF1A46ABE23
BE70EA0E10905B07EE0AFCE38EDB59653B7FCFC5FF00A4C8FB7E1049E3E77FE4
7F9C4C24D12D718F2C49B80F9994FE7FE7D6A8CBE11D26E66569B4FB46C670CF
0AE7F223357BCF0EA4162A4A83B8F2704F3DFBE6A3B76792572DFBD8D0F3FC38
EA3D6BF0A8D4A91D549AF99FAE3A7097C4933027F871A14EAE7FB2EDE205480C
8369CFD0570FAE7C17910BCBA75DA364E04322ED207FBD9AF5679D0EE04B28C1
23E524363D3D3F5AA92C25DC8647991D432041E87049E7AFB57A387CC7154257
8CEFEBA9C55B0187ACACE36F43E78BEF06EB1A71FDF69D7201FE358CB03F88E2
B36E34EBA807CF6F2AE7A6E422BE96B8D3A00C55519CECC2B6E00673FEF76CFB
D67DED9DBB831C8AAAC9F282E013923BF3D075CD7BF4F3E6FE381E2CF26EB099
F38BA36082A41F7E298508EBC57D032785EDA67CCB6F6CFB012CCCA06EC9F5E3
DB02ABC1E00B09642C6182551F2AECEBDFAF3C74AEBFEDDA5D62CC3FB1EAF492
3C17146DE71D7E95EE93F827457B5632C31C40E47239FCEB9E5F02C36174CF6A
B6F71075686E5B6B2F04E4377E9EDD6B7A79C51A9756699854CAEB53DDDD1E5C
2376030B9FA54A34DBB2A185B4A51891B829C715E9714B610EA07F70B67CE161
68C3823EA4FEB5B105CE9572AEF19799E2F98A860C0104703B74F6A753339417
32A6EC2A78053D39D5CF1AB8B0B9B54569ADE48958F06452A0FE750A29601472
7D7D6BD9355BEB5D521FB39B5F3A31C849071D3D7B77AE42FF00C276193E4BB5
A82377CDCFE38CD6987CCE157DDA8ACC9AF97CE9EB0774749FB393DD68BF15F4
0BD974C3A842B7290A438F94CB26523C9C1E85B35DEFED6FA2BF8E3C79AEF8D6
D2FE39E24BB5D3AEB4D57DCD66628922F301CFCD1BBC6C03051838070586785F
81DE25D13C09F103C3D7F7B6CFACDC43A9C5B00DC91401658CA4CAC082CC0863
8231F2F539E3DA3F6BFD3B5AF07F8AA4F09F8712DE2D2353B54BFB886D91FCF9
99A476632BB33331DD1EEE081C0F45DBC75A738E3E33D95BAF6EA694E319615C
3777E9DCF30FD9E3C1B347E279F553E121E3186D6C2E99EC64B3FB4461C44427
CBB58160CC3008EBF4AE17E267C3C93C21A95AFD9DDA717502DCC96623225B27
6CEE8241CFCC84100F04820E074AD1F087C4AD6BC3692DBE8F7D7FA35E5DAB43
77736F3150F19C12063A1C86E7AFCC456D5DC9A44D66F2BCF39BC2B91E62E773
75C93DF393D7D6A6B626B61B12EA4B552EC6D4B0D4B1341463A347932E9AE7AB
449DB6C920523F035A5A75AEAB03AADAC88A32794652BF98CD74778B1DD8D92C
2AE84FCA36D66CDA34309F3AD1C4215B9466386FA11C8FC2BD6862556567A7A9
E6CA83A4EEB52449FC419D82EC919E48973F4AB826D75807FED3C3127AE7D2B3
EF45F416E8F6F2B9273887686E33EE338F7E6B206BF709BA3699BE50718F9719
EBC62B2FABF3ECA3F717EDF9776FEF3AD5935068C86D4118E31F700CFEB53C37
F3C719491FCC65C0C06DC33EDC572369ABDBA1324ED3B3678DA1703EA73FD2B4
7FE123B48143091E4DC7F800C8FE54DE06125CBA5BC90962E49DF5FBCE81B519
5E029B320AE0B467923A734D693ED37323379BE5105801213823A738EB8CD73E
7C431B1F33ED0553FE79B4796FAF6ABF79249269D23A5C2C2153702F8C1078C7
D6B09E06852B6B6368E2EB55D2C7BAFC5BD6EC34BF87DF0DF4FCDAD9DCB693F6
9942146F319847B4B211946C004E792467D2BCE5752D3F55D36F2D6F8F9D6D31
E4C2A37A30CED9532305C763C6412B91B8D79B786746D4BC65ACD9E9B6A4DD5E
DD4D15B40B21E0BC8DB631EC338FC0D7AB78EBE0CF8A7F67CD62DF4FF115BDA5
F25DDB33C53D84CED013D19371553B97BAF1C1041E6B82AE02141693F7F7475D
3C6BACED28FB9D4E7ECE6D4349BF9B4FBB9CCD3C6EC5268D8C8B3A7216446EEB
CF07D0738C55E105F148C98E5183B95A4070483E9F5AA71EACA20DC90182FADC
0FB1DDC7FF002CD7F8D187390C09C67A73C73C453F886E660337120503AE0127
23DF8AE4AB87AB27CF18DAFB9D34B114A2B9272DB62CCB617AC88CCF1A91C61E
60A7D7B9A6A68859C0FB4471444FCEC1B2DED8F5FF00EBD65199B673365F1823
A7E3530B99DED8A8959947A36493C56D1C2E26DEEB5F7112C461D3F7933A0FEC
E581A48DACEF2E15002AFF007411D327A9C66ACCB7F6F0C99FECBB88A265C00C
58AE71C1F71E9F9D605A78BF54B094F97303190176C88AC71907B8F6AB3AA78F
B58D62CE4B5B9B9430BB2B18A28634008E98C0CFEB8E4F15E73C354E7B4FF33B
96269F27EEF4F913DCEB96B24B97B18EDE44C8DEC8097E30383D79E6B327D59E
4500222A649C2205201E7B1F7AA76BBAE6755F33617F94B48C719F7ED4E974D6
50CC591C28CFCA49FC7E95E82861E9E9CBA9C0E788A9B3D0B2BADCA708B1B953
9FE2C7192700FA679FCEA44D552381956D5039E8C4679F5E4556FB18728B1CBE
6B9382A06303D6A38BC9C0640ADB38E8707DFAD428C25ADBEE29B9C74BFDE5F2
1EE15D9498C752320718FF00EB74A8BCC0D1B299B81DD4ED5C919E9496E85629
E501BC8C1DDD48E79EFD3BFE7558DCCA4EC1C671B703807B741FA528C5ECDE83
728AD6DA97D6E122678240B292C0EE6C107DB22A54960B88F634516FCE30AABD
3DFD6A0B3B07B901DC46F0C5F3B127240E00078EB9C7FF005EACB5B08D50A464
4CECAAA370FBC091FA6306A1F2BD9971BAD6C4020566DEB6A843705F6601FC71
486D546E736FFBBE01209E7F2FF3CD5994C8B0242CC5318764419C1C64002AB2
CB75081E5DC4520C95C1CEDC9EFD0FFF005EB6A7395D28B31A94E2B592266B2C
22EC0E368CB299890C0D546B445723ED1296E7E50DE664E7B1C7A54AAD744E7C
E8F6AB0460723AF008F5E69A9739856371B9724F0B8C77FBD8A1BA906ED2252A
335B0DB8D39EDE362977F313F2AF96AC7DF0323D681665D40728C4F3CC438C7A
F353B24916678785031CE09E4804FB75FD2A686EE041344C85D48DA4AE413803
38FF003DE97B7AB0D987D5E9C9DF94CF16E8ECC5846AAFD0EC3DFA6307FAD569
B4E8C6E3106752470256E7DFBE2AF48CB1ED3E62226739030768E7FA7AD37CD7
4643B573B725586391C7F4AEB8E2AB25B9C52A34BA44AB0E9D342C5B6B904120
7DA33DCF1D062A3305CDBCC58B4C1718D9205723DFAD69C45FF77CF9795772B8
C90073C671DB9A7AB845324A72C415C940D8E3AE723271C557D6A4D5DA4FEF1F
D5A1B2664DB89637512079893FF3C8823DB835F6E57C8420B47BDF2A1CABA1CC
8AE40C73D473C8AFAF6BF43E15AEEBFB76D5ADCBFF00B71F1B9F5254DD3B3BEF
FA0514515F7E7CA05792F8FEEACED3C497AF732346B98B3B7D76AE327FC2BD6A
BE76F8EF6F2DFEB7AAAC37022781149881C17062539C0EB8F7AF81E33A4AB606
9424ECBDA2FF00D2647D7F0C55951C5D49C55FDC7F9C4B76FA8585DA811DD349
B4954E7700B8EE0739EB5237976F70B1DB0E07DD2CD907F0EA4F3DBA66BE7CD2
B5BB8D12F16647942A901937115ED5A76B70EA36D6F2C520CEDE238DF956C8EF
9E3AF5AFC731D964B06D34EF167EA183CC2389F764ACCD969C5A41248C33395D
AEDB72A0F4C7AE3B0E6A91B95FB311B17F78093B948006EEDCE7D0FE3493CF15
CACD2DD38495F6B17662F838EBF5C8355D204015F7C523965C4523860AB8EEBC
E33D7915E5F2A47A3CD22CFDB2E25C92D09F2930437523B75E78CD53BABB97C9
11ACBFBA39DE5491863E98278A6CBA9952516DA24119C978D70BCF6EC08E98AC
F79DAE23557670724330C827A0C923B67A0C715B4606539EA5EBABB10EF63146
B14A4842CB905C0C8E07238F5F4F7AA8F3C28C1648F790DCAEE00AE33C6738ED
55D67786C5E3591A491C10DBB3D3A7D2A081A39ADE56BB998306388021C9C803
80381EBF415AA8591939DDD84B8D45E3918C00ED752396192B8CFE07D2AA79AF
25D4816DF68193B59F9236E3B9F4A8E79218A3022F31DF277654E0F20F5E703A
D655D5F4D36E4CCA91A82768CE3E9C7AF4CFBD76D3A7CDF09C93A9CBF1127886
D8DDE9D710210CA71B58B6ECB70706B84B5D46FB4192484FCA7243472720FE47
D315D935C346CCE0E0A0DC183609EB9EFED9AC9BBB882F2E104D0890302DF77E
6F703BE6BE9F034A6A0E1515D1F3D8BA917353A7A32BDAF8E6E0A949E2404925
8C78FEB51DFEAB0EAA22B581A4632B8DE4E471DBFAD625FD89B79491BD549E03
AE0E2AADB4AD6D711CA83254E727A5777D529297345599C9F58A8E3CB27A1F48
7C02F00E97AB6A86FB50D45ACACF4BBAB71024414B5CCBBF2376EE89F29CF4C0
35AFFB605DCEDF1EEEF575990D86A3696ED6B3063CC42211838183CBC4FF00CF
18AE2FE0FF00C7287E1F596B36D75A7C7AB69FA908A47B57BAF28A4AADB8329D
A79E4FA571BF17FE29DDFC52F12B6A5307851234821804CD208A345002827920
B176FAB1AF2E387AF3C5B7555E276CAAD28E1E3ECDDA4432DDC3BB324E1C7404
0DC001F4FC2A39754B4727330249E9D08238C7E1C8AE31647038241EC738C54F
1DDF971EDF2A3662725DD77357A9F53A77B9C5F599EC76B0DE45789888C92124
818889E9EBC7A66A492290C6C3C9742C72BE6B2A738F73FCAB8DB5D46F223B22
BB9634C1C2A1207E42B6ACA3BA9AD9BCC5336E60C32727F5E949D271F86CBF10
5514B496A5C6F36624EF8E3DE4B6E5239C7AE3AD67EA7A5C976417D8C41E3036
13F99AD6B6B75DBB9B1B80CE08C15E3D3BD3E254323F390C3E5DC3007A1F5347
B554B795C3D9B9ED139897C372C648192D9F946E07F3AA936917F64ACCD0B2A8
C82430E9F9D76724E0C6C1888E461CB13F7CF4E87AF07F4A74616645DDC851BC
13F9E07FFAAAA38A52D5A14A838F53814B99611B5802318DAE09C54E3523F669
A3DCC80E080BFD6BAC16705D8C4D0C6015FBE53AF1F4A5B5D3EC2D2D847F6186
E80E4CAC83773D067AD6557174E9ECAE5D2C3CAA5F5B163E05F882C7C3BF147C
27A96A12F91A7D9EB16971712609DA8B2AB336073D149FC2BEA1FDB8FE347877
E215AE81E1FF000C5F41AD1B577BCB8B8815CE0EDDAAA1881CED6CB63B9E7BD7
CA7069DA7C504CB369B2B17036142015CF7CF3E9D3BD58F0B6A0DA15E2CB6F62
642B1C80492CB84C9E8C40E7819EBC13C73D2B8AAFEFAA7D661BC569B599D304
A09519BD25EA6541AADC884ACAC368277151C8E3152ACB011BE47D9BF952DDCF
F855F16888DBE68D212CDB4EC25B3DF3838F5F4FE54F4815E56728CAAA086655
C83F5F6AED8E321B5B539A58693D53D0A86EA0879DE02367E623AF3EB57D801B
8672F9E02F7F7AABFD9904E5A558A264420B7C83180707B7AD5C8B4F8D625650
AADB80194C76CE00C834AB62E3043A785949E80AAD2236E4270393C75CD39008
9807760CC72772F51F80A70851DCABBAA7CC72D8DC339E7F9D244D1AEE20215D
BF7E53803A703A0AF3962A76B2D579AB1DCF0D15BE8FEF196F72B09DD8562581
2700B0E4743531BF73E71180ACE18B2707FF00ADF85425A5C49E5C0F288C6772
8CF155FC8BAB9D92C21C444EE29246573D38C9F4AD65469CAD2B2BFA9946B4E3
78DDFDC68B1BAB9550DBA5407E556C001BBE3A77A8DE3F29D1670C8AA39E7951
D33EFD2AE586AB6AB6AB14B68A658C00C15C60FB818F4FC2B720B6B49DE397CC
8920CF98E91804E31C7E23EA2BC7A95A5426F9A1647AD0A51AD0F7677672C251
0412A72B92A73212700673EDDAAD19C2A2C6268DE242307700725B24805466AC
964BBB865DE6587948D980CEDCF1C67D31DFAD51BDB4DAECF129F293F76AC13D
39E41EDC7D73DEA9495476D88941D357DCB9E6991AE4C32978514EDCA907A7E9
4C610DB3B04C2EF1B327A2FA76E983496B6ED6C162136F5196760A546EC9E0FF
007BEBCF150DC8C0930C51D64F28C4C7A77241E8141FFD0AA54573593173CB7B
0493EC11962E58AED2CA7A9CE3038EDC73D2AE5F482EA38FFD5C92150C5D1085
EB820FD31FA9EB54E25324522B18E38914A8DE013D73D077E4F38A2DC1370ED2
1170E99077B00AC39F5FE5EDEF55C9CAEF7D84E7CCACC8504519F421C01B4900
F3562DE2B769C462532C2C4F0AA37633DAA76B2F36069D02A3AED53108C90C4E
7182075E9515A3C36F77265567895768DC3209EC7FFD75BFB47383716CC79146
49489627582EA30798DD118876C871BBB8ED5214C894A602AAB1217079F4EB9C
7CCA7D7D8D50B9B196D6E86E8B11B60E5B80C3BAF355AE6536D33322EF2A5B85
5E18707AE3DC510C3B9D9C7514EB28BB32F86287E748D37295DCABC938C01D7D
71515C2CD2CD856862546D84B82493DB23773C6071C7158B3F8A552EE6DD68EA
AC3EEB36E2BEBF36067F2A67FC25277FFA82405001671CFB6307F9576430756F
F0A39658883EA6FBB4E23DAE41645C829C03F5F6A92DC4B184C2207008E49F9B
93CF38ED581178A02E330CAA0A91B84801F4CD49078AE3501591D48046472304
E718A52C2D56ACA2888D6A7D646DCF235F95592389D530836AE0F6E323AF03BD
7D975F127FC241672DC6E432AB71862A0F7E49E7DFF4AFB6EBEFF8563387B652
56F87FF6E3E4B3E716E9B8BBEFFA0514515F7C7CA057CCDF193516D37E216B6E
64C46CB12950A391E4A6473EB5F4CD7C85FB484928F891A828C18F6C6718FF00
A631D7C9F125255B0B08CB6E75F948F77269CA15E4E3FCBFAA3CDB57D422BEB8
9258A3F289C671C03F856C7863C64DA4C5E54A098F2394033C11DEB9493B8078
1E95174C7B57C454A10AB0F6735A1F5B0AB3A72E78EE7B3D978AED35290A0B98
C195B0A9329278270013F5EA6B6E68DA38D3ED3E64842919545287A9E08C1E87
F4AF9FD6468CFCA704F5AE9743F1BDCE98EB14C12E2DC0C10E093EBCFE55F3D8
9C9EDAD167B74733B3FDE23D62FEFE19BCA04C726F2079A80807039183D31C74
F5AA21E6B6826883794B7077317E72B918CFA00476ED54F4EF1258EA30214113
60F2C3232D81918FA8C8E9D6B46EEFA2661FB8196564250E485C60F19AF02709
527C9289ED4271A91E75220BF82EACE0FDE29DAA03A148D88C9EC4903B67F953
D356B0B6B72B133C65D865D8293EE00CF039FF003DB3EF6C85C7DA552DCA6C0A
773918C7CA4F03A5644F6215E41E72A04043060473D31D3FCE6BA6951854D2A4
AC73D5AB386B0573526BEB355BAF91A491F3870FD07B8E9592C92797872A8CF8
241C96E07238E00EF4D160700B3346BC7CCA739E7D6AC5D5B94FDE46ECE525D8
0F2198E09C91DB8078FD2BA7D9C60ED177B9CFCF29EB256B1476B202383B49C1
1E846381CFE755AEB4C17089F2ED68C67710011C71DAAD85168CDE682189C0C1
3D4D3D674918F9283E7000561C60F031CF5AEFA73AF875CD6D0E29C29567CB7D
4C06D26EDDD8ACCA703F886EFE79ACE9B459C306650CBD320633F90AECCDAE11
8BCC727858F7723DF3D3F5A8A380395F2812F9C0040604FF00915BD3CCA5D519
D4C025B3388934B612BB052A99F941C9FE952DBE81248A79DA48CF3C6071FD6B
AF74704630324E0A63D79FD6A6861F330ECFB70A7014139E7A1F4EA6BAFEBF0B
5EC72FD4E57B1CC45E16548C9965048FEEE79A95BC3117988C8CA63DC376F620
91ED5D1AE9D3334AA14EE44DE411CE323A7BFF00F5EA6834F49602C15DDD7AA9
700E4FA570BCCA4AF73B9601492B1CB45A2CD6BCC72A16195D8CA49FCB15AF16
5389368DC39118F4E833DAB73EC682D43222A994ED232307FC9E3F0A6CB612C7
725238C82880938E075078FEB51FDA7CFA343FECFE4D6E66451B61F8DAA1720E
3B7BFF00F5F35612009B83047DAD86284FDE00F4231FE15A0D6331B489E44370
5F76CD840E5783C039C0CAF51DEB3ED2E648249640C25908E30A09E473D73C57
0CEB4AAA6A3B763B214A349A72DC49AC966512EC432000AED1C81DF839F6A79B
5105C10ECF86DDE59C0E3EB4DBD94CB72AF1AAC3105C2B74C95E48FE553CFA66
F586412A29754662A0009C93D33E98FA77E734BDF8A4A521DE0DDE312B4F69FD
9E617F29D836460AF1C1C1F5A4DAB2664810B9380599471D3238EB8073535D5A
476ACD3ABA480BE3CA200DD8E3A672BCE47E19A82791AE59A5197DA022CBB724
83C0CFE06B5872B777A98CB992B2D2E25ACB13CAD6F2F0D21088C58200C78079
C71C7EB50451196545E1998A83950063A559589D9A4B728B2AAA3643920A9E73
83F97B7351F9490BE106FE78C019E01EE00AEC8B8544E31EBF71C9353A6D4A44
CD72D1890191642ADB971FC5EBB723D31CF6C1E0D32F9E57B87925C24B3012B6
7E5273CE703D734492B02EAC707031C761D09F5F4AAB7EEB630AC92379A18826
340414604F19E9DAAE9D0707CBD5933AAA4B996C87B7976A1951CC51BB2E4B26
09E39E3E618E6B462F0FCAB1346248C21625402C437182338E0F4E87FF00AD41
6D8CF0643165033CB60E31D7D7D7F3A974CD65BCE1142E123DA77311C803000A
2BA9F25A9BD63B85070E7BCD6E5B1E1B9F23132C790799471F98EB8C8FCAB42C
7C1D7376CF1A845641B90B36E523A1E71D79E383F854B3CF6714059EF259A631
1F91549DAC077CF6C01DEAB5A6B777713476E15CB26408A03F3723A7208EB83D
2BC59D6C4D48E9A1EBC2961E12EE4BA8F84C69EB3CD24E0F960E18E30BDCE71F
EE9ACBB767B630428C0BB9C86DC70471C0E71FCA8BEB98DB7CDE598959D99915
980031C819078C8C6724E41ED515CDE09E05E64453C649C80B8C0EDE98ADA9D3
AD38AE6D4CAA54A5193E5562492DBCA79942E245C2A9520E41C639CFA5320BC9
7CA96359083B76E31C7AFE3514FAA468E1A32BE531DE57B67271EDF955AB996D
599A449408B79DEA10A888F755CF60D91F85743A7251F7E373994D737B92B0CB
7B8805C441F610E0AEE72418CED2BC60FBE7D38E94C4F35D43A15951F2429182
4038E476FCEA586CCBC3324708BA9A53B620DBB763B9182067BF43D2AA3C292A
9C3EEDA41C871CFB0C71E86851A737EEE8C5CF34AEF5572DDD5D19644940DBB3
0A41E73F51531B816EAE8F23AF9B11320DAA49CAE483D703AD67C56B39FDF6F6
F25495382300F1E9CFFF00AAA68C348EC91FCFB881BBCBEBDFD3BE289420D7B9
AE81194EEDCB4B8A079C810304203162EDC1E323F98A4650B23163B5C13BCE3B
74E3FEFAF4A96CBECCD342B26F9613869154E0B28C9C03D00C9EBD69C6E54895
09F3266607733F0C060F24F707359CB9AFB685E9DC895A38C81B648919FE6C31
E49E8319EBD3F3A6992341B15B729604B4AB80DF503BD58374F1A344CABB78C2
BAFB0C74FC2A95D03777124B14C85994E3236EF391D874382D9EDF28F5E75A29
B7AE88CEA3B2D1DD963CBF3D565493E4F9A2F9810F95009257A7F101D7B511DC
0B7B59308C9BDB3E675523691CE7F3F6C554FB4B2A64796A158056E981D71F99
A984ED2C21BF74C4002460BD0A827F1E335BFB376E5EE63CEAF76B50D5F4D82E
6EA53B56E5F183205C64E071918E3F2E307DAA84DE1DB4604799B64750CA8339
5E4F5C8F6EC7D2AC0DC92F9818B4AA38700FBF38FD33D2A769E64F32350AC1B2
43162307803AF24607E95D119CA09462F630718CB56B739A7F0FC8B82245FBD8
00FD7FCF3493681796D82F1FBE1793D715D5447731139C2BFDE907451EA31DBB
FAFB52ADDED815428C2EE5E99619E7D8574FD66A2BE9B187B28F739286DA5499
55E3646CF0186335F7ED7C7765243E746D2C6F2C6802811F2CCDE80F23BF7C57
D895F6DC335FDABACAD6B72FFEDC7CBE794FD9FB3D77BFE81451457DC9F2E15F
217ED2196F88DA892372A797F86618EBEBDAF973E3CE9F1CDE3AD54C930CC862
0AA00C8FDCA7EB5F2FC4338C30D0E6EB25F933DCCA22E55E56FE5FD51E10C495
3903F014CC55BBCB74B399D086C83D0E01AACEB8E718CD7C61F52370307939A4
24E7827F1A503271411838A00B3617F2E9D3A490C854A9CE4122BB2D2BC54B7E
B12C876CAAA54AB364313DC57079E40A92D26F26E627EC1AB96BE1E9D75EF2D4
DA9D59D37EEBB1EA6DA8CC142AED27A82EDC1079FCF38A57D42CADCA4AE12512
7CAC17A03EFC1FE46B1C4B0DCC71A062D20FBBB471CE08FC314EFB1465523690
119DCC00C07C743EDDEBC6783A4DF24B467A11C5D48FBC9DCD1D675696FF0063
468FB2388AEDDF8C000740074FE7D703A545A6A417CB1AABB4AF33641E980381
C9FEB59893B5EC8D6711585C7CADBB04953D871E940D9A7CC1D98C81D08C440E
E661FF00EAABFA9C634DD35BA2162E4E7CCF636E4B08D43AC6ACE3824C63247A
5528E06FB401B24553F292411C1E39C03C5269BAAB59DD40F09311766645EA40
E38F4EE783E955EF356964BC65C347248C5C1C643F3C0C74FD2B9961F10E5ECD
BD0EA588A1A4ADA9AF118EE2F2D81966B744383217385E9CA9033C0CE7145E0B
69A59DD992358D9488608B01C8201E0703819FFF005D4371AA5A0B48F7C251D0
FEF06FEA4F4E3D7DE93EDA2E1248810A665F3182A8E4827DFD0E3AD79EE8D48E
B6D0EF8D6A735A3D44226B992344C44B2105780AB8EA73EBFE714F0ADA63322C
8B741FEEB28E71EDE83A9C8F5A2758E4658C65443F27EF23018AE4E0633EE055
A6B75B98BCF66916D8B10913004E00C90791EBD7EB50E5A599AA8EB72B4B3BC1
B62365246F93BFCD5C3F4E410474E9D6A5B3BE68412EE530300AB939C0C638E9
8EB53BDB5D5D9797E66553B643CE41230BF51F2FE9CFA9CFFECF96091972AA1F
F80F5E9F4A57838D983E752BA2FC77B0C376278E147488392A464376E07193CE
6B3CCCF3CE726511B29186C9C9C9C63F1153CC24D3E411EE32104731E1D7919F
6E69239192E4CD6F1FD92188B79796DEC83D0E7BE1A9A515A89B93122D45F4F8
ED24059B12F9C006DBF30C8391D7BAF3C75A4731BB45284283231963C0C1EA71
EB8E7A7AE29F6DA8ED5088A92DCA969219B27E401B781B4FCA791D31D49EB552
7590C8B75CCBC81BD000AB8191D3D0FAFA56B14D36D6865277567A971E3105C7
92D2B075E111D4E428036B01EE0B720E3AFAD3E38E091E2B789D6DD848489241
F2E1B20F23EA0E7B605676A1797179712CF3BF9CE5880EDCF1D87F4FC29AB782
38F323A92E028C67803F950E9CEC9846A45E869CF34B132A6C59C49200FB5762
B76519F4181D6A9DC5D148992289AD8B10DB33B86411CF61D571F9D0F709247B
CC8C991BB61C70463D473EB4497F1CEA46C60A49C6E1CAE075273EB9E2A629DF
5894E575A488AEA592E2E0C84A9690E762600C9EABB7B73F854710C96FB9C654
EEC7CBEFCFD29D2CF6AAD18DB9914E370391BBF0A92D23F3165509E52B65B713
D873B79EF935EBD19C210B463F79E6558CA72F798C73E6397244B2B7CCCE5B2C
09EBC1E4F24F153269E353B398CD22245144406036EFDA01038EA70DDEAA18E5
8E40D90AC3A2A8CE463DF9EF56A31035BDCE0AACE5E358E26C0DAA739C9EB904
2E38E73DB158D5936F99174A292E5667A69D234B13432384400F97B7A1C9F4F5
38E0FD6B42C6C9EEC88ED7FD63863804A97206768201DC79E83F4A83799E20AA
7684701304E01E73D07F33C55A10B585AAC65912511B6E8D7FD62838E49E392A
48C73D3DEAEAD59CE293DC885384657E84CDA74B1DC431C8A97C18796D6D1019
036AF2DB4E472C3E53DC7B1A2557B46598AEE56428D1C885B610D80BEBC000E7
A7359AB76197FD103A248422618EEC7CA01CE39078FC3152DCB3DA46CD25C172
B1655A12339238C9F973C9209EBDF9159C69CD3D6D62DCE0D697B9993DEDCF92
66C48EBBB0EFCBE32327DBBF526AB48D32DC44A5AE2DF001DB2214DEAC382727
818ADADC82011B1760318B794E763100720F5C8C71C7E946A57CB14B03ED2C92
801839E840191903EEE7207B015E9D29C92B28591C152117EF731952CF716CB0
EE44B8DC701173D3B9C74FCAB56CA1924D39DC653037379C0818271D7B7B7E35
53EDD0482448D51573BCEE51955C72054995BC9161B492E24DD1011B4898C292
0E700919C67AD2A9CF257E5B5822A2B4BDEE59B6B5921B38E46911911CEE4798
6E5C81D013CF43D2B42CCDBDC23BDD4B1C4214660C623FBD6DC00552BD4F5F4C
63DB9CABEB8786FE6540123766033F316C1C827D38C715656243E518672DB943
2A8539CED1EFD8923F5F6AF3EA4135CF7B37ADCECA73B7BB6BD89AD76C644CD3
C3B1B2BE4B315DB80339E7A73F9E6996EB2804C8A10AA890190EC38038C1CF1D
3A8A8ED9E145072BBD982813C6082BC9E7F102AF433C6113CF66D913A4691B61
C32F560318C60FCC3271DB38E6A2A4670778ABA2E1284B47B94E2BBD82256D93
B60828492DC83C91E83D7F3A5D6B4F92C19E17006CDA1E485D645C6376032920
8C1F5F5E98A2ED22BA9DE08E01247800B300AE73D7BE303071CF4EBCD476B712
4103473AEE6FBE250BB768C72000718F9875F7C56D16D72C9233693BA6C82DE7
67F31844AD1AEC0AD9E5F7138C7BF18A21994491E54C46493AAA938193D80EB8
F703DEA2368921972ECADBB72ECC1C1E7F91CFAE73486378FCBDBCB0C8D88338
03A1FCB8E00AEE71854BA3913941A6694EAB32B3328599372F99090096CE77ED
E31F7B1C71D703A93456D3CB68DD9FE6EA411B001DFE5FE59A78558E52932E03
AB6D009DA491DCE727A0CFE156EE6486EAE77AA931C98C2A64800606DEBC761F
81AE6BCA92515B1AE937CDD496D6D195616CA448CA3649BBEF11D470383FFD71
55DE21E41334996FB8E84FDDE077CF20E7D7B52078F4FB7690C25C2A8F981CAA
9208CE01EB923F2EF5104B8BAB531878963405F3201920ED03EBFAF43514E9CE
EDB7A173A91D125A8F36EE232DB808F8F900C103B71EA471C53E169ADCDB3A2B
2C9B82F03209EC00C64E7D08E4D43725A631214190BC00777DCE3775F6CFBE68
730F99FBB6662DB5CEFCE4608F4C739C74AEAD64F95F5399D96C5AD3E478D15C
B1840EA54ED1CF6E3F0E074AFB3ABE2EB5B89205887FAA20860F8C3A73DBB8CE
3D4D7DA35F6FC2E9A75DB56F87FF006E3E5B3C77F67F3FD028A28AFBC3E582BE
65F8BFF2FC4DD5B69DAE447C81FF004C631F9D7D354578F9A65FFDA54151E7E5
B3BDED7EFE6BB9DF82C5FD4EA3A9CB7BAB76EC7C1FE26D25AE4FDA20527E6F9B
7115C9B295EBD6BF4728AF1A1C3CE11B3AD7FF00B77FE09EABCE2EFF0087F8FF
00C03F3881C1A462C4038E7D6BF47A8ABFEC0FFA7BF87FC127FB63FE9DFE3FF0
0FCE0F9B3D699939F7CE6BF48A8A3FB03FE9EFE1FF00047FDB1FF4EFF1FF0080
7E79693AB4B6F22249CA0EC30307EB5D535F85B7DF3F136EF9421E0838C1AFB8
E8AC6A70DC6A59BABB7F77FE0971CE9C6F6A7F8FFC03E10B0DF6DAC472DD9203
1F918A823AE067BE2AFB6985AF2495A5729290CB1B7CBCE31C1ED5F705149F0E
372E68D6B7FDBBFF00DB13FDB3A6B4FF001FF807C350DA245024313EFC038DCB
C9F7CFE7F9526A17D35AA43088B743146B1EF206554B707F139AFB9A8A6F872F
F155BFFDBBFF00047FDB36DA9FE3FF0000F886E1A79AE21589FCC5C6C5DDC724
E793D3D6ABDBDE2C76FBE270B2601651D88E0E3F3FD6BEE6A2A3FD59F7791D5D
3FC3FF00DB14B3AB3BAA7AFAFF00C03E206D5239AEA691D4C71C68005319C2E7
23818E9D455AB5D7A58DE5C2060EA3792B9741F43D3EB5F6AD158CB84E8C959D
4FC3FE09AC3886AC1DD47F1FF807C491CD74AF98D95F6315428C118679C1C9E4
F39A922D6A19DA4B26203290AE7049761E87A77EBD2BED7A2B37C2145FFCBCFF
00C97FE09AAE24AABEC7E3FF0000F891F51BCD37538A12233E59C962FB8B2609
2719C8FA915761BE8ECD1229DDC87600143F3127AF6EBFE15F6751532E10A724
93ABB7F77FE0847892A46EF93F1FF807C70D0047966B57DBE585FDE29049EB83
D2AA4B22B5AB468E1897DCE180C9FA30AFB4A8AE78F0659EB88BFF00DBBFFDB1
D2F8A2EACA8FFE4DFF00DA9F135C413424ACCACAE7183E98F6FC6886EED239C2
DE4936D380A96F8CB1C8EA4E7B13F9AD7DB34575AE14E92AFF00F92FFF006C71
BCFF00B52FFC9BFE01F132CDF6A5D90805E44C0DA30703A8E0E38C60D59B12AB
78AFBDD510962F0AF201CE7AF5EBDFD6BED0A2B2FF00545ADB11FF0092FF00F6
C6AF8893DE8FE3FF0000F8A4DA5CDD799343E6BDBE586FEA42E40FEB4E590584
B3A461E1206D2546180FC791DB9FF1AFB528AD570A492B3AF7FF00B77FFB621F
102BDD51FF00C9BFE01F1444B66B672348DBE42A3089F2856DF8E7AE78FA539A
53710A46771850E234279C6E63EDD4B1E9EB5F6AD1511E11517775EFFF006EFF
00F6C54B889B5A52B7FDBDFF0000F89C45E5803EE1070170724E09E47BF4E3D6
AB998D9A72A5783975E4F3DF3DBA8AFB828ADA9F0AA8FC55AFFF006EFF00F6C6
53E2072F869DBE7FF00F88032CC9B368C0CC83008EA01FA5491DEEC63140CB11
674768C06752768C9C2F504838F406BEDBA29AE168DEFEDBFF0025FF00824BCF
E56B7B3FC7FE01F162A2BDCA858B7A34659557804ED2DFC5D00232727A7D0623
8AC23BB85DE77751B0B2919C4846303A7A6327DCF7C1AFB5E8ACBFD546BE1C47
FE4BFF00DB1AFF00AC09EF47F1FF00807C29A868F1854B99032EEC82F1B0EBF4
23D6A85AC5A8589FF42997F78490B26148279CF6EBC74F4AFBEA8AEDFF00575B
872CEB5FFEDDFF00ED8E579D2E6BC69DBE7FF00F8421B86BE94A5CC4472AACDB
4E0B0EB83D3AFAE6AFE9AD25AB347245BD53A397DC48EA78AFB828ACEA70CAA9
0E4F6BA7F87FFB62E39E38BE6F67F8FF00C03E2CD46D8DBBB6E5F9BE5DCC3683
9C9F41CF7A7D9F98C2DA6B68D6E64447BA1991419147CC57923070A4E07383D0
9C57DA14573C7851A8F2BAFF00F92FFF006C6AF3FBBBFB2FC7FE01F155D5CDDC
F68B195591645693318504FF00BCC79FC2A38AD36FEF9E4101888458D0025C74
C8E3A0C0AFB668AD23C2FCBA2ADFF92FFF006C43CF6FFF002EBF1FF807C4AC52
667318915C2060AFF8E49E3D85356E17ECECCE84A05F9198672783D31EBD3FAD
7DB9455AE184BFE5F7FE4BFF00049FEDDFFA77F8FF00C03E29B9CC719DC892B8
2BF2AF2776471DFB13F8D2188C325C0DEF19E8125CEE5EBF293C64AE08E2BED7
A2A570C34ADEDFFF0025FF00ED83FB73FE9DFE3FF00F84E7D46EA39B60104CCA
3764FDD638EC734EB2D7A6B797FD26D6370571C00CA01FC4D7DD5456EF86A125
6753F0FF008267FDB52BDF93F1FF00807C3EB772CF2111C6A6346E323AA93D7E
B5695A12C19A2DB1E7734FD5B2A3BFB7CA6BED6A2B3970C45FC356DF2FF8252C
EDF5A7F8FF00C03E399A17B6B9579230AD20DEA5970483DFD474AFB1A8A2BD8C
AB2AFECCE7FDE73735BA5AD6BF9BEE7998EC77D75C7DDE5B5FADF7B7920A28A2
BE80F2C28A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A002
8A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A002
8A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A0028A28A002
8A28A0028A28A0028A28A0028A28A0028A28A0028A28A00FFFD9>
%%EOF

View file

@ -1,250 +0,0 @@
%%
%% getstart.tex -- Flight Gear documentation: Installation and Getting Started
%% Chapter file
%%
%% Written by Michael Basler % Bernhard Buckel, starting September 1998.
%%
%% Copyright (C) 1999 Michael Basler (pmb@knUUt.de)
%% & Bernhard Buckel (buckel@wmad95.mathematik.uni-wuerzburg.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: getstart.tex,v 0.20 1999/06/04 michael
%% (Log is kept at end of this file)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{Getting the engine: Installing \Index{OpenGL} \Index{graphics drivers}\label{opengl}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\markboth{\thechapter.\hspace*{1mm} GETTING THE
ENGINE}{\thesection\hspace*{1mm} 3DFX UNDER LINUX}
\FlightGear's graphics engine is based on a \Index{graphics library} called
\Index{OpenGL}. Its primary advantage is it's platform independence, i.\,e., programs
written with \Index{OpenGL} support can be compiled and executed on several platforms,
given the proper drivers having been installed in advance. Thus, independent of if you
want to run the binaries only or if you want to compile the program yourself you must
install some sort of \Index{OpenGL} support for your \Index{video card}. Naturally, you
can skip this Chapter in case you already did (maybe for Quake or some other game).
Unfortunately, there are so many graphics boards, graphics chips and drivers that we are
unable to provide a complete description for all systems. To give beginners a hand, we
just describe what we did to install drivers on our systems, which might be not too
exotic.
By any means, try getting hardware \Index{OpenGL} drivers for your system, which is
exemplary described in Sections \ref{3dfxlinux} to \ref{3DFXwin98}, resp. If you are
unable to locate any such drivers you can try software support\index{OpenGL!software
support} as detailed under \ref{softrend}.
\section{\Index{3DFX} under \Index{Linux}\label{3dfxlinux}}
%%Bernhard, 21.02.1999,25.06.1999
An excellent place to search for documentation about Linux and 3D accelerators is the
{\it Linux \Index{Quake} HOWTO} at
\web{http://www.linuxquake.com}.
It describes all the following steps in an in-depth fashion and
should be your first aid in case something goes wrong with your 3D
setup.
%%
The \Index{3DFX} graphics card is a quite popular one (We tested
the \Index{Voodoo}1 to work). At first, you need the \Index{GLIDE}
library installed. Grab it at:
\href{http://www.3dfx.com/software/download_glidel.html}{http://www.3dfx.com/software/download\_glidel.html}
\noindent
and install it.
%%Bernhard 21.02.1999%%
Be careful, you need different Glide libraries for the different types of VooDoos (I, II, III Banshee).
%%
There is even an install script included that will do things for you. The canonical place
for \Index{GLIDE} is \texttt{/usr/local/glide}, if you prefer another location, you'll
have to edit the Makefile for \FlightGear by hand. Be sure to read and understand the
file \texttt{/usr/local/glide/README}. Next, you need to install the \Index{MESA} library
version 3.0 (or later). Grab it at
\web{ftp://iris.ssec.wisc.edu/pub/Mesa},
\noindent
unpack it and run
\texttt{make linux-glide}
\noindent
in the \Index{Mesa} directory. Follow the instructions in the \texttt{README} file, take
a close look at \texttt{README.3DFX} and play with the demo programs.
Besides these, you need the \Index{GLUT} library version 3.7 (or
greater, aka GameGLUT) installed. Grab it at:
\web{http://reality.sgi.com/opengl/glut3/glut3.html}.
\noindent
Note: Glut-3.7 is included with \Index{Mesa} 3.0 so if you've already grabbed the latest
version of mesa, you should have everything you need.
%%Bernhard 25.06.1999
For the lazy of you, there is of course the possibility to install the 3D stuff included
in your distribution. At least \Index{RedHat} 6.0 and \Index{SuSE} 6.1 are known to
contain all the necessary stuff.
Finally, some more notes on the behavior of \Index{Voodoo} boards:
Your card comes packaged with a \Index{loop-through-cable}. If you
have only one monitor, then the Voodoo will take it over when
used. This means that all the applications on your desktop will
continue running but you'll only see the \FlightGear screen. If
your window manager uses a focus-follows-mouse policy, don't move
the mouse. If you lose the focus, there's no way to shut down
\FlightGear graciously! Better solution: Use two monitors, one for
your desktop, connect the other one to your accelerator. You'll
then get a window on your desktop which manages all keyboard
events and you're still able to see your desktop.
Running \FlightGear under Linux using a 3DFX accelerator board is
somewhat tricky. Most of the boards behavior is controlled by
environment variables.\index{environment variable} The two most
important are:
\begin{itemize}
\item{\texttt{MESA\_GLX\_FX}}: When set to \texttt{f} rendering will be in
fullscreen mode,
%%Bernhard 21.2.99
\texttt{w} will perform rendering in a window at a significant speed penalty.
%%
\item {\texttt{FX\_GLIDE\_NO\_SPLASH}}:
When set to \texttt{1} the rotating 3DFX logo
won't appear. For a description of all environment
variables\index{environment variable} for VooDooI/II have a look at
\href{http://www.bahnhof.se/~engstrom/e_3dfxvars.htm}{http://www.bahnhof.se/\~{}engstrom/e\_3dfxvars.htm}.
\end{itemize}
This completes preparing your \Index{3DFX} equipped Linux PC for running
\FlightGear\hspace{-1mm}.
%%B.B 21.2.99
Now proceed and install the support files as described later in this document.
%%
\section{Rendition Chipset\index{Rendition chipset} under
\Index{Windows 98/NT}\label{renditionwin}}
This Section serves as an example for installing \Index{OpenGL} drivers under
\Index{Windows 98/NT}. The \Index{Rendition 2100 chipset} is, for instance, included in
the \Index{Diamond Stealth II} card performing especially well in somewhat weaker
machines.
Diamond itself does not provide any \Index{OpenGL} driver support for that board.
However, Rendition, who make the graphics chip, do. Go to their Web site and grab the
latest \Index{OpenGL} \Index{Windows drivers} from
\web{http://www.rendition.com/download.html}
\noindent
Follow the description in \texttt{readme.txt}. We recommend making
the drivers the default ones by copying them to
\texttt{$\backslash$windows$\backslash$system} (which avoids the
hassle of not being sure which driver actually runs).
With this step you're already done.
According to our experience, so-called \Index{mini-OpenGL} drivers
provided by some manufacturers for making Quake playable do not
provide the level of OpenGL support required by {\FlightGear}. At
least, Rendition's \Index{mini-OpenGL} driver definitely does not.
\section{RIVA TNT Chipset\index{RIVA TNT chipset} under
\Index{Windows 98/NT}\label{rivatnt}}
Because of its high performance, the RIVA TNT is one of the most popular chipsets today.
The \Index{Diamond Viper 550}, ELSA Erazor-2, \Index{Creative Graphics Blaster}, and
more cards come equipped with this chip. At least the default Viper 550 drivers are known
to us having native built-in OpenGL support making any add-on OpenGL drivers obsolete.
Similar things should apply to the other RIVA TNT based boards. In any case, NVIDIA's
reference drivers being available from
\web{http://www.nvidia.com/}
\noindent
do the job as well.
\section{3DFX chip based boards\index{3DFX chip} under
\Index{Windows 98/NT}\label{3DFXwin98}}
The \Index{3DXF} based 3D add-on or 2D/3D boards are perhaps the
most popular ones today at all. \Index{3DFX} made Beta OpenGL
Windows 98 drivers available on their Website at
\web{http://www.3dfx.com}.
\noindent
From the main page go to \texttt{Develop 3DFX} and further to \texttt{SDKs and
Demos} and grab them there.
First, make sure you have the file \texttt{glu32.dll} either under
\texttt{$\backslash$Windows$\backslash$System} or elsewhere in your path. If not, install
the MS OpenGL kit \texttt{opengl95} available from Microsoft or elsewhere on the net
(which by itself only provides software rendering).
Next, locate the file \texttt{3dfxopengl.dll}. in the 3DFX driver package, rename it to
\texttt{opengl32.dll} and copy it into \texttt{$\backslash$Windows$\backslash$System}
overwriting the file with the same name installed from the MS kit. This should get you
going.
\section{\Index{OpenGL} software rendering\index{OpenGL!software rendering}
under Windows 98/NT\label{softrend}}
If you have an accelerated 3D card, it is highly recommended you
install hardware \Index{OpenGL} drivers for your specific card.
However, in case you are really unable to find such drivers and
want to try \FlightGear despite this you can install SGI software
\Index{OpenGL} rendering. For this purpose, get the file
\texttt{sgi-opengl2.exe} from
\web{ftp://ftp.flightgear.org/pub/fgfs/Misc/}.
\noindent
This is a \Index{Windows 98/NT} self extracting installation
program. Install it by double-clicking in Windows explorer. The
package includes some demo games you may wish to try by invoking
them from the Start menu.
%% Revision 0.00 1998/09/08 michael
%% Initial revision for version 0.53.
%% incl. Linux stuff from b buckel
%% Revision 0.01 1998/09/20 michael
%% several extensions and corrections
%% revision 0.10 1998/10/01 michael
%% added 3dfx stuff from b. buckel
%% final proofreading for release
%% revision 0.11 1998/11/01 michael
%% Remark on mini-OpenGL drivers
%% revision 0.12 1999/03/07 bernhard
%% Complete rewrite of 3DFX/Linux part
%% revision 0.12 1999/03/07 michael
%% Added Riva TNT Win95
%% Added 3DFX Win95
%% revision 0.20 1999/06/04 michael
%% corrections of links
%% revision 0.21 1999/06/30 bernhard
%% updated and expanded 3DFX/Linux

File diff suppressed because it is too large Load diff

View file

@ -1,126 +0,0 @@
%%
%% getstart.tex -- Flight Gear documentation: Installation and Getting Started
%% Chapter file
%%
%% Written by Michael Basler, started September 1998.
%%
%% Copyright (C) 1999 Michael Basler (pmb@knUUt.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: getstart.tex,v 0.20 1999/06/04 michael
%% (Log is kept at end of this file)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{Preflight: Installing \FlightGear \label{prefligh}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\markboth{\thechapter.\hspace*{1mm}
PREFLIGHT}{\thesection\hspace*{1mm} INSTALLING THE BINARIES}
\section{Installing the Binaries on a Windows system}\index{binaries!installation}
You can skip this Section and go to the installation of scenery in case you built
\FlightGear along the lines describes during the previous Chapter. If you did not and
you're jumping in here your first step consists in installing the binaries. At present,
there are only pre-compiled \Index{binaries} available for \Index{Windows 98/NT} while in
principle it might be possible to create (statically linked) binaries for \Index{Linux}
as well.
The following supposes you are on a Windows 98 or Windows NT\index{Windows 98/NT} system.
Installing the binaries is quite simple. Go to
\web{ftp://ftp.flightgear.org/pub/fgfs/Win32/}
\noindent
get the latest binaries from that subdirectory named
\texttt{fgfs-win32-bin-X.XX.exe}
\noindent
and unpack them via double clicking. This will create a directory \texttt{FlightGear}
with several subdirectories. You are done.
\section{Installing \Index{Support files}}
Independent on your operating system and independent on if you built the binaries
yourself or installed the precompiled ones as described above you will need
\Index{scenery}, \Index{texture}, \Index{sound}, and some more support files. A basic
package of all these is contained in the binaries directory mentioned above as
\texttt{fgfs-base-X.XX}.
\noindent
Preferably, you may want to download the \texttt{.tar.gz} version
if you are working under \Index{Linux}/\Index{UNIX} and the \texttt{.exe} version if you
are under \Index{Windows 98/NT}. Make sure you get the \textbf{most recent} version.
If you're working under \Index{Linux} or \Index{UNIX}, unpack the
previously downloaded file with
\texttt{tar xvfz fgfs-base-X.XX.tar.gz}
\noindent
while under \Index{Windows 98/NT} just double click on the file (being situated in the
root of your \FlightGear drive.).
This already completes installing \FlightGear and should you enable to invoke the
program.
Some more scenery which, however, is not a substitute for the
package mentioned above but rather is based on it can be found in
the scenery subdirectory under
\web{http://www.flightgear.org/Downloads/}
\noindent
These may be older versions which may or may not work with the
most recent binaries.
In addition, there is a complete set of \Index{USA Scenery files}
available created by Curt Olson\index{Olson, Curt} which can be
downloaded from
\web{ftp://ftp.kingmont.com/pub/kingmont/}
\noindent
The complete set covers several 100's of MBytes. Thus, Curt
provides the complete set on CD-ROM for those who really would
like to fly over all of the USA. For more detail, check the
remarks in the downloads page above.
Finally, the binaries directory mentioned contains the complete \FlightGear documentation
as
\texttt{fgfs-manual-X.XX.exe}.
It includes a .pdf version of this \textit{Installation and Getting Started} guide
intended for pretty printing using Adobe's Acrobat reader being available from
\web{http://www.adobe.com/acrobat}
Moreover, if properly installed the .html version can be accessed via \FlightGear's
\texttt{help} menu entry.
%% Revision 0.00 1998/09/08 michael
%% Initial revision for version 0.53.
%% Revision 0.01 1998/09/20 michael
%% several extensions and corrections
%% revision 0.10 1998/10/01 michael
%% final proofreading for release
%% revision 0.11 1998/11/01 michael
%% support files Section completely re-written
%% revision 0.20 1999/06/04 michael
%% some updates and corrections, corrected links

File diff suppressed because it is too large Load diff

View file

@ -1,267 +0,0 @@
%%
%% getstart.tex -- Flight Gear documentation: Installation and Getting Started
%% Chapter file
%%
%% Written by Bernhard Buckel, starting September 1998.
%%
%% Copyright (C) 1999 Bernhard Buckel (buckel@wmad95.mathematik.uni-wuerzburg.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: getstart.tex,v 0.20 1999/06/04 michael
%% (Log is kept at end of this file)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\chapter{Takeoff: How to start the program\label{takeoff}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\markboth{\thechapter.\hspace*{1mm}
TAKEOFF}{\thesection\hspace*{1mm} Command line parameters}
\section{Starting under Linux}
Under Linux, \FlightGear is invoked by
\texttt{fgfs -$\!$-option1 -$\!$-option2\dots},
\noindent
where the options are described in Section \ref{options} below.
\section{Starting under \Index{Windows 98/NT}}
In Windows explorer, change to the \texttt{$\backslash$FlightGear$\backslash$} directory.
Call \texttt{runfgfs.bat} by double-clicking if you want to invoke the hardware
accelerated version of \FlightGear \texttt{fgfs.exe}, or \texttt{runfgfs-sgi.bat} if you
installed SGI's software \Index{OpenGL} support.
Alternatively, if for one or the other reason the batch does not work, you can open an
MS-DOS shell, change to the directory where your binary resides (typically something like
\texttt{d:$\backslash$FlightGear$\backslash$bin} where you might have to substitute
\texttt{d:} in favor of your \FlightGear directory), set the environment variable with
\texttt{SET FG\_ROOT=d:$\backslash$FlightGear$\backslash$bin}
\noindent
and invoke \FlightGear (within the same shell -- Windows environment
settings are only valid locally within the same shell) via
\texttt{fgfs -$\!$-option1 -$\!$-option2\dots}.
For getting maximum performance it is highly recommended to
minimize (iconize) the non-graphics window while running
{\FlightGear}$\!$.
\medskip
\centerline{
\includegraphics[clip,width=12.5cm]{arizona.eps}
}
\smallskip
\noindent
Fig.\,2: \textit{Ready for takeoff. We are at the default startup
position in Arizona.}
\medskip
\section{Command line parameters\label{options}}
\index{command line options}
Following is a list and short description of the command line options available. In case
of Windows 98/NT it is recommended to include these in \texttt{runfgfs.bat}.
\subsection{General Options}
\begin{itemize}
\item{\texttt{-$\!$-help}}: gives a small help text, kind of a short version of this Section.
\item{\texttt{-$\!$-fg-root={\it path}}}: tells \FlightGear where to look for its data
files if you didn't compile it with the default settings.
\item{\texttt{-$\!$-disable-game-mode}}: Disables \Index{fullscreen display}.
\item{\texttt{-$\!$-enable-game-mode}}: Enables fullscreen rendering.
\item{\texttt{-$\!$-disable-splash-screen}}: Turns off the rotating \Index{3DFX
logo} when the accelerator board gets initialized.
\item{\texttt{-$\!$-enable-splash-screen}}: If you like advertising, set this!
\item{\texttt{-$\!$-disable-intro-music}}: No MP3-sample is being played when
\FlightGear starts up.
\item{\texttt{-$\!$-enable-intro-music}}: If your machine is powerful enough, enjoy
this setting.
\item{\texttt{-$\!$-disable-mouse-pointer}}: In the future, \FlightGear will
feature a mouse interface so that options can be set at runtime. As
this feature is not implemented yet it seems wise to disable the
mouse interface.
\item{\texttt{-$\!$-enable-mouse-pointer}}: Enables another mouse pointer in the
\FlightGear window. This is useful when running \FlightGear in full
screen mode and will allow access to the - yet to be implemented -
mouse interface of \FlightGear\hspace{-2mm}.
\item{\texttt{-$\!$-disable-pause}}: This will put you into \FlightGear with the
engine running, ready for Take-Off.
\item{\texttt{-$\!$-enable-pause}}: Starts \FlightGear in pause mode.
\end{itemize}
\subsection{Features}
\begin{itemize}
\item{\texttt{-$\!$-disable-hud}}: Switches off the \Index{HUD} (\textbf{H}ead \textbf{U}p
\textbf{D}isplay).
\item{\texttt{-$\!$-enable-hud}}: Turns the \Index{HUD} on. This is the default.
\item{\texttt{-$\!$-disable-panel}}: Turns off the \Index{instrument panel}. This is the
default, as the instrument panel is not yet complete -- but in our opinion
should be given at least a try.
\item{\texttt{-$\!$-enable-panel}}: This will give you the look of a real \Index{cockpit}.
\item{\texttt{-$\!$-disable-sound}}: Pretty self explaining, isn't it?
\item{\texttt{-$\!$-enable-sound}}:
\end{itemize}
\subsection{Flight model\index{flight model}}
\begin{itemize}
\item{\texttt{-$\!$-fdm=abcd}} There are four allowed values for abcd: \texttt{slew, jsb, larcsim,
external}, which you might want to try. Default value is \texttt{larcsim}.
\end{itemize}
\subsection{Initial Position and Orientation\index{orientation}}
\begin{itemize}
\item{\texttt{-$\!$-airport-id=ABCD}}: If you want to start directly at an airport,
enter its international code, i.e. KJFK for JFK airport in New York.
A long/short list of the IDs of the airports being implemented can
be found in \texttt{/Flight Gear/Airports}. You only have to unpack
one of the files with gnuzip. Keep in mind, you need the
terrain data for the relevant region!\index{airport code}
\item{\texttt{-$\!$-lon=degrees}}: This is the starting longitude in degrees (west = -)
\item{\texttt{-$\!$-lat=degrees}}: This is the starting latitude in degrees (south = -)
\item{\texttt{-$\!$-altitude=meters}}: You may start in free flight at the given
altitude. Watch for the next options to insert the plane with a
given heading etc.
\item{\texttt{-$\!$-heading=degrees}}: Sets the \Index{initial heading}.
\item{\texttt{-$\!$-roll=degrees}}: Initial roll angle.\index{initial roll angle}
\item{\texttt{-$\!$-pitch=degrees}}: Initial pitch angle.\index{initial pitch angle}
\end{itemize}
\subsection{Rendering Options\index{rendering options}}
\begin{itemize}
\item{\texttt{-$\!$-fog-disable}}: To cut down the rendering efforts, distant
regions are vanishing in \Index{fog} by default. If you disable fogging,
you'll see farther but your frame rates will drop.
\item{\texttt{-$\!$-fog-fastest}}: The scenery will not look very nice but
frame rates will increase.
\item{\texttt{-$\!$-fog-nicest}}: This option will give you a fairly realistic
view of flying on a hazy day.
\item{\texttt{-$\!$-fov=xx.x}}: Sets the \Index{field of view} in degrees.
The value is displayed on the HUD. Default is 55.0.
\item{\texttt{-$\!$-disable-fullscreen}}: Self explaining, isn't it?
\item{\texttt{-$\!$-enable-fullscreen}}:
\item{\texttt{-$\!$-shading-flat}}: This is the fastest mode but the terrain will look ugly! This option might help if your video accelerator is really slow.
\item{\texttt{-$\!$-shading-smooth}}: This is the recommended (and default) setting - things will look really nice.
\item{\texttt{-$\!$-disable-skyblend}}: No fogging or \Index{haze}, sky will be displayed
using just one color. Fast but ugly!
\item{\texttt{-$\!$-enable-skyblend}}: Fogging/haze is enabled, sky and \Index{terrain} look realistic. This is the default and recommended setting.
\item{\texttt{-$\!$-disable-textures}}: Terrain details will be disabled. Looks ugly, but might help if your video board is slow.
\item{\texttt{-$\!$-enable-textures}}: Default and recommended.
\item{\texttt{-$\!$-enable-wireframe}}: If you want to know how the world of \FlightGear internally looks like, try this!
\item{\texttt{-$\!$-geometry=WWWxHHH}}: Defines the size of the window used, i.e.
\texttt{WWWxHHH} can be \texttt{640x480}, \texttt{800x600}, or \texttt{1024x768}.
\end{itemize}
\subsection{Scenery Options Options\index{scenery options}}
\begin{itemize}
\item{\texttt{-$\!$-tile-radius=n}}: Specifies the tiles radius; allowed values for
\texttt{n} are 1 -- 4.
\end{itemize}
\subsection{HUD Options\index{HUD}}
\begin{itemize}
\item{\texttt{-$\!$-units-feed}}: HUD displays units in feet.
\item{\texttt{-$\!$-units-meters}}: HUD displays units in meters.
\item{\texttt{-$\!$-hud-tris}}: HUD displays the number of triangles rendered.
\item{\texttt{-$\!$-hud-culled}}: HUD displays percentage of triangles culled.
\end{itemize}
\subsection{Time options\index{time options}}
\begin{itemize}
\item{\texttt{-$\!$-time-offset=[+-]hh:mm:ss}}: Offset local time by this amount.
\item{\texttt{-$\!$-start-date-gmt=yyyy:mm:dd:hh:mm:ss}}: Specify a starting time and
date. Time is Greenwich Mean Time.
\item{\texttt{-$\!$-start-date-lst=yyyy:mm:dd:hh:mm:ss}}: Specify a starting time and
date. Uses local sidereal time.
\end{itemize}
%% Revision 0.02 1998/09/29 bernhard
%% revision 0.10 1998/10/01 michael
%% final proofreading for release
%% revision 0.11 1998/11/01 michael
%% Added pic from Arizona takeoff
%% revision 0.20 1999/06/04 michael
%% added new options

View file

@ -1,53 +0,0 @@
%%
%% getstart.tex -- Flight Gear documentation: Installation and Getting Started
%% Title file
%%
%% Written by Michael Basler, started September 1998.
%%
%% Copyright (C) 1999 Michael Basler (pmb@knUUt.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: getstart.tex,v 0.20 1999/06/04 michael
%% (Log is kept at end of this file)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\title{FlightGear Flight Simulator -- Installation and Getting Started}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\author{
Michael Basler (\mail{pmb@knUUt.de})\\
Bernhard Buckel
(\mail{buckel@wmad95.mathematik.uni-wuerzburg.de})\\
{ \setlength{\fboxsep}{12mm}\setlength{\fboxrule}{0pt}
\fbox{
\includegraphics[clip,width=10.0cm]{start.eps}
}}}
\date{June 30, 1999}
\maketitle
\tableofcontents
%% Revision 0.00 1998/09/08 michael
%% Initial revision for version 0.53.
%% revision 0.10 1998/10/01 michael
%% final proofreading for release
%% revision 0.11 1998/11/01 michael
%% added title pic

View file

@ -1,14 +0,0 @@
Sky
stars
correct placement for time, date, and viewer position
correct magnitude
sun
correct position
lights the scene correctly
sky
blends into haze at horizon
sunset/sunrise effects
planets
correct position
correct magnitude

View file

@ -1,308 +0,0 @@
#This file was created by <root> Sat Dec 5 17:56:22 1998
#LyX 0.12 (C) 1995-1998 Matthias Ettrich and the LyX Team
\lyxformat 2.15
\textclass article
\language default
\inputencoding default
\fontscheme default
\graphics default
\paperfontsize default
\spacing single
\papersize Default
\paperpackage a4
\use_geometry 0
\use_amsmath 0
\paperorientation portrait
\secnumdepth 3
\tocdepth 3
\paragraph_separation indent
\defskip medskip
\quotes_language english
\quotes_times 2
\papercolumns 1
\papersides 1
\paperpagestyle default
\layout Title
\added_space_top vfill \added_space_bottom vfill
\emph on
FlightGear
\emph default
Flight Simulator
\newline
Portability Guide
\layout Author
Bernie Bright (bbright@c031.aone.net.au)
\layout Date
28 November 1998
\layout Standard
FlightGear is a multi-platform general aviation flight simulator\SpecialChar \@.
It is an
open development project in which anyone with network access and a C++
compiler can contribute patches or new features.
\newline
\layout Section
Introduction
\layout Standard
The file
\emph on
Include/compiler.h
\emph default
attempts to capture the differences between C++ compiler and STL implementation
s through the use of
\begin_inset Quotes eld
\end_inset
feature test macros
\begin_inset Quotes erd
\end_inset
\SpecialChar \@.
The file is divided into two parts.
The first part contains a section for each compiler, consisting of manifest
constants specifying the features supported or absent from the particular
compiler/STL combination\SpecialChar \@.
The second part uses the feature test macros to
supply any missing features\SpecialChar \@.
\layout Subsection
Supported compilers (more to come)
\layout Standard
gcc 2.7.x
\newline
gcc 2.8.x
\newline
egcs 1.x
\newline
Inprise (Borland) C++ 5.02
\newline
Inprise (Borland) C++Builder 1 (5.20)
\layout Subsection
Features Tests
\layout Subsubsection
STL
\layout Description
FG_NEED_AUTO_PTR Some STL implementations don't supply an
\family typewriter
auto_ptr<>
\family default
class template.
Define this to provide one.
\layout Description
FG_NO_DEFAULT_TEMPLATE_ARGS Define this if the compiler doesn't support
default arguments in template declarations.
\emph on
(example)
\layout Description
FG_INCOMPLETE_FUNCTIONAL Some STL implementations don't have
\family typewriter
mem_fun_ref()
\family default
.
Define this to provide one.
\layout Description
FG_NO_ARROW_OPERATOR Define this if iterators don't support
\family typewriter
operator->()
\family default
.
\emph on
(example)
\layout Description
FG_EXPLICIT_FUNCTION_TMPL_ARGS
\layout Description
FG_MEMBER_TEMPLATES
\layout Subsubsection
Compiler
\layout Description
FG_NAMESPACES Define if compiler supports namespaces.
\layout Description
FG_HAVE_STD Define if std:: namespace supported.
\layout Description
FG_HAVE_STD_INCLUDES Define if headers should be included as
\family typewriter
<iostream>
\family default
instead of
\family typewriter
<iostream
\family default
.h>.
Also implies that all ISO C++ standard include files are present.
\layout Description
FG_HAVE_STREAMBUF Define if
\family typewriter
<streambuf>
\family default
or
\family typewriter
<streambuf
\family default
.h> are present.
\layout Description
FG_CLASS_PARTIAL_SPECIALIZATION
\layout Description
FG_NEED_EXPLICIT Define if the compiler doesn't support the
\family typewriter
\series bold
explicit
\family default
\series default
keyword.
\layout Description
FG_NEED_TYPENAME Define if the compiler doesn't support the
\family typewriter
\series bold
typename
\family default
\series default
keyword.
\layout Description
FG_NEED_MUTABLE Define if the compiler doesn't support the
\family typewriter
\series bold
mutable
\family default
\series default
keyword.
\layout Description
FG_NEED_BOOL Define if the compiler doesn't have the
\family typewriter
\series bold
bool
\family default
\series default
type.
\layout Subsubsection
Include Files
\layout Standard
This section deals with header file naming conventions.
Some systems truncate filenames, 8.3 being common, other systems use old
or non-standard names for some header files.
We deal with the simple cases by defining macros that expand to the appropriate
filename.
\layout Description
STD_ALGORITHM => <algorithm>,
\begin_inset Quotes eld
\end_inset
algorithm
\begin_inset Quotes erd
\end_inset
\layout Description
STD_FUNCTIONAL => <functional>,
\begin_inset Quotes eld
\end_inset
functional
\begin_inset Quotes erd
\end_inset
\layout Description
STD_IOMANIP => <iomanip>, <iomanip.h>
\layout Description
STD_IOSTREAM => <iostream>, <iostream.h>, <iostreams.h>
\layout Description
STD_STDEXCEPT => <stdexcept> (ignore this, FlightGear doesn't use exceptions)
\layout Description
STD_STRING => <string>
\layout Description
STD_STRSTREAM => <strstream>, <strstream.h>
\layout Standard
In use, instead of writing #include <iostream> you write #include STD_IOSTREAM.
\newline
\newline
The situation becomes complicated with missing header files.
<streambuf> is a good example.
In this case we must rely on FG_HAVE_STD_INCLUDES and FG_HAVE_STREAMBUF.
\newline
\emph on
\newline
TODO
\layout Subsection
and the rest
\layout Subsubsection
Namespace Issues
\layout Description
FG_USING_STD(X)
\layout Description
FG_NAMESPACE(X)
\layout Description
FG_NAMESPACE_END
\layout Description
FG_USING_NAMESPACE(X)
\layout Subsubsection
Templates
\layout Description
FG_NULL_TMPL_ARGS
\layout Description
FG_TEMPLATE_NULL
\layout Bibliography
\bibitem {1}
Stroustrup, Bjarne,
\emph on
The C++ Programming Programming Language
\emph default
, 3rd edition, June 1997, ISBN 0-201-88954-4
\layout Bibliography
\bibitem {2}
SGI Standard Template Library (STL) release 3.11
\the_end

View file

@ -1,142 +0,0 @@
%% This LaTeX-file was created by <root> Sat Dec 5 17:56:02 1998
%% LyX 0.12 (C) 1995-1998 by Matthias Ettrich and the LyX Team
%% Do not edit this file unless you know what you are doing.
\documentclass{article}
\usepackage[T1]{fontenc}
\makeatletter
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% LyX specific LaTeX commands.
\newcommand{\LyX}{L\kern-.1667em\lower.25em\hbox{Y}\kern-.125emX\spacefactor1000}
\makeatother
\begin{document}
\vfill{}
\title{\emph{FlightGear} Flight Simulator\\
Portability Guide}
\vfill{}
\author{Bernie Bright (bbright@c031.aone.net.au)}
\date{28 November 1998}
\maketitle
FlightGear is a multi-platform general aviation flight simulator\@. It is an
open development project in which anyone with network access and a C++ compiler
can contribute patches or new features.\\
\section{Introduction}
The file \emph{Include/compiler.h} attempts to capture the differences between
C++ compiler and STL implementations through the use of ``feature test macros''\@.
The file is divided into two parts. The first part contains a section for each
compiler, consisting of manifest constants specifying the features supported
or absent from the particular compiler/STL combination\@. The second part uses
the feature test macros to supply any missing features\@.
\subsection{Supported compilers (more to come)}
gcc 2.7.x\\
gcc 2.8.x\\
egcs 1.x\\
Inprise (Borland) C++ 5.02\\
Inprise (Borland) C++Builder 1 (5.20)
\subsection{Features Tests}
\subsubsection{STL}
\begin{description}
\item [FG\_NEED\_AUTO\_PTR]Some STL implementations don't supply an \texttt{auto\_ptr<>}
class template. Define this to provide one.
\item [FG\_NO\_DEFAULT\_TEMPLATE\_ARGS]Define this if the compiler doesn't support
default arguments in template declarations. \emph{(example)}
\item [FG\_INCOMPLETE\_FUNCTIONAL]Some STL implementations don't have \texttt{mem\_fun\_ref()}.
Define this to provide one.
\item [FG\_NO\_ARROW\_OPERATOR]Define this if iterators don't support \texttt{operator->()}.
\emph{(example)}
\item [FG\_EXPLICIT\_FUNCTION\_TMPL\_ARGS]~
\item [FG\_MEMBER\_TEMPLATES]~
\end{description}
\subsubsection{Compiler}
\begin{description}
\item [FG\_NAMESPACES]Define if compiler supports namespaces.
\item [FG\_HAVE\_STD]Define if std:: namespace supported.
\item [FG\_HAVE\_STD\_INCLUDES]Define if headers should be included as \texttt{<iostream>}
instead of \texttt{<iostream}.h>. Also implies that all ISO C++ standard include
files are present.
\item [FG\_HAVE\_STREAMBUF]Define if \texttt{<streambuf>} or \texttt{<streambuf}.h>
are present.
\item [FG\_CLASS\_PARTIAL\_SPECIALIZATION]~
\item [FG\_NEED\_EXPLICIT]Define if the compiler doesn't support the \texttt{\textbf{explicit}}
keyword.
\item [FG\_NEED\_TYPENAME]Define if the compiler doesn't support the \texttt{\textbf{typename}}
keyword.
\item [FG\_NEED\_MUTABLE]Define if the compiler doesn't support the \texttt{\textbf{mutable}}
keyword.
\item [FG\_NEED\_BOOL]Define if the compiler doesn't have the \texttt{\textbf{bool}}
type.
\end{description}
\subsubsection{Include Files}
This section deals with header file naming conventions. Some systems truncate
filenames, 8.3 being common, other systems use old or non-standard names for
some header files. We deal with the simple cases by defining macros that expand
to the appropriate filename.
\begin{description}
\item [STD\_ALGORITHM]=> <algorithm>, ``algorithm''
\item [STD\_FUNCTIONAL]=> <functional>, ``functional''
\item [STD\_IOMANIP]=> <iomanip>, <iomanip.h>
\item [STD\_IOSTREAM]=> <iostream>, <iostream.h>, <iostreams.h>
\item [STD\_STDEXCEPT]=> <stdexcept> (ignore this, FlightGear doesn't use exceptions)
\item [STD\_STRING]=> <string>
\item [STD\_STRSTREAM]=> <strstream>, <strstream.h>
\end{description}
In use, instead of writing \#include <iostream> you write \#include STD\_IOSTREAM.\\
\\
The situation becomes complicated with missing header files. <streambuf> is
a good example. In this case we must rely on FG\_HAVE\_STD\_INCLUDES and FG\_HAVE\_STREAMBUF.\\
\emph{}\\
\emph{TODO}
\subsection{and the rest}
\subsubsection{Namespace Issues}
\begin{description}
\item [FG\_USING\_STD(X)]~
\item [FG\_NAMESPACE(X)]~
\item [FG\_NAMESPACE\_END]~
\item [FG\_USING\_NAMESPACE(X)]~
\end{description}
\subsubsection{Templates}
\begin{description}
\item [FG\_NULL\_TMPL\_ARGS]~
\item [FG\_TEMPLATE\_NULL]~
\end{description}
\begin{thebibliography}{}
\bibitem{1}Stroustrup, Bjarne, \emph{The C++ Programming Programming Language}, 3rd edition,
June 1997, ISBN 0-201-88954-4
\bibitem{2}SGI Standard Template Library (STL) release 3.11
\end{thebibliography}
\end{document}

View file

@ -1,140 +0,0 @@
=============================================================================
A basic set of bright stars -- taken from the xephem program.
Based on the 5th Revised edition of the Yale Bright Star Catalog, 1991, from
ftp://adc.gsfc.nasa.gov/pub/adc/archives/catalogs/5/5050.
Only those entries with a Bayer and/or Flamsteed number are retained
here.
Format: Constellation BayerN-Flamsteed, as available. Bayer is
truncated as requried to enforce a maximum total length of 13
imposed within xephem.
Common names were then overlayed by closest position match from
hand-edited a list supplied by Robert Tidd (inp@violet.berkeley.edu)
and Alan Paeth (awpaeth@watcgl.waterloo.edu)
=============================================================================
Data file format:
name , right assention (radians) , declination (radians) , magnitude (0.0 - 1.0)
=============================================================================
The following information is taken from:
http://www.lclark.edu/~wstone/skytour/celest.html
Please visit the above site, it contains much more complete information.
CELESTIAL MEASUREMENTS
RIGHT ASCENSION AND DECLINATION
Although we know that the objects we see in the sky are of different
sizes and at different distances from us, it is convenient to
visualize all the objects as being attached to an imaginary sphere
surrounding the Earth. From our vantage point, the sky certainly looks
like a dome (the half of the celestial sphere above our local
horizon). The celestial sphere is mapped in Right Ascension (RA) and
Declination (Dec). Declination is the celestial equivalent of
latitude, and is simply the Earth's latitude lines projected onto the
celestial sphere. A star that can be directly overhead as seen from
the Earth's Equator (0 degrees latitude) is said to be on the
Celestial Equator, and has a declination of 0 degrees . The North
Star, Polaris, is very nearly overhead as seen from the North Pole (90
degrees North latitude). The point directly over the North Pole on the
celestial sphere is called the North Celestial Pole, and has a
declination of +90 degrees . Northern declinations are given positive
signs, and southern declinations are given negative signs. So, the
South Celestial Pole has a declination of -90 degrees .
Right Ascension is the equivalent of longitude, but since the Earth
rotates with respect to the celestial sphere we cannot simply use the
Greenwich Meridian as 0 degrees RA. Instead, we set the zero point as
the place on the celestial sphere where the Sun crosses the Celestial
Equator (0 degrees Dec) at the vernal (spring) equinox. The arc of
the celestial sphere from the North Celestial Pole through this point
to the South Celestial Pole is designated as Zero hours RA. Right
Ascension increases eastward, and the sky is divided up into 24
hours. This designation is convenient because it represents the
sidereal day, the time it takes for the Earth to make one rotation
relative to the celestial sphere. If you pointed a telescope (with no
motor drive) at the coordinates (RA=0h, Dec=0 degrees ), and came back
one hour later, the telescope would then be pointing at (RA=1h, Dec=0
degrees ). Because the Earth's revolution around the Sun also
contributes to the apparent motion of the stars, the day we keep time
by (the solar day) is about four minutes longer than the sidereal
day. So, if you pointed a telescope at (RA=0h, Dec=0 degrees ) and
came back 24 hours later, the telescope would now be pointing at
(RA=0h 4m, Dec=0 degrees). A consequence is that the fixed stars
appear to rise about four minutes earlier each day.
=============================================================================
From: steve@mred.bgm.link.com (Steve Baker)
Subject: Re: FG: Fun in the sun ...
Date: Tue, 5 Aug 97 15:37:27 -0500
You probably ought to get the stars right too - there is a database
of the 300 brightest stars in the 'Yale Bright Star Catalog' - which
I enclose below. I'd guess that you could navigate by the stars -
so this might not be a completely useless feature - right?
Anyway, if all else fails - and the flight sim never gets going - we
could at least sell this as a planetarium :-)
The format of the star data is:
Name Right-Ascension Declination Magnitude
(Ascension and Declination are in radians)
We took the magnitude value, scaled it by 0.8 and added 0.2 to make
a 0->1 brightness value. Using the raw data created too many very
dark stars.
Originally, there were constellation names as sub-headings - but I
think I deleted them to make the file easier to parse :-) That makes
the 'name' field pretty pointless.
if you are still talking about the geocentric coordinate system
where the terrain is modelled with Z pointing towards the North
pole, X out of the 0 degree meridian at the equator and Y out at the
Indian ocean at the equator - then you can position the stars using:
star[ X ] = fsin ( ra ) * fcos( decl ) ;
star[ Y ] = fcos ( ra ) * fcos( decl ) ;
star[ Z ] = fsin ( decl ) ;
(which you can precompute at startup)
...and then rotate them about the Z axis using GMT*two_pi/24.0
#
Put them all in a display list - use GL_POINTS as the primitive...
glNewList ( ...whatever... )
glBegin ( GL_POINTS ) ;
for ( int i = 0 ; i < num_stars ; i++ ) {
glColor3f ( star_brightness[i], star_brightness[i], star_brightness[i] ) ;
glVertex3f ( star_x[i], star_y[i], star_z[i] ) ;
}
glEnd () ;
glEndList () ;
You need to draw them out by the far clip plane so they don't occult
anything. Then you need to translate them using the same x/y/z as
the eyepoint so that you can never fly any closer to them.

View file

@ -1,203 +0,0 @@
%
% `Stars.tex' -- describes our procedure for drawing stars
%
% Written by Curtis Olson. Started December, 1997.
%
% $Id$
%------------------------------------------------------------------------
\documentclass[12pt]{article}
\usepackage{anysize}
\papersize{11in}{8.5in}
\marginsize{1in}{1in}{1in}{1in}
\usepackage{amsmath}
\usepackage{epsfig}
\usepackage{setspace}
\onehalfspacing
\usepackage{url}
\begin{document}
\title{
Flight Gear Stars Representation and Rendering.
}
\author{
Curtis L. Olson\\
(\texttt{curt@me.umn.edu})
}
\maketitle
\section{Introduction}
Flight Gear attempts to render the top several hundred stars in the
correct position in the sky for the current time and position as will
as rendering these stars with the correct ``magnitude''.
This document will give a quick overview of our approach.
\section{Resources}
\subsubsection{XEphem}
The set of bright stars was extracted from the xephem program. For a
full list of features and the latest news, please see the xephem home
page at \url{http://iraf.noao.edu/~ecdowney/xephem.html}. The XEphem
star list was itself taken from the Yale Bright Star Catalog.
\begin{quote}
Based on the 5th Revised edition of the Yale Bright Star Catalog,
1991, from ftp://adc.gsfc.nasa.gov/pub/adc/archives/catalogs/5/5050.
Only those entries with a Bayer and/or Flamsteed number are retained
here.
Format: Constellation BayerN-Flamsteed, as available. Bayer is
truncated as required to enforce a maximum total length of 13
imposed within xephem.
Common names were then overlayed by closest position match from
hand-edited a list supplied by Robert Tidd (inp@violet.berkeley.edu)
and Alan Paeth (awpaeth@watcgl.waterloo.edu)
\end{quote}
The author of XEphem, Elwood Downey (ecdowney@noao.edu), was very
instrumental in helping me understand sidereal time, accurate star
placement, and even contributed some really hairy sections of code.
Thanks Elwood!
\section{Terminology and Definitions}
The following information is repeated verbatim from
\url{http://www.lclark.edu/~wstone/skytour/celest.html}: If you are
interested in these sorts of things I urge you to visit this site. It
contains much more complete information.
\subsection{Celestial Measurements}
Although we know that the objects we see in the sky are of different
sizes and at different distances from us, it is convenient to
visualize all the objects as being attached to an imaginary sphere
surrounding the Earth. From our vantage point, the sky certainly
looks like a dome (the half of the celestial sphere above our local
horizon). The celestial sphere is mapped in Right Ascension (RA) and
Declination (Dec).
\subsubsection{Declination}
Declination is the celestial equivalent of latitude, and is simply the
Earth's latitude lines projected onto the celestial sphere. A star
that can be directly overhead as seen from the Earth's Equator (0
degrees latitude) is said to be on the Celestial Equator, and has a
declination of 0 degrees . The North Star, Polaris, is very nearly
overhead as seen from the North Pole (90 degrees North latitude). The
point directly over the North Pole on the celestial sphere is called
the North Celestial Pole, and has a declination of +90 degrees .
Northern declinations are given positive signs, and southern
declinations are given negative signs. So, the South Celestial Pole
has a declination of -90 degrees .
\subsubsection{Right Ascension \& Sidereal Time}
Right Ascension is the equivalent of longitude, but since the Earth
rotates with respect to the celestial sphere we cannot simply use the
Greenwich Meridian as 0 degrees RA. Instead, we set the zero point as
the place on the celestial sphere where the Sun crosses the Celestial
Equator (0 degrees Dec) at the vernal (spring) equinox. The arc of
the celestial sphere from the North Celestial Pole through this point
to the South Celestial Pole is designated as Zero hours RA. Right
Ascension increases eastward, and the sky is divided up into 24
hours. This designation is convenient because it represents the
sidereal day, the time it takes for the Earth to make one rotation
relative to the celestial sphere. If you pointed a telescope (with no
motor drive) at the coordinates (RA=0h, Dec=0 degrees ), and came back
one hour later, the telescope would then be pointing at (RA=1h, Dec=0
degrees ). Because the Earth's revolution around the Sun also
contributes to the apparent motion of the stars, the day we keep time
by (the solar day) is about four minutes longer than the sidereal
day. So, if you pointed a telescope at (RA=0h, Dec=0 degrees ) and
came back 24 hours later, the telescope would now be pointing at
(RA=0h 4m, Dec=0 degrees). A consequence is that the fixed stars
appear to rise about four minutes earlier each day.
\subsection{Implementation}
Here is a brief overview of how stars were implemented in Flight Gear.
The right ascension and declination of each star is used to build a
structure of point objects to represent the stars. The magnitude is
mapped into a color on the gray/white continuum. The points are
positioned just inside the far clip plane. When rendering the stars,
this structure (display list) is rotated about the $Z$ axis by the
current sidereal time and translated to the current view point.
\subsubsection{Data file format}
The star information is stored in a simple data file called
``Stars.dat'' with the following comma delimited format: name, right
ascension(radians), declination(radians), magnitude(smaller is
brighter). Here is an extract of the data file:
\begin{verbatim}
Sirius,1.767793,-0.266754,-1.460000
Canopus,1.675305,-0.895427,-0.720000
Arcturus,3.733528,0.334798,-0.040000
Rigil Kentaurus,3.837972,-1.032619,-0.010000
Vega,4.873563,0.676902,0.030000
Capella,1.381821,0.802818,0.080000
Rigel,1.372432,-0.136107,0.120000
Procyon,2.004082,0.091193,0.380000
Achernar,0.426362,-0.990707,0.460000
\end{verbatim}
\subsubsection{Building the display list}
The display list is built up from a collection of point objects as the
star data file is loaded. For each star, the magnitude is mapped into
a brightness value from 0.0 to 1.0 with 1.0 being the brightest. Our
coordinate system is described in the coordinate system document: Z
points towards the North pole, X out of the 0 degree meridian at the
equator, and Y out at the Indian ocean at the equator. Given this
coordinate system, the position of each star at 0:00H sidereal time is
calculated as follows:
\begin{align}
x &= \mathrm{distance} * \cos(\mathrm{rightascension}) *
\cos(\mathrm{declination}) \\
y &= \mathrm{distance} * \sin(\mathrm{rightascension}) *
\cos(\mathrm{declination}) \\
z &= \mathrm{distance} * \sin(\mathrm{declination})
\end{align}
\subsubsection{Transformations and Rendering}
The tricky part about rendering the stars is calculating sidereal time
correctly. Here's where Elwood Downey saved my butt. 0:00H sidereal
time aligns with 12:00 noon GMT time on March 21 of every year. After
that they diverge by about 4 minutes per day. The solar day is
approximately 4 minutes longer than the side real day. Once you know
the proper sidereal time, you simply translate the center of the star
structure to the current view point, then rotate this structure about
the Z axis by the current sidereal time.
The stars are drawn out by the far clip plane so they don't occult
anything. They are translated using the same x/y/z as the eye point
so that you can never fly any closer to them.
\end{document}
%------------------------------------------------------------------------

View file

@ -1,173 +0,0 @@
%
% `coord.tex' -- describes the coordinate systems and transforms used
% by the FG scenery management subsystem
%
% Written by Curtis Olson. Started July, 1997.
%
% $Id$
\documentclass[12pt]{article}
% \usepackage{times}
% \usepackage{mathptm}
\usepackage{anysize}
\papersize{11in}{8.5in}
\marginsize{1in}{1in}{1in}{1in}
\usepackage{epsfig}
\usepackage{setspace}
\onehalfspacing
\usepackage{url}
\begin{document}
\title{
Flight Gear Internal Scenery Coordinate Systems and
Representations.
}
\author{
Curtis L. Olson\\
(\texttt{curt@me.umn.edu})
}
\maketitle
\section{Coordinate Systems}
\subsection{Geocentric Coordinates}
Geocentric coordinates are the polar coordinates centered at the
center of the earth. Points are defined by the geocentric longitude,
geocentric latitude, and distance from the \textit{center} of the
earth. Note, due to the non-spherical nature of the earth, the
geocentric latitude is not exactly the same as the traditional
latitude you would see on a map.
\subsection{Geodetic Coordinates}
Geodetic coordinates are represented by longitude, latitude, and
elevation above sea level. These are the coordinates you would read
off a map, or see on your GPS. However, the geodetic latitude does
not precisely correspond to the angle (in polar coordinates) from the
center of the earth which the geocentric coordinate system reports.
\subsection{Geocentric vs. Geodetic coordinates}
The difference between geodetic and geocentric coordinates is subtle
and must be understood. The problem arose because people started
mapping the earth using latitude and longitude back when they thought
the Earth was round (or a perfect sphere.) It's not though. It is
more of an ellipse.
Early map makers defined the standard \textit{geodetic} latitude as
the angle between the local up vector and the equator. This is shown
in figure \ref{fig:geodesy}. The point $\mathbf{B}$ marks our current
position. The line $\mathbf{ABC}$ is tangent to the ellipse at point
$\mathbf{B}$ and represents the local ``horizontal.'' The line
$\mathbf{BF}$ represents the local ``up'' vector. Thus, in
traditional map maker terms, the current latitude is the angle defined
by $\angle \mathbf{DBF}$.
However, as you can see from the figure, the line $\mathbf{BF}$ does
not extend through the center of the earth. Instead, the line
$\mathbf{BE}$ extends through the center of the earth. So in
\textit{geocentric} coordinates, our latitude would be reported as the
angle $\angle \mathbf{DBE}$.
\begin{figure}[hbt]
\centerline{
\psfig{file=geodesy.eps}
}
\caption{Geocentric vs. Geodetic coordinates}
\label{fig:geodesy}
\end{figure}
The LaRCsim flight model operates in geocentric coordinates
internally, but reports the current position in both coordinate
systems.
\subsection{World Geodetic System 1984 (WGS 84)}
The world is not a perfect sphere. WGS-84 defines a standard model
for dealing with this. The LaRCsim flight model code already uses the
WGS-84 standard in its calculations.
For those that are interested here are a couple of URLS for more
information:
\noindent
\url{http://acro.harvard.edu/SSA/BGA/wg84figs.html} \\
\url{http://www.afmc.wpafb.af.mil/organizations/HQ-AFMC/IN/mist/dma/wgs1984.htm}
\\
\url{http://www.nima.mil/publications/guides/dtf/datums.html}
To maintain simulation accuracy, the WGS-84 model should be used when
translating geodetic coordinates (via geocentric coordinates) into the
FG Cartesian coordinate system. The code to do this can probably be
borrowed from the LaRCsim code. It is located in
\texttt{ls\_geodesy.c}.
\subsection{Cartesian Coordinates}
Internally, all flight gear scenery is represented using a Cartesian
coordinate system. The origin of this coordinate system is the center
of the earth. The X axis runs along a line from the center of the
earth out to the equator at the zero meridian. The Z axis runs along
a line between the north and south poles with north being positive.
The Y axis is parallel to a line running through the center of the
earth out through the equator somewhere in the Indian Ocean. Figure
\ref{fig:coords} shows the orientation of the X, Y, and Z axes in
relationship to the earth.
\begin{figure}[hbt]
\centerline{
\psfig{file=coord.eps}
}
\caption{Flight Gear Coordinate System}
\label{fig:coords}
\end{figure}
\newpage
\subsection{Converting between coordinate systems}
Different aspects of the simulation will need to deal with positions
represented in the various coordinate systems. Typically map data is
presented in the geodetic coordinate system. The LaRCsim code uses
the geocentric coordinate system. FG will use a Cartesian coordinate
system for representing scenery internally. Potential add on items
such as GPS's will need to know positions in the geodetic coordinate
system, etc.
FG will need to be able to convert positions between any of these
coordinate systems. LaRCsim comes with code to convert back and forth
between geodetic and geocentric coordinates. So, we only need to
convert between geocentric and cartesian coordinates to complete the
picture. Converting from geocentric to cartesian coordinates is done
by using the following formula:
\noindent
\[ x = cos(lon_\mathit{geocentric}) * cos(lat_\mathit{geocentric}) *
radius_\mathit{geocentric} \]
\[ y = sin(lon_\mathit{geocentric}) * cos(lat_\mathit{geocentric}) *
radius_\mathit{geocentric} \]
\[ z = sin(lat_\mathit{geocentric}) * radius_\mathit{geocentric} \]
Here is the formula to convert from cartesian coordinates back into
geocentric coordinates:
\noindent
\[ lon = atan2( y, x ) \]
\[ lat = \frac{\pi}{2} - atan2( \sqrt{x*x + y*y}, z ) \]
\[ radius = \sqrt{x*x + y*y + z*z} \]
\end{document}

View file

@ -1,25 +0,0 @@
#FIG 3.2
Landscape
Center
Inches
Letter
100.00
Single
0
1200 2
5 1 0 1 0 7 0 0 -1 0.000 0 1 0 0 6000.000 2700.000 4200 5100 6000 5700 7800 5100
5 1 1 1 0 7 0 0 -1 4.000 0 0 0 0 6000.000 7500.000 4200 5100 6000 4500 7800 5100
1 3 0 1 0 7 0 0 -1 0.000 1 0.0000 6000 5100 1814 1814 6000 5100 7575 6000
2 1 0 2 0 7 0 0 -1 0.000 0 0 -1 1 0 2
2 1 2.00 120.00 240.00
6000 5100 8400 5100
2 1 0 2 0 7 0 0 -1 0.000 0 0 -1 1 0 2
2 1 2.00 120.00 240.00
6000 5100 6000 2700
2 1 0 2 0 7 0 0 -1 0.000 0 0 -1 1 0 2
2 1 2.00 120.00 240.00
6000 5100 6900 4200
4 0 0 0 0 0 14 0.0000 4 195 1245 5925 2550 Z (North Pole)\001
4 0 0 0 0 0 14 0.0000 4 195 1485 6975 4125 Y (Indian Ocean)\001
4 0 0 0 0 0 14 0.0000 4 150 150 8550 5175 X\001
4 0 0 0 0 0 14 0.0000 4 195 2025 6750 5475 (Zero Meridian, Africa)\001

View file

@ -1,43 +0,0 @@
#FIG 3.2
Landscape
Center
Inches
Letter
100.00
Single
0
1200 2
1 3 2 1 0 7 0 0 -1 3.000 1 0.0000 6300 4800 1800 1800 6300 4800 8100 4800
1 1 0 2 0 7 0 0 -1 0.000 1 0.0000 6300 4800 2025 1500 6300 4800 8325 3300
1 3 0 1 0 0 0 0 20 0.000 1 0.0000 6300 4800 44 44 6300 4800 6344 4795
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
2 1 1.00 60.00 120.00
7500 3600 8400 2700
2 1 1 1 0 7 0 0 -1 4.000 0 0 -1 0 0 2
6300 4800 7500 3600
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
2 1 1.00 60.00 120.00
7500 3600 8700 3600
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
2 1 1.00 60.00 120.00
7500 3600 8100 2400
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 1 2
2 1 1.00 60.00 120.00
2 1 1.00 60.00 120.00
8700 4200 6000 2850
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
2 1 1.00 60.00 120.00
5625 4125 5400 3225
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
2 1 1.00 60.00 120.00
6000 5475 6300 6300
2 1 1 1 0 7 0 0 -1 4.000 0 0 -1 0 0 2
7500 3600 6750 5100
4 0 0 0 0 0 14 0.0000 4 150 165 8550 4425 A\001
4 0 0 0 0 0 14 0.0000 4 150 150 5775 2925 C\001
4 0 0 0 0 0 14 0.0000 4 150 150 8550 3825 D\001
4 0 0 0 0 0 14 0.0000 4 150 135 8325 3075 E\001
4 0 0 0 0 0 14 0.0000 4 150 120 7800 2625 F\001
4 0 0 0 0 0 12 0.0000 4 180 1125 5100 4350 Perfect Sphere\001
4 0 0 0 0 0 12 0.0000 4 180 1980 5100 5400 True Earth ellipsoid shape\001
4 0 0 0 0 0 14 0.0000 4 150 135 7500 3900 B\001

View file

@ -1,3 +0,0 @@
An online guide for interpreting the DEM data file format is available at:
http://edcwww.cr.usgs.gov/glis/hyper/guide/1_dgr_dem

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load diff

View file

@ -1,550 +0,0 @@
%
% `SceneryGeneration.tex' -- describes the scenery generation tool pipeline
%
% Written by Curtis Olson. Started February, 1999. curt@flightgear.org
%
% $Id$
%------------------------------------------------------------------------
\documentclass[12pt]{article}
\usepackage{anysize}
\papersize{11in}{8.5in}
\marginsize{1in}{1in}{1in}{1in}
\usepackage{amsmath}
\usepackage{epsfig}
\usepackage{setspace}
\onehalfspacing
\usepackage{url}
\begin{document}
\title{
Flight Gear Scenery Generation Tools.
}
\author{
Curtis L. Olson\\
(\texttt{curt@flightgear.org})
}
\maketitle
\section{Introduction}
This document gives a brief overview of the Flight Gear scenery
generation tools and how they fit together in a pipeline to produce
the runtime scenery from the raw data.
The first sections describe how the Flight Gear Earth is subdivided
and the coordinate systems that Flight Gear uses internally. The
remaining sections describe the tools that take diverse data sources
and produce the actual scenery.
\section{Internal Scenery Representation}
This section describes how FG represents, manipulates, and
transforms scenery internally.
Internal, all FG scenery is defined using a cartesian coordinate
system centered at the center of the earth. Please refer to the
Flight Gear CoordinateSystem document for more information. This
means that one of the scenery tools processing steps will be to
convert from the source data coordinate system to the internal Flight
Gear coordinate system.
\subsection{Scenery Partitioning}
Flight Gear splits the world up into tiles. This splits up the
immense scenery data base into chunks that are managable by the run
time simulator.
Tile edges are parallel to longitude and latitude lines. Tiles are
gauranteed to be at least 8 miles long in both width and height. As
we move towards the poles, the tiles get narrower, so at certain
predefined latitudes, the tile with is doubled. Figure \ref{fig:lats}
shows latitudes vs. tile widths. The southern hemisphere is a mirror
image of the northern hemisphere.
\begin{figure}[hbt]
\begin{center}
\begin{tabular}{||l|l||} \hline
Latitude Range & Tile Width \\ \hline
$[0, 22)$ & $\frac{1}{8}$ degree \\ \hline
$[22, 62)$ & $\frac{1}{4}$ degree \\ \hline
$[62, 76)$ & $\frac{1}{2}$ degree \\ \hline
$[76, 83)$ & $1$ degree \\ \hline
$[83, 86)$ & $2$ degrees \\ \hline
$[86, 88)$ & $4$ degrees \\ \hline
$[88, 89)$ & $8$ degrees \\ \hline
$[89, 90]$ & polar cap \\ \hline
\hline
\end{tabular}
\end{center}
\caption{Latitude vs. Tile Widths.}
\label{fig:lats}
\end{figure}
Since Flight Gear tiles are partitioned parallel to longitude and
latitude lines, they have a trapezium shape. Figure \ref{fig:trap}
shows an exaggerated scenery area.
\begin{figure}[hbt]
\centerline{
\psfig{file=trap.eps}
}
\caption{Basic Tile Shape}
\label{fig:trap}
\end{figure}
\subsection{Reference Points}
Each scenery area will have a reference point at the center of its
area. This reference point (for purposes of avoiding floating point
precision problems) defines the origin of a local coordinate system
which. The local coordinate system is simply translated from the
global coordinate system by the distance of the tile's center
reference point from the center of the earth. Figure
\ref{fig:reference} demonstrates this better than I can explain it.
\begin{figure}[hbt]
\centerline{
\psfig{file=ref.eps}
}
\caption{Reference Points and Translations}
\label{fig:reference}
\end{figure}
All the objects for a specific scenery area will be defined based on
this local coordinate system. For each scenery area we define a
vector $\vec{\mathbf{a}}$ which represents the distance from the
center of the earth to the local coordinate system.
\subsection{Putting the pieces of scenery together}
To render a scene, the scenery manager will need to load all the
visible tiles. Before rendering each tile we translate it by
$\vec{\mathbf{a}}_{current} - \vec{\mathbf{a}}_{n}$. This moves all
the rendered tiles near to the origin, while maintaining the relative
positions and orientations. The of moving all the tiles near the
origin before rendering them is to try to reduce floating point round
off problems.
When rendering, it is straightforward to calculate the proper view
point and up vector so that the scenery will appear right side up when
it is rendered.
\subsection{Scenery file format}
Here is a very brief overview of the flight gear scenery file format.
Some of this format will have to change in the future, so I won't put
a lot of effort here right now. This description will be most
understandable if you reference an actual scenery tile file. If you
have questions, please ask!
\begin{itemize}
\item Coordinates are in (X, Y, Z) with (0, 0, 0) being the center of
the earth. Units are in meters.
\item ``gbs'' is the ``global bounding sphere'' specified by the
center reference point and a radius.
\item This is followed by a list of vertices prefaced by ``v''
specifying the offsets of the vertices from the gbs reference point.
\item Then follows the list of vertex normals ``vn''.
\item Then the sets of triangle strips are specifed:
\item ``usemtl'' points to a material property record in the materials
file and specifies the texture/color/etc. for this triangle strip.
\item ``bs'' specifies the bounding sphere for this particular tri
strip (for view frustum culling)
\item ``t'' is the start of a tri strip and the integer numbers are
just indices back into the vertex and vertex normal lists.
\item ``q'' is simply a continuation of the triangle strip.
\end{itemize}
I will eventually need to add texture coordinate support to this file
format, as well as a way to reference and position objects from an
external library.
\section{Scenery Generation}
This section is very fluid right now. I have implemented a first pass
at generating scenery. This was a good learning experience, but it
exposed several flaws and limitations in my original approach. I am
in the midst of a complete overhaul of these tools which is intended
to address all the short comings of my first attempt. At this point I
am simply outlining the plan. Much of this could change as my plan
continues to smack up against reality.
With that in mind, the scenery generation tools can be subdivided into
four major categories.
\begin{itemize}
\item Libraries which provide basic functionality used by the terrain
tools.
\item Preprocessing tools which convert data from it's original format
(as downloaded from the net) to something that is easier for the
scenery tools to process.
\item Scenery generation tools which assemble and massage the
resulting input data into the Flight Gear scenery format.
\item Miscellaneous utilities
\end{itemize}
\subsection{Libraries}
\subsubsection{GPC}
GPC is the ``Generic Polygon Clipper'' library. It is available from
\url{http://www.cs.man.ac.uk/aig/staff/alan/software}
Please be aware that the licensing terms for the gpc library clash
with the GPL and prevent the source code from being redistributed with
any GPL program. Therefore any developers interested in building the
scenery tools will have to fetch and install this library individually
on their own systems.
\subsubsection{GFC}
GFC is the ``Geographic Foundation Classes'' library. It is available
from:
\url{http://www.geog.psu.edu/~qian/gfc/index.html}
This library allows programs to process GIS shapefiles and extract out
the lon/lat coordinates of the GIS structures.
\subsubsection{DEM}
This library has routines to parse the 3 arcsec DEM file format, and
output a square section corresponding to a specified tile.
\subsubsection{Polygon}
This lib contains routines to assign a unique id number to each
polygon before it is clipped against tial boundaries. We can use this
unique id later on to match up the edges of polygons across tile
boundaries.
This lib also contains routines to track and assign names (types) to
each polygon so we can color it with the correct texture at run time.
\subsubsection{Triangle}
Triangle can be built as a standalone binary, or as a library. For
our uses I am choosing to build it as a library. This library
impliments the delauney triangulation algorithm. It takes a set of
unorder points and finds the optimal triangulation of these points.
For our use we feed in a set of unordered height values and the
triangle library will output a set of triangles that can be rendered
as terrain.
The triangle library does a few more things that are useful. It will
subdivide triangles to ensure that they never get too long and
skinny. It will also let you set up boundaries and holes within the
triangulation area.
\subsection{Scenery Work Space}
The scenery is constructed in a directory structure that parallels the
final structure. The structure looks something like the following:
\begin{verbatim}
Scenery/ ->
w140n50/ ->
w140n60/ ->
w150n50/ ->
w141n59/ ->
w142n59/ ->
w148n59/ ->
533872.gz
533873.gz
533874.gz
\end{verbatim}
Beneath the scenery subdirectory is a series of subdirectories
representing 10x10 degree chunks. Each directory is named after the
lower left hand corner of the area it contains.
Beneath each of the 10x10 degree subdirectories is a subdirectory for
each 1x1 degree area. Within each of these 1x1 degree subdirectories,
is a file for each tile. The file name is the tile's unique numeric
index number. There can be multiple files per tile. When this is
needed, all files relating to a tile will have the same numeric root
for the file name.
\subsection{Preprocessing tools}
The preprocessing tools are responsible for inputing raw world data,
clipping it to the appropriate scenery tiles, and outputing it into
the workspace directory tree.
The scenery assembly and creation tools work on each tile
individually, so they expect all the relevant information for a tile
to already be there.
\subsubsection{DemChop}
This utility inputs 3 arcsec dem files, chops the data up along tile
boundaries and outputs the result into the scenery workspace.
\subsubsection{DemInfo}
Reads the ``A'' record from a 3 arcsec DEM file and dumps some
pertinent information.
\subsubsection{DemRaw2ascii}
This tool will input the 30 arcsec raw DEM format, split it up into 1
x 1 degree sections, and output the result into the 3 arcsec format so
it can be fed through the scenery pipeline. (Note to self, at some
point, this could be updated to work like DemChop and output the tile
chunks directly.)
\subsubsection{GenAirports}
This tools inputs an ascii specification of the airports of the world
that looks like the following:
\begin{verbatim}
A KORD 41.979595 -087.904464 668 CCY Chicago O Hare International
R 04L 41.989606 -087.905138 039.39 7500 150 AHYN NNNL 0 0 NNNO 0 0
R 04R 41.961618 -087.889594 041.40 8071 150 AHYN YNNO 0 0 YNNO 0 0
R 09L 41.983954 -087.903705 089.70 7967 150 AHYN YNNO 0 0 YNNO 0 0
R 09R 41.969040 -087.902380 089.88 10141 150 AHYN YNNO 0 0 YNNO 0 0
R 14L 41.991918 -087.903546 140.10 10003 150 AHYN YNNC 0 0 YNNO 0 0
R 14R 41.976778 -087.917774 140.08 13000 200 AHYN YNNC 0 0 YNNO 0 0
R 18 41.990086 -087.900410 180.00 5341 150 AMNN NNNN 0 0 NNNN 0 0
\end{verbatim}
For each airport, a bounding polygon is generated, and written as a
clipping record for each intersecting tile in the scenery construction
area. The actual airport will belong to the tile containing it's
center point, but the airport will need to be clipped out of the base
terrain from any tiles it might spill over into.
Robin Peel (robin@cpwd.com) maintains this data base, primarily for
use with X-Plane, but lets us use it too. His distribution contians a
much more detailed description of the fields and formats.
\subsubsection{ShapeFile}
The ShapeFile tool will take the polygons from shapefiles (via GFC),
clip them to the appropriate tile boundares (via GPC) and write the
resulting polygons to the appropriate tile in the scenery work space.
The file naming scheme is tile\_index.polygon\_id where tile\_index is
the unique numeric index number for the tile and polygon\_id is a
unique id for the corresponding polygon. Each polygon is assigned a
unique id before it is clipped against tile boundaries. Later we will
need to match up the edges of polygons with the pieces from the
neighboring tiles and this unique polygon id will enable us to do
this. Each polygon that is written out (no matter what the source or
type) should have a unique id number assigned to it.
\subsection{Scenery generation tools}
Issues:
\begin{itemize}
\item Combining height data, polygon data.
\item Triangulating / tri-stripping / tri-fanning.
\item Matching vertices and normals along edges and at corners.
\item Resolving conflicts in data:
overlapping polygon areas.
conflicting height data between airports and DEM data
\end{itemize}
Here's the basic process to create scenery:
Dump the raw data into the appropriate tile areas in the work space.
This includes height data (DEM, airport) and polygon data (airport,
hydro-data, land use data, etc.)
For each tile create a fitted set of ``important height'' points from
the original regular grid of data.
For each tile, run the generic clipper on each polygon in order from
highest to lowest incrementally building an accumulation ``super''
polygon that comprises a union of all polygons we've processed so far
for this tile. For each polygon first clip against this
super-accumlation-polygon. What's left after the clip is the new
shape of the polygon. This is the scheme for eliminating overlapping
features on a priority basis.
For each polygon on a tile we must determine a point inside. We need
this for the triangulation step so we can assign a regional attribute
to all triangles inside a polygon.
Run the delauney triangulator for the tile. The triangulator code is
very powerful and feature rich, but also very obfuscated to use. It
is very robust and fast, but suffers a bit on the usability continuum.
In preparation for the triangulation step we need to create the
following items:
\begin{itemize}
\item A list of all unique vertices (nodes) in this tile, including
the corners
\item A list of all the unique segments (edges of the polygons) in no
particular order. The triangulator doesn't really care how the
polygons connect together, it just cares about boundary edges.
\item A list of ``holes'' (if any) to cut out of the tile. If an
airport overlaps multiple tiles we assign it one tile and leave a
hole in remaining tiles. A hole is specified by a single point.
When the triangulation step is finished, the triangulator will start
at each hole point and recursively eat away all neighboring
triangles until it encounters an edge.
\item A list of regions with region attributes. These are specified
much the same way as holes. After the triangulation step is
finished, regional attributes are assigned. The procedure is
identical to cutting out a hole except that instead of removing a
triangle it is simply assigned the attribute for that region.
\end{itemize}
The result of the triangulation step is a list of triangles for the
tile with each triangle assigned an attribute representing the polygon
it lives inside.
Now we have a pile of triangles. We are heading in the right
direction! However, no we need to go through and assign the proper
height to each of the verticies of the triangles. We must be aware of
certain constraints. Airport elevations should have the highest
priority, followed by the DEM elevations. We will also want to impose
additional constraints such as ensuring lakes are level and rivers
don't run up hill. Anyways, with a flurry of handwaving, we have now
adjusted all the heights. :-)
The next thing we have to worry about is making sure each tile meshes
exactly with all it's neighbors. We do this by spliting the tile up
into it's 4 edges, 4 corners, and the remaining vertices. We write
these parts out as individual files if a neighboring tile hasn't been
processed first. In other words, the first tile to be process gets to
define the shared edge or corner. The neighbor must use this data if
it exists. Then we have to reassemble the tile using any pre-existing
edges from a neighbor tiles that were processed before us and
retriangulate since our node list has changed. <whew>
Unfortunately it's not quite this simple!
We need to be careful, because we have to make sure we also preserve
the polygon connections since lakes, rivers, and even airports often
span multiple tiles.
To do this I propose a scheme of assigning a unique integer id to each
polygon. When writing out the shared edge/corner pieces I also
associate this idea. So rather than disassembling, sharing, and
reassembling whole tiles, we need to do this on a per-polygon basis.
More handwaving and we are off to the next step.
Now, we need to take our 3d, triangulated polygons and tri-fan or
tri-strip them for rendering efficiency. We have been using a
freeware tool called ``stripe'' but it's a typical CSci hack job where
the author was more interested in demonstrating the theory, rather
than demonstrating bug free, robust, well written code. Oh well. I
think I will try to write a utility to combine triangles into fans.
This will help culling (smaller, centralized objects == better
culling) but will happen at the expense of more vertex
transformations. I'm hoping this will result in a net gain. Finger
crossed. :-)
Finally, we need to take our 3d, fan-ified polygons and convert them
to the FGFS scenery format and copy them from the work space directory
tree into the final scenery directory tree.
\subsubsection{Array}
This library reads in the regular grid data written by the DemChop
preprocessing tool. It has a fit routine which approximates the
regular grid of height data with an irregular grid, and interpolate
the elevation of any arbitrary point inside this grid.
An irregular grid can often represent the same level detail as a
regular grid with 4-6x fewer polygons. This is very desirable in a
flight sim where both detail and rendering speed is very important.
Another feature of an irregular grid is that it carries fewer
artifacts that could provide negative training value to pilots. For
instance a regular grid could give a pilot non-realistic cues for
determining north/south/east/west.
\subsubsection{Clipper}
This library makes heavy use of ``the generic polygon clipper''. The
polygons of each tile are clipped against the tile boundaries as well
as any higher priority polygons for that tile. To do this the library
processes the polygons from highest priority to lowest and
incrimentally builds up an accumulation ``super-polygon''. This
super-polygon is the union of all the polygons processed so far. As
each polygon is processed, it is first clipped against this
super-accumlation-polygon. What's left after the clip is the new
shape of the polygon. This is the scheme for eliminating overlapping
features on a priority basis. In the end we can create a base-terrain
polygon out the remaining open areas of the tile that weren't covered
by any other polygons. This way we end up with a set of ``puzzle''
pieces that together form the complete tile with no overlaps and no
gaps.
% \subsubsection{Dem2node}
%
% This tool takes the raw DEM files and calls routines from libDEM.a to
% create the irregular grid approximation of the original data. The
% elevation data is writen to the to the appropriate tile in the scenery
% work space.
% \subsubsection{Areas}
% \subsubsection{AssemTris}
% \subsubsection{FixNode}
% \subsubsection{FixObj}
% \subsubsection{SplitTris}
% \subsubsection{Stripe\_w}
% \subsubsection{Tri2obj}
\subsection{Miscellaneous Utilities}
\subsubsection{tile-sizes.pl}
Generates the width of a 1/8 x 1/8 degree tile at various latitudes.
\end{document}
%------------------------------------------------------------------------

View file

@ -1,47 +0,0 @@
#FIG 3.2
Landscape
Center
Inches
Letter
100.00
Single
0
1200 2
5 1 0 1 0 7 0 0 -1 0.000 0 1 0 0 6900.000 3304.688 5100 5700 6975 6300 8700 5700
5 1 1 1 0 7 0 0 -1 4.000 0 0 0 0 6900.000 8100.000 5100 5700 6900 5100 8700 5700
5 1 0 1 0 7 0 0 -1 4.000 0 0 0 0 6900.000 5175.000 5925 5100 6075 4650 6375 4350
5 1 0 1 0 7 0 0 -1 4.000 0 0 0 0 8887.500 5062.500 6600 5325 6600 4800 6675 4425
5 1 0 1 0 7 0 0 -1 4.000 0 1 0 0 6675.000 3975.000 5925 5100 6225 5250 6600 5325
5 1 0 1 0 7 0 0 -1 4.000 0 1 0 0 6600.000 4087.500 6375 4350 6525 4425 6675 4425
1 3 0 1 0 7 0 0 -1 0.000 1 0.0000 6900 5700 1802 1802 6900 5700 8700 5775
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
2 1 1.00 60.00 120.00
6300 4800 6300 3600
2 1 0 2 0 7 0 0 -1 0.000 0 0 -1 1 0 2
2 1 2.00 120.00 240.00
6900 5700 9300 5700
2 1 0 2 0 7 0 0 -1 0.000 0 0 -1 1 0 2
2 1 2.00 120.00 240.00
6900 5700 7800 4800
2 1 0 2 0 7 0 0 -1 0.000 0 0 -1 1 0 2
2 1 2.00 120.00 240.00
6900 5700 6900 3300
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
2 1 1.00 60.00 120.00
6300 4800 7200 4800
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
2 1 1.00 60.00 120.00
6300 4800 6750 4350
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
0 0 1.00 60.00 120.00
6900 5700 6300 4800
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
0 0 1.00 60.00 120.00
6075 4950 6300 4950
4 0 0 0 0 0 14 0.0000 4 150 120 6825 3150 Z\001
4 0 0 0 0 0 14 0.0000 4 150 135 7875 4800 Y\001
4 0 0 0 0 0 14 0.0000 4 150 150 9450 5775 X\001
4 0 0 0 0 0 12 0.0000 4 135 135 7275 4875 X\001
4 0 0 0 0 0 12 0.0000 4 135 135 6675 4275 Y\001
4 0 0 0 0 0 12 0.0000 4 135 120 6300 3525 Z\001
4 0 0 0 0 0 12 0.0000 4 90 90 6150 5100 a\001

View file

@ -1,50 +0,0 @@
Basically what I'm doing is starting with the 3 arcsec DEM files (a
point every 100 meters roughly.)
I start out at one corner and walk down a horizonal row. I start with
the first 2 points and do a least squares fit, I then add the next
point, and the next, and the next until my least squares fit exceeds
some error tolerance from the original data. At that point, I back up
one point and include that point in the output set of points. This
point then becomes my new starting point for the least squares fit. I
repeat this until I finish the row. I do this for each row to produce
an "irregular" set of output points from the original. I'm sure from
a pure mathematical perspective you can see some potential flaws in
this approach, but the actual real life result is actually quite good.
I then do a Delauney triangulation of these points (and add in more to
keep the triangles from getting too long and skinny.)
I have to go through additional pain to make sure that all the points
coincide on the edge between two adjacent areas (and the normals to so
there is continuity in the shading.)
I then run a "tri-striper" program to connect up all the individual
triangles into more efficient opengl strips.
Finally I post process everything to compensate for bugs in our lousy
tri-striper and to add in a few other things that our render requires.
There is a wee bit of documentation at:
http://www.menet.umn.edu/~curt/fgfs/Docs/Scenery/CoordinateSystem/CoordinateSystem.html
Here I lay out our basic coordinate system. Essentially the scenery
tiles that result in the above process are just cutouts of the Earths
surface. The maintain the curved shape and spacial orientation. The
renderer translates everything to near (0,0,0) to compensate for
GLfloat precision limitations.
All the tools I use to do this are distributed with the FG source, so
feel free to download them, play around, and ask questions.
Our resulting scenery tile format is structured to facilitate view
frustum culling on a per tile basis as well as a per "fragment" basis.
The next thing I plan to work on is sorting by material properties.
As I walk through the tile structures doing my view frustum culling,
instead of immediately rendering the visible fragments, I plan to toss
them into buckets by material property. Then I make a pass through
each of these buckets, rendering all the items with like properties.
This should minimize opengl state and texture changes which should
help keep the performance from going in the dumpster.

View file

@ -1,16 +0,0 @@
#FIG 3.2
Landscape
Center
Inches
Letter
100.00
Single
0
1200 2
5 1 0 1 0 7 0 0 -1 0.000 0 1 0 0 6900.000 3304.688 5100 5700 6975 6300 8700 5700
5 1 1 1 0 7 0 0 -1 4.000 0 0 0 0 6900.000 8100.000 5100 5700 6900 5100 8700 5700
5 1 0 1 0 7 0 0 -1 4.000 0 0 0 0 6900.000 5175.000 5925 5100 6075 4650 6375 4350
5 1 0 1 0 7 0 0 -1 4.000 0 0 0 0 8887.500 5062.500 6600 5325 6600 4800 6675 4425
5 1 0 1 0 7 0 0 -1 4.000 0 1 0 0 6675.000 3975.000 5925 5100 6225 5250 6600 5325
5 1 0 1 0 7 0 0 -1 4.000 0 1 0 0 6600.000 4087.500 6375 4350 6525 4425 6675 4425
1 3 0 1 0 7 0 0 -1 0.000 1 0.0000 6900 5700 1802 1802 6900 5700 8700 5775

View file

@ -1,224 +0,0 @@
%
% `Sky.tex' -- describes the sky rendering procedure
%
% Written by Curtis Olson. Started December, 1997.
%
% $Id$
%------------------------------------------------------------------------
\documentclass[12pt]{article}
\usepackage{anysize}
\papersize{11in}{8.5in}
\marginsize{1in}{1in}{1in}{1in}
\usepackage{amsmath}
\usepackage{epsfig}
\usepackage{setspace}
\onehalfspacing
\usepackage{url}
\begin{document}
\title{
Flight Gear Sky Representation and Rendering.
}
\author{
Curtis L. Olson\\
(\texttt{curt@me.umn.edu})
}
\maketitle
\section{Introduction}
No flight simulator should be without a nice sky that smoothly
transitions into haze at the horizon. Such a sky should also be able
to render sunrise and sunset effects. This document describes how we
have implemented such a sky.
\section{Overview}
The sky is represent as a 12 sided dome (or upside down bowl if you
prefer.) Figure \ref{fig:dome} shows how a 6 sided dome might be
constructed.
\begin{figure}[hbt]
\centerline{
\psfig{file=dome.eps}
}
\caption{Simplified (6 Sided) Sky Dome}
\label{fig:dome}
\end{figure}
The center section can be constructed with a triangle fan. The inner
and outer ``skirts'' can be constructed with triangle strips.
The colors of each vertex can be independently controlled to achieve
sky to haze transitions, sunrise/sunset effects with a pinkish/oranges
glow, and one side of the sky can easily be made brighter than the
other. By enabling smooth shading in OpenGL, the colors will be
blended together for a very nice effect.
\section{Implementation}
This sections describes how the sky has been implemented in OpenGL.
\subsection{Vertex Generation}
The sky dome structure is intended to be centered over the current
view point at sea level. This way we could paste cloud textures on
the dome if we liked. So, we simply have to generate vertices for a
fixed dome, and then use OpenGL calls to transform and rotate it to
the desired place. Please refer to the actual code
(.../Src/Scenery/sky.c) for specifics, but
to generate the vertices we simply create a 12 element array for the
inner set of vertices, another 12 element array for the middle set of
vertices and a last 12 element array for the outer set of vertices.
\subsection{Vertex Coloring}
For each vertex position array, there is a corresponding vertex color
array. This way we don't have to compute each vertex color every
iteration. Also, by being able to individually control the color at
each vertex, we can do all sorts of nice sky to haze blending with
dusk and dawn effects. Again, please refer to the source
(.../Src/Scenery/sky.c) for specific details on how the coloring is
implemented. However, here's the quick overview.
\subsubsection{Day and Night Coloring}
For the general middle of the day, or middle of the night sky, we
already know the desired sky color, and the haze color. This is
computed elsewhere based on the current sun position. During the
night these colors are both nearly black. During the dawn they are
smoothly transitioned to day time colors. And, during the dusk they
are smoothly transitioned back to night time colors.
The center of the dome is assigned the current sky color. The color
of the first inner ring of vertices is weighted 70\% towards the sky
color and 30\% towards the fog color.
Then color of the middle ring of vertices is weighted 10\% towards the
sky color and 90\% towards the fog color.
The the outer ring of vertices are assigned the current fog color.
\subsubsection{Dusk and Dawn Effects}
Dusk and dawn effects can be accomplished by controlling the color of
the vertices. Rather than trying to figure out which vertices are
near the current sun position, I just rotate the dome so the 0'th
vertex of each ring (and the center fan) align with the sun. This
makes it easier to calculate vertex colors. But, there is a fair
amount of work involved in calculating the proper dome rotation.
\begin{figure}[hbt]
\centerline{
\psfig{file=earth.eps}
}
\caption{Overview of Earth}
\label{fig:earth}
\end{figure}
Figure \ref{fig:earth} shows an overview of the setup. $P$, the
current view position, and $\mathbf{n}$, the local ``up'' vector,
define the plane which is tangent to the Earth's surface at point $P$.
Just for a quick review of your linear algebra, given $\mathbf{v_0}$,
the position vector of $P$ and $\mathbf{v}$, the position vector of
some other arbitrary point on the plane, and $\mathbf{n}$, the normal
to the plane, then the vector $\mathbf{n}$ and the vector $(\mathbf{v}
- \mathbf{v_0})$ are orthogonal (perpendicular.) If the two vectors
are orthogonal then their dot product will be zero, so the following
must be true:
\begin{equation}
\mathbf{n} \cdot ( \mathbf{v} - \mathbf{v_0} ) = 0
\end{equation}
This is the vector equation of the plane and can be rewritten as:
\begin{align}
a(x - x_0) + b(y - y_0) + c(z - z_0) &= 0 \\
ax + by + cz - (\mathbf{n} \cdot \mathbf{v_0}) &= 0
\end{align}
We want to find a vector $\mathbf{v}$ representing the
direction along the current tangent plane towards the position on the
Earth where the Sun is directly overhead. The vector $\mathbf{u}$ is
defined as $\vec{\mathbf{PS}}$.
\begin{figure}[hbt]
\centerline{
\psfig{file=local.eps}
}
\caption{Vectors and Points in Local Coordinate System}
\label{fig:local}
\end{figure}
Figure \ref{fig:local} shows a more detailed ``local'' view of the
points and vectors involved. The point, $P$, is the current view
point. The vector, $\mathbf{n}$, is the local up vector. $S$
represents the current position on the Earth's surface where the Sun
is directly overhead. We want to find the vector, $\mathbf{v}$ which
is a projection of $\mathbf{u}$ onto the plane defined by $P$ and
$\mathbf{n}$.
To do this we first calculate $\mathbf{u_1}$ which is the shortest
distance from point $S$ to the tangent plane.
\begin{equation}
\mathbf{u_1} = \frac { \mathbf{n} \cdot \mathbf{u} }
{ {\| \mathbf{n} \|}^2 } \mathbf{n}
\end{equation}
Armed with $\mathbf{u_1}$ we can now calculate
$\mathbf{v}$ which is the local surface direction on the tangent
plane towards the sun, $S$.
\begin{equation}
\mathbf{v} = \mathbf{v_0} + \mathbf{u} - \mathbf{u_1}
\end{equation}
Ok, so now we have $\mathbf{v}$, but the fun doesn't stop here. Now
we need to calculate a rotation angle $\theta$ about $\mathbf{n}$ to
align our dome with $\mathbf{v}$. The origin of the dome always
aligns with a vector pointing directly South. So, we need to repeat
the above procedure to map a vector pointing straight down $( 0, 0,
-\mathbf{z} )$ onto our tangent plane to produce the local, surface,
south vector $\mathbf{w}$. We then take the $\arccos()$ of the dot product
of $\mathbf{v}$ with $\mathbf{w}$.
\begin{equation}
\theta = \arccos( \mathbf{v} \cdot \mathbf{w} )
\end{equation}
Whew, that gives us the angle we want. Well almost, not quite. The
problem is that the dot product returns a number in the range of
$(-1.0 \ldots 1.0)$. Thus, the $\arccos()$ function returns a $\theta$
in the range of $(0.0 \ldots 180.0)$. But this is not enough
information to determine if $\mathbf{v}$ is in the east hemisphere or
west hemisphere and if this angle should be positive or negative.
So, to get that last piece of information we need, we can rotate the
vector $\mathbf{w}$ by 90 degrees about $\mathbf{n}$. This gives us
the local surface east vector on the tangent plane. Taking the dot
product of $\mathbf{v}$ and the local east vector tells us which
hemisphere $\mathbf{v}$ is in. And, from this, we can uniquely
determine the proper angle for the sky dome rotation.
\end{document}
%------------------------------------------------------------------------

View file

@ -1,47 +0,0 @@
#FIG 3.2
Portrait
Center
Inches
Letter
100.00
Single
0
1200 2
2 1 0 2 0 7 0 0 -1 0.000 0 0 -1 0 0 7
4800 2700 3375 3450 4050 4500 6600 4500 7725 3450 6750 2700
4800 2700
2 1 0 2 0 7 0 0 -1 0.000 0 0 -1 0 0 8
3375 3450 2700 4500 2400 5400 3300 7200 7500 7200 8700 5400
8400 4500 7725 3450
2 1 0 2 0 7 0 0 -1 0.000 0 0 -1 0 0 4
2700 4500 3450 5850 7200 5850 8400 4500
2 1 0 2 0 7 0 0 -1 0.000 0 0 -1 0 0 3
3300 7200 3450 5850 4050 4500
2 1 0 2 0 7 0 0 -1 0.000 0 0 -1 0 0 3
6600 4500 7200 5850 7500 7200
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
3375 3450 3450 5850
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
4050 4500 7200 5850
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
6600 4500 8400 4500
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
2700 4500 3300 7200
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
3450 5850 7500 7200
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
7200 5850 8700 5400
2 1 2 1 0 7 0 0 -1 4.000 0 0 -1 0 0 4
2700 4500 4125 3600 7275 3600 8400 4500
2 1 2 1 0 7 0 0 -1 4.000 0 0 -1 0 0 3
6750 2700 7275 3600 7350 4350
2 1 0 1 0 7 0 0 -1 4.000 0 0 -1 0 0 3
4050 4500 5625 3075 6750 2700
2 1 0 1 0 7 0 0 -1 4.000 0 0 -1 0 0 3
4800 2700 5625 3075 6600 4500
2 1 2 1 0 7 0 0 -1 4.000 0 0 -1 0 0 4
2400 5400 4050 4350 7350 4350 8700 5400
2 1 2 1 0 7 0 0 -1 4.000 0 0 -1 0 0 3
4050 4350 4125 3600 4800 2700
2 1 0 1 0 7 0 0 -1 4.000 0 0 -1 0 0 3
3375 3450 5625 3075 7725 3450

View file

@ -1,44 +0,0 @@
#FIG 3.2
Landscape
Center
Inches
Letter
100.00
Single
-2
1200 2
5 1 0 2 0 7 0 0 -1 0.000 0 1 0 0 4800.000 -4650.000 2400 4800 4800 5100 7200 4800
5 1 0 2 0 7 0 0 -1 0.000 0 0 0 0 14250.000 4800.000 4800 7200 4500 4800 4800 2400
5 1 2 1 0 7 0 0 -1 3.000 0 1 0 0 -4650.000 4800.000 4800 7200 5100 4800 4800 2400
5 1 2 1 0 7 0 0 -1 3.000 0 0 0 0 4800.000 14250.000 2400 4800 4800 4500 7200 4800
1 3 0 2 0 7 0 0 -1 0.000 1 0.0000 4800 4800 2400 2400 4800 4800 7200 4800
1 3 0 1 0 -1 0 0 20 0.000 1 0.0000 4800 4800 25 25 4800 4800 4820 4815
1 3 0 1 0 -1 0 0 20 0.000 1 0.0000 6300 4200 25 25 6300 4200 6320 4215
2 1 2 1 0 7 0 0 -1 3.000 0 0 -1 0 0 2
4500 5100 5100 4500
2 1 0 1 0 7 0 0 -1 4.000 0 0 -1 0 0 2
6600 5400 7800 4200
2 1 2 1 0 7 0 0 -1 3.000 0 0 -1 0 0 2
2400 4800 7200 4800
2 1 0 2 0 7 0 0 -1 6.000 0 0 -1 0 0 5
6600 4200 6600 6600 7800 5400 7800 3000 6600 4200
2 1 0 1 0 7 0 0 -1 4.000 0 0 -1 0 0 2
7200 3600 7200 6000
2 1 0 1 0 -1 0 0 20 4.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
7200 4800 6750 4200
2 1 0 1 0 -1 0 0 20 4.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
7200 4800 6300 4200
2 1 2 1 0 -1 0 0 20 3.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
6750 4200 6300 4200
2 1 0 1 0 -1 0 0 20 4.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
7200 4800 8100 4800
4 0 0 0 0 0 14 0.0000 4 105 105 8175 4875 n\001
4 0 0 0 0 0 14 0.0000 4 150 120 7275 5025 P\001
4 0 0 0 0 0 14 0.0000 4 105 105 6825 4200 v\001
4 0 0 0 0 0 14 0.0000 4 195 645 5625 4275 S (Sun)\001
4 0 0 0 0 0 14 0.0000 4 105 105 6375 4500 u\001
4 0 0 0 0 0 14 0.0000 4 195 525 4800 5025 Origin\001

View file

@ -1,45 +0,0 @@
#FIG 3.2
Landscape
Center
Inches
Letter
100.00
Single
-2
1200 2
1 3 0 1 0 -1 0 0 20 0.000 1 0.0000 4500 8700 21 21 4500 8700 4515 8715
1 3 0 1 0 -1 0 0 20 0.000 1 0.0000 6900 8100 21 21 6900 8100 6915 8115
1 3 0 1 0 -1 0 0 20 0.000 1 0.0000 6900 6600 21 21 6900 6600 6915 6615
1 3 0 1 0 -1 0 0 20 0.000 1 0.0000 5700 6000 21 21 5700 6000 5715 6015
2 1 0 2 0 7 0 0 -1 0.000 0 0 -1 0 0 5
1800 7200 4200 4800 9600 4800 7200 7200 1800 7200
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
4500 7200 6900 4800
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
3000 6000 8400 6000
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
5700 6000 5700 4200
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
5700 6000 6900 8100
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
5700 6000 6900 6600
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
0 0 1.00 60.00 120.00
6900 6600 6900 8100
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
4500 8700 5686 5994
4 0 0 0 0 0 14 0.0000 4 105 105 6825 6450 v\001
4 0 0 0 0 0 14 0.0000 4 195 645 6750 8325 S (Sun)\001
4 0 0 0 0 0 14 0.0000 4 105 105 6975 7500 u\001
4 0 0 0 0 0 10 0.0000 4 105 75 7080 7568 1\001
4 0 0 0 0 0 14 0.0000 4 195 525 4200 8925 Origin\001
4 0 0 0 0 0 14 0.0000 4 150 120 5475 5850 P\001
4 0 0 0 0 0 10 0.0000 4 105 75 5550 5925 0\001
4 0 0 0 0 0 14 0.0000 4 105 105 5625 6375 v\001
4 0 0 0 0 0 10 0.0000 4 105 75 5700 6450 0\001
4 0 0 0 0 0 14 0.0000 4 105 105 6450 7725 u\001
4 0 0 0 0 0 14 0.0000 4 105 105 5625 4125 n\001

View file

@ -1,635 +0,0 @@
One place to find this document is at:
ftp://sundae.triumf.ca/pub/peter/nmeafaq.txt
---------------------------------------------------------------------------
The NMEA FAQ
Version 6.1 Sept. 15, 1997
(NMEA URL updated)
Additions, corrections, and comments should be emailed to the author,
Peter Bennett bennett@triumf.ca
Contents:
1. What is NMEA?
1.1 What is an NMEA Standard
1.2 NMEA Address
2. Electrical Interface
3. NMEA-0180 and NMEA-0182
3.1 Simple Format
3.2 Complex Format
4. NMEA-0183
4.1 General Sentence Format
4.2 Sentences sent by specific equipment
4.3 Sample Sentences Dissected
4.3.1 Standard Sentences
4.3.2 Garmin Proprietary Sentences
5. RS-232 connections
6. Troubleshooting
7. About the author
7.1 Acknowledgements
1. What is NMEA?
The National Marine Electronics Association is dedicated to the
education and advancement of the marine electronics industry and
the market which it serves.
It is a non-profit association composed of manufacturers,
distributors, dealers, educational institutions, and others
interested in peripheral marine electronics occupations
(quoted from a promo in "NMEA News")
1.1 What is an NMEA standard?
For the purposes of this article, an NMEA standard defines an
electrical interface and data protocol for communications
between marine instrumentation. (They may also have standards
for other things.)
1.2 NMEA Address
P.O. Box 3435
New Bern NC, 28564-3435
U.S.A.
Phone: 919-638-2626
Fax: 919-638-4885
email: nmea@coastalnet.com
web page: http://www4.coastalnet.com/nmea/default.html
2. Electrical Interface
These standards allow a single "talker", and several "listeners"
on one circuit. The recommended interconnect wiring is a
shielded twisted pair, with the shield grounded only at the
talker. The standards do not specify the use of any particular
connector.
The NMEA-0180 and 0182 standards say that the talker output may
be RS-232, or from a TTL buffer, capable of delivering 10 mA at
4 V. A sample circuit shows an open collector TTL buffer with a
680 ohm resistor to +12 V, and a diode to prevent the output
voltage from rising above +5.7 V.
NMEA-0183 accepts this, but recommends that the talker output
comply with EIA-422. This is a differential system, having two
signal lines, A and B. The voltages on the "A" line correspond
to those on the older TTL single wire, while the "B" voltages
are reversed (while "A" is at +5, "B" is at ground, and vice
versa)
In either case, the recommended receive circuit uses an
opto-isolator with suitable protection circuitry. The input
should be isolated from the receiver's ground.
In practice, the single wire, or the EIA-422 "A" wire may be
directly connected to a computer's RS-232 input.
3. NMEA-0180 and NMEA 0182
NMEA-0180 and 0182 are very limited, and just deal with
communcations from a Loran-C (or other navigation receiver,
although the standards specifically mention Loran), and an
autopilot.
From the information I have, it appears that 0180 and 0182 are
identical. I suspect that equipment claiming to use NMEA-0180
will use the "simple" format described below, while those using
NMEA-0182 will use the "complex" format. (but this is really
just a guess... corrections??)
3.1 "Simple" data format
The simple format consists of a single data byte transmitted at
intervals of 0.8 to 5 seconds, at 1200 baud with odd parity.
Bits 5 - 0 give the cross-track error in units of 0.1 uS or 0.01
nautical mile. The error is given in offset binary, with a
count of 1 representing full scale right error, 32 (hex 20) for
on course, and 63 (hex 3f) full scale left error. Bit 6 is a 1
if the data is valid, and bit 7 is 0 to indicate the simple
data format.
3.2 "Complex" data format
The complex format consists of a data block of 37 bytes of
(mostly) readable ASCII text giving cross-track error, bearing
to waypoint, present Lat/Long, and a binary status byte. The
data block shall be sent at intervals of 2 to 8 sec. All bytes
in the complex format have bit 7 = 1 to distinguish them from
the simple format. It is permissible for a sending device to
send both simple and complex data, and even to send a "simple"
data byte in the middle of a "complex" data block.
Byte Data
1 $
2 M | device
3 P | address
4 K = kilometres | cross track
N = nautical miles | error
U = microseconds | units
5 - 8 0 - 9 or . cross track error value
9 L or R cross track error position
10 T or M True or Magnetic bearing
11 - 13 0 - 9 bearing to next waypoint
14 - 23 12D34'56"N or present latitude
12D34.56'N
24 - 34 123D45'56"W or present longitude
123D45.67"W
35 non-ASCII status byte
bit 0 = 1 for manual cycle lock
1 = 1 low SNR
2 = 1 cycle jump
3 = 1 blink
4 = 1 arrival alarm
5 = 1 discontinuity of TDs
6 = 1 always
36 "NUL" character (hex 80)(reserved status byte)
37 "ETX" character (hex 83)
Any unavailable data is filled with "NUL" bytes.
4. NMEA-0183
4.1 General Sentence Format
Under the NMEA-0183 standard, all characters used are printable
ASCII text (plus carriage return and line feed). NMEA-0183 data
is sent at 4800 baud.
The data is transmitted in the form of "sentences". Each
sentence starts with a "$", a two letter "talker ID", a three
letter "sentence ID", followed by a number of data fields
separated by commas, and terminated by an optional checksum, and
a carriage return/line feed. A sentence may contain up to 82
characters including the "$" and CR/LF.
If data for a field is not available, the field is simply
omitted, but the commas that would delimit it are still sent,
with no space between them.
Since some fields are variable width, or may be omitted as
above, the receiver should locate desired data fields by
counting commas, rather than by character position within the
sentence.
The optional checksum field consists of a "*" and two hex digits
representing the exclusive OR of all characters between, but not
including, the "$" and "*". A checksum is required on some
sentences.
The standard allows individual manufacturers to define
proprietary sentence formats. These sentences start with "$P",
then a 3 letter manufacturer ID, followed by whatever data the
manufacturer wishes, following the general format of the
standard sentences.
Some common talker IDs are:
GP Global Positioning System receiver
LC Loran-C receiver
OM Omega Navigation receiver
II Integrated Instrumentation
(eg. AutoHelm Seatalk system)
4.2 Sentences sent by specific equipment
This section lists the sentence types used by various equipment.
The format and data included in each sentence type is given in
section 4.3.
Eagle AccuNav
Standard: RMB, RMC, GLL, APB
Proprietary: PSLIB
It also pretends it's a Loran, sending LCGLL, as well as GPGLL
Garmin GPS-38, NMEA-0183 V. 1.5 mode
Standard: GLL, RMB, RMC, WPL, BOD, XTE, VTG, BWC
Proprietary: PGRMM (map datum), PGRMZ (altitude), PSLIB (dgps ctrl)
Garmin GPS-38, NMEA-0183 V. 2.0 mode
Standard: GLL, RMB, RMC, WPL, BOD, GSA, GSV, RTE, GGA
Proprietary: PGRME (estimated error), PGRMM, PGRMZ, PSLIB
Garmin GPS-45 (and probably GPS-40 and GPS-90)
Standard: BOD, GLL, RTE, RMB, RMC, GGA, GSA, GSV
Proprietary: PGRME, PGRMM, PGRMZ
Garmin GPS-65 (and probably GPS-75)
Standard: BWC, GLL, RMB, RMC, R00, WPL, XTE, VTG
Proprietary: PGRMM, PGRMZ, PSLIB
Magellan Trailblazer
Standard: APB, BWC, GGA, GLL, RMB, RMC, VTG
Trimble Ensign XL
Standard: APA, BWC, BWR, GGA, GLL, RMB
Trimble Flightmate Pro and Scoutmaster
Standard: APA, APB, BWC, GGA, GLL, GSA, GSV, RMB, RMC,
VTG, WCV, XTE, ZTC
Autohelm Seatalk
Autohelm Seatalk is a proprietary bus for communications
between various intruments. Some of the instruments can act
as NMEA-0183 talkers or listeners. Data received from an
external NMEA-0183 device will, if Seatalk understands the
sentence, be re-transmitted, but not necessarily in the same
sentence type.
The specific sentences sent will depend on the data
available on the Seatalk bus (i.e. sentences containing wind
speed and direction will only be sent if the system includes
a wind instrument)
Seatalk output:
Standard: APB, BPI, BWC, VWR, VHW, DBT, GLL, HDM, HDT, HCS,
MTW, VTG
Seatalk input:
Standard: APA, APB, RMB, XTE, XTR, BPI, BWR, BWC, BER,
BEC,WDR, WDC, BOD, WCV, VHW, VWR, DBT
4.3 Sample Sentences Dissected
4.3.1 Standard Sentences
A talker typically sends a group of sentences at intervals
determined by the unit's update rate, but generally not more
often than once per second.
Characters following the "*" are a checksum. Checksums are
optional for most sentences, according to the standard.
APB - Autopilot format B
APB,A,A,0.10,R,N,V,V,011,M,DEST,011,M,011,M
A Loran-C blink/SNR warning
A Loran-C cycle warning
0.10 cross-track error distance
R steer Right to correct (or L for Left)
N cross-track error units - nautical miles
V arrival alarm - circle
V arrival alarm - perpendicular
011,M magnetic bearing, origin to destination
DEST destination waypoint ID
011,M magnetic bearing, present position to destination
011,M magnetic heading to steer
(bearings could be given in True as 033,T)
(note: some pilots, Roberston in particular, misinterpret "bearing
from origin to destination" as "bearing from present position to
destination". This apparently results in poor performance if the
boat is sufficiently off-course that the two bearings are
different.)
BOD - Bearing - origin to destination waypoint
BOD,045.,T,023.,M,DEST,START
045.,T bearing 045 True from "START" to "DEST"
023.,M breaing 023 Magnetic from "START" to "DEST"
DEST destination waypoint ID
START origin waypoint ID
BWC - Bearing and distance to waypoint - great circle
BWC,225444,4917.24,N,12309.57,W,051.9,T,031.6,M,001.3,N,004*29
225444 UTC time of fix 22:54:44
4917.24,N Latitude of waypoint
12309.57,W Longitude of waypoint
051.9,T Bearing to waypoint, degrees true
031.6,M Bearing to waypoint, degrees magnetic
001.3,N Distance to waypoint, Nautical miles
004 Waypoint ID
BWR - Bearing and distance to waypoint - rhumb line
(format same as BWC)
DBT - Depth below transducer
DBT,0017.6,f,0005.4,M
0017.6,f 17.6 feet
0005.4,M 5.4 Metres
GGA - Global Positioning System Fix Data
GGA,123519,4807.038,N,01131.324,E,1,08,0.9,545.4,M,46.9,M, , *42
123519 Fix taken at 12:35:19 UTC
4807.038,N Latitude 48 deg 07.038' N
01131.324,E Longitude 11 deg 31.324' E
1 Fix quality: 0 = invalid
1 = GPS fix
2 = DGPS fix
08 Number of satellites being tracked
0.9 Horizontal dilution of position
545.4,M Altitude, Metres, above mean sea level
46.9,M Height of geoid (mean sea level) above WGS84
ellipsoid
(empty field) time in seconds since last DGPS update
(empty field) DGPS station ID number
GLL - Geographic position, Latitude and Longitude
GLL,4916.45,N,12311.12,W,225444,A
4916.46,N Latitude 49 deg. 16.45 min. North
12311.12,W Longitude 123 deg. 11.12 min. West
225444 Fix taken at 22:54:44 UTC
A Data valid
(Garmin 65 does not include time and status)
GSA - GPS DOP and active satellites
GSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39
A Auto selection of 2D or 3D fix (M = manual)
3 3D fix
04,05... PRNs of satellites used for fix (space for 12)
2.5 PDOP (dilution of precision)
1.3 Horizontal dilution of precision (HDOP)
2.1 Vertical dilution of precision (VDOP)
DOP is an indication of the effect of satellite geometry on
the accuracy of the fix.
GSV - Satellites in view
GSV,2,1,08,01,40,083,46,02,17,308,41,12,07,344,39,14,22,228,45*75
2 Number of sentences for full data
1 sentence 1 of 2
08 Number of satellites in view
01 Satellite PRN number
40 Elevation, degrees
083 Azimuth, degrees
46 Signal strength - higher is better
<repeat for up to 4 satellites per sentence>
There my be up to three GSV sentences in a data packet
HDM - Heading, Magnetic
HDM,235.,M
HDM Heading, Magnetic
235.,M Heading 235 deg. Magnetic
(HDG, which includes deviation and variation, is recommended
instead)
HSC - Command heading to steer
HSC,258.,T,236.,M
258.,T 258 deg. True
236.,M 136 deg. Magnetic
MTW - Water temperature, Celcius
MTW,11.,C
11.,C 11 deg. C
R00 - List of waypoint IDs in currently active route
R00,MINST,CHATN,CHAT1,CHATW,CHATM,CHATE,003,004,005,006,007,,,*05
(This sentence is produced by a Garmin 65, but is not listed
in Version 2.0 of the standard. The standard lists RTE for
this purpose.)
RMB - Recommended minimum navigation information (sent by nav.
receiver when a destination waypoint is active)
RMB,A,0.66,L,003,004,4917.24,N,12309.57,W,001.3,052.5,000.5,V*0B
A Data status A = OK, V = warning
0.66,L Cross-track error (nautical miles, 9.9 max.),
steer Left to correct (or R = right)
003 Origin waypoint ID
004 Destination waypoint ID
4917.24,N Destination waypoint latitude 49 deg. 17.24 min. N
12309.57,W Destination waypoint longitude 123 deg. 09.57 min. W
001.3 Range to destination, nautical miles
052.5 True bearing to destination
000.5 Velocity towards destination, knots
V Arrival alarm A = arrived, V = not arrived
*0B mandatory checksum
RMC - Recommended minimum specific GPS/Transit data
RMC,225446,A,4916.45,N,12311.12,W,000.5,054.7,191194,020.3,E*68
225446 Time of fix 22:54:46 UTC
A Navigation receiver warning A = OK, V = warning
4916.45,N Latitude 49 deg. 16.45 min North
12311.12,W Longitude 123 deg. 11.12 min West
000.5 Speed over ground, Knots
054.7 Course Made Good, True
191194 Date of fix 19 November 1994
020.3,E Magnetic variation 20.3 deg East
*68 mandatory checksum
RTE - Waypoints in active route
RTE,2,1,c,0,W3IWI,DRIVWY,32CEDR,32-29,32BKLD,32-I95,32-US1,BW-32,BW-198*69
2 two sentences for full data
1 this is sentence 1 of 2
c c = complete list of waypoints in this route
w = first listed waypoint is start of current leg
0 Route identifier
W3IWI... Waypoint identifiers
VHW - Water speed and heading
VHW,259.,T,237.,M,05.00,N,09.26,K
259.,T Heading 259 deg. True
237.,M Heading 237 deg. Magnetic
05.00,N Speed 5 knots through the water
09.26,K Speed 9.26 KPH
VWR - Relative wind direction and speed
VWR,148.,L,02.4,N,01.2,M,04.4,K
148.,L Wind from 148 deg Left of bow
02.4,N Speed 2.4 Knots
01.2,M 1.2 Metres/Sec
04.4,K Speed 4.4 Kilometers/Hr
VTG - Track made good and ground speed
VTG,054.7,T,034.4,M,005.5,N,010.2,K
054.7,T True track made good
034.4,M Magnetic track made good
005.5,N Ground speed, knots
010.2,K Ground speed, Kilometers per hour
WCV - Waypoint Closure Velocity
WDC - Distance to Waypoint
WDR - Waypoint Distance, Rhumb Line
WPL - waypoint location
WPL,4917.16,N,12310.64,W,003*65
4917.16,N Latitude of waypoint
12310.64,W Longitude of waypoint
003 Waypoint ID
When a route is active, this sentence is sent once for each
waypoint in the route, in sequence. When all waypoints have
been reported, GPR00 is sent in the next data set. In any
group of sentences, only one WPL sentence, or an R00
sentence, will be sent.
XTE - Cross track error, measured
XTE,A,A,0.67,L,N
A General warning flag V = warning
(Loran-C Blink or SNR warning)
A Not used for GPS (Loran-C cycle lock flag)
0.67 cross track error distance
L Steer left to correct error (or R for right)
N Distance units - Nautical miles
XTR - Cross-Track Error - Dead Reckoning
XTR,0.67,L,N
0.67 cross track error distance
L Steer left to correct error (or R for right)
N Distance units - Nautical miles
4.3.2 Proprietary Sentences
The following are Garmin proprietary sentences. "P" denotes
proprietary, "GRM" is Garmin's manufacturer code, and "M" or "Z"
indicates the specific sentence type.
$PGRME,15.0,M,45.0,M,25.0,M*22
15.0,M Estimated horizontal position error in metres (HPE)
45.0,M Estimated vertical error (VPE) in metres
25.0,M Overall spherical equivalent position error
$PGRMZ,93,f,3*21
93,f Altitude in feet
3 Position fix dimensions 2 = user altitude
3 = GPS altitude
This sentence shows in feet, regardless of units shown on the display.
$PGRMM,NAD27 Canada*2F
Currently active horizontal datum
Proprietary sentences to control a Starlink differential beacon
receiver. (I assume Garmin's DBR is made by Starlink)
$PSLIB,,,J*22
$PSLIB,,,K*23
These two sentences are normally sent together in each group
of sentences from the GPS.
The three fields are: Frequency, bit Rate, Request Type. The
value in the third field may be:
J = status request
K = configuration request
blank = tuning message
When the GPS receiver is set to change the DBR frequency or
baud rate, the "J" sentence is replaced (just once) by (for
example): $PSLIB,320.0,200*59 to set the DBR to 320 KHz, 200
baud.
5. RS-232 connections
Although this is not really related to NMEA, many people want to
connect a GPS to a computer, so need to know about the RS-232
serial ports on a computer.
The RS-232 standard defines two classes of devices that may
communicate using RS-232 serial data - Data Terminal Equipment
(DTE), and Data Communication Equipment (DCE). Computers and
terminals are considered DTE, while modems are DCE. The
standard defines pinouts for DTE and DCE such that a "straight
through" cable (pin 2 to pin 2, 3 to 3, etc) can be used between
a DTE and DCE. To connect two DTEs together, you need a "null
modem" cable, that swaps pins between the two ends (eg. pin 2 to
3, 3 to 2). Unfortunately, there is sometimes disagreement
whether a certain device is DTE or DCE, hence my standard RS-232
disclaimer:
if it doesn't work, swap pins 2 and 3!
The standard RS-232 connector is a 25 conductor DB-25, although
many PCs (and some other equipment) now use a 9 pin DE-9 (often
incorrectly called DB-9)
Serial Port Connections
Computer (DTE) Modem
DB-25 DE-9 Signal Direction DB-25
2 3 Tx Data -> 2
3 2 Rx Data <- 3
4 7 Request to send -> 4
5 8 Clear to send <- 5
6 6 Data Set Ready <- 6
7 5 signal ground 7
8 1 Data CarrierDetect <- 8
20 4 Data Terminal Ready -> 20
22 9 Ring Indicator <- 22
For NMEA-0183 interfacing, we are only concerned with Rx Data,
signal ground (and possibly Tx Data, if we want the computer to
talk to the GPS)
NMEA-0183 data is sent at 4800 baud.
6. Troubleshooting
First check that the talker (usually GPS or Loran) can send
NMEA-0183, and determine what sentences it sends. Also, verify
that the listener understands NMEA-0183, and that it understands
the sentences the talker is sending. In some cases the same
information may be sent in two or more different sentences. If
the talker and listener don't both use the same sentences, there
will be no communication. It may be possible to change the
sentences sent by the talker, to match those understood by the
listener.
Next, check that the talker is indeed set to send NMEA-0183
data. Some talkers may have provision to send NMEA-0180 or
0182, or some proprietary format.
A computer, using any convenient terminal program (Telix,
Procomm, Windows Terminal, etc.) set to 4800 baud, can be used
to monitor the NMEA data, and confirm what sentences are sent,
and that the data is in the correct format.
Verify that the wiring is correct - that the talker data output
is connected to the listener data input, and that a signal
ground line is connected between the two pieces of equipment.
If you have multiple listeners connected to a single talker, you
may be overloading the talker port. Try connecting only one
listener at a time.
On any NMEA-0183 circuit, there can _only_ be one talker. If
you must have more than one talker, and one of the talker
devices can also act as a listener, you may be able to connect
things "in series", so a talker-only output is connected to a
listener/talker input, and the listener/talker output is
connected to other listeners. However, some listener/talker
devices may reformat the data, or only pass data they
understand. (The Autohelm Seatalk system does this, and claims
the data as it's own, starting all output sentences with "$II".)
Particularly with older equipment, the equipment may claim to
comply with NMEA-0183, but in fact have an error in the data
format. (My Kings 8001 Loran-C claims to send an APB sentence,
but gets some of the fields in the wrong order, so my autopilot
can't understand it.) This sort of problem can be verified by
capturing the NMEA-0183 data on a computer, and comparing the
data formats with those given above.
7. About the author
This FAQ was written by:
Peter Bennett
bennett@triumf.ca
I have an FTP site containing this file, a GPS FAQ, and other
NMEA information files and PC programs for capturing and
displaying NMEA data, and related things:
ftp://sundae.triumf.ca/pub/peter/index.html
This site is mirrored in Germany at:
ftp://ftp-i2.informatik.rwth-aachen.de/pub/arnd/GPS/peter/index.html
7.1 Acknowlegments
I would like to thank the following for their contributions
or corrections to this document:
Tom Clark, clark@tomcat.gsfc.nasa.gov
Bob Shearer, t.shearer@unixa.nerc-wallingford.ac.uk
David Steckler, davidst@nobeltec.com
Karl Olmstead, olmstead@ridgecrest.ca.us
Dave Wells, KD6TO, davew@cruzio.com
Mike Morrow, caveman@castles.com

View file

@ -1,148 +0,0 @@
%
% `Events.tex' -- describes the FG Event Manager
%
% Written by Curtis Olson. Started December, 1997.
%
% $Id$
%------------------------------------------------------------------------
\documentclass[12pt]{article}
\usepackage{anysize}
\papersize{11in}{8.5in}
\marginsize{1in}{1in}{1in}{1in}
\usepackage{amsmath}
\usepackage{epsfig}
\usepackage{setspace}
\onehalfspacing
\usepackage{url}
\begin{document}
\title{
Flight Gear Periodic Event Manager and Scheduler
}
\author{
Curtis L. Olson\\
(\texttt{curt@me.umn.edu})
}
\maketitle
\section{Introduction}
Many tasks within the simulator need to only run periodically. These
are typically tasks that calculate values that don't change
significantly in 1/60th of a second, but instead change noticeably on
the order of seconds, minutes, or hours.
Running these tasks every iteration would needless degrade
performance. Instead, we would like to spread these out over time to
minimize the impact they might have on frame rates, and minimize the
chance of pauses and hesitations.
\section{Overview}
The goal of the event manager is to provide a way for events to be run
periodically, and to spread this load out so that the processing time
spent at any particular iteration is minimized.
The scheduler consists of two parts. The first part is simply a list
of registered events along with any management information associated
with that event. The second part is a run queue. When events are
triggered, they are placed in the run queue. The system executes only
one pending event per iteration in order to balance the load.
\section{The Events List}
\subsection{Event List Structure}
All registered events are maintained in a list. Currently, this list
is simply an array of event structures. Each event structure stores
the following information.
\begin{itemize}
\item An ASCII description or event identifier. This is used when
outputting event statistics.
\item A pointer to the event function.
\item An event status flag. The flag marks the process as ready to
run, queued in the run queue, or suspended from eligibility to
run.
\item A time interval specifying how often to schedule and run this
event.
\item The absolute time this event was last run.
\item The next absolute time this event is scheduled to run.
\item The cumulative run time for this process (in ms.)
\item The least time consumed by a single run of this event (in ms.)
\item The most time consumed by a single run of this event (in ms.)
\item The number of times this event has been run.
\end{itemize}
\subsection{Event List Operation}
To use the event list, you must first initialize it by calling
\texttt{fgEventInit()}.
Once the list has been initialized, you can register events by calling
\texttt{fgEventRegister()}. A typical usage might be:
\texttt{fgEventRegister(``fgUpdateWeather()'', fgUpdateWeather,
FG\_EVENT\_READY, 60000)}. This tells the event manager to schedule
and run the event, \texttt{fgUpdateWeather()}, every 60 seconds. The
first field is an ASCII description of the function, the second field
is a pointer to the function, the third field is the status flag, and
the last field is the time interval. Event functions should return
\texttt{void} and accept no parameters. The status flag can set to
either \texttt{FG\_EVENT\_SUSP}, \texttt{FG\_EVENT\_READY}, or
\texttt{FG\_EVENT\_QUEUED}. \texttt{FG\_EVENT\_SUSP} means register
the event, but never schedule it to run. \texttt{FG\_EVENT\_READY}
means register the event and schedule and run it normally.
\texttt{FG\_EVENT\_QUEUED} is mostly used internally so that an event
will never have more than one entry in the run queue.
Finally, in your main loop, you must add a call to
\texttt{fgEventProcess()} to run it every iteration. This routine
will schedule all pending events (push them onto the run queue) and
then execute the first thing in the run queue.
\section{The Run Queue}
The run queue is a very simple queue who's elements are just a pointer
to an event list element. When an event needs to be scheduled, a
pointer to that event is pushed onto the back of the queue. Each time
\texttt{fgEventProcess()} is called, the first element on the run
queue will be executed.
\section{Profiling Events}
As stated before, each event record contains simple event statistics
such as the total time spent running this event, the quickest run, the
slowest run, and the total number of times run. We can output the
list of events along with these statistics in order to determine if any of
them are consuming an excessive amount of time, or if there is any
chance that a particular event could run slow enough to be responsible
for a perceived hesitation or pause in the flow of the simulation.
\end{document}
%------------------------------------------------------------------------

306
Hints/aaa
View file

@ -1,306 +0,0 @@
From fatcity!root@news.cts.com Wed Aug 20 16:34:24 1997
X-VM-v5-Data: ([nil nil nil nil nil nil nil nil nil]
["3412" "Wed" "20" "August" "1997" "14:14:39" "-0800" "Steve Baker" "steve@mred.bgm.link.com" nil "83" "Re: culling with view frustrum before view transformation" "^From:" nil nil "8" nil nil nil nil nil]
nil)
Received: from mailhub.cts.com (mailhub.cts.com [204.216.216.130])
by meserv.me.umn.edu (8.8.6/8.8.6) with SMTP id QAA04291
for <curt@me.umn.edu>; Wed, 20 Aug 1997 16:34:23 -0500 (CDT)
Received: from donews.cts.com(really [192.188.72.21]) by mailhub.cts.com
via smail with smtp
id <m0x1IGC-000Y2Ba@mailhub.cts.com>
for <curt@me.umn.edu>; Wed, 20 Aug 97 14:25:48 -0700 (PDT)
(Smail-3.1.92 1996-Mar-19 #3 built 1996-Apr-21)
Received: from fatcity by donews.cts.com with uucp
(Smail3.1.29.1 #5) id m0x1IG4-000007a; Wed, 20 Aug 97 14:25 PDT
Received: by fatcity.com (06-Aug-97/v1.0d-b55/bab) via UUCP id 0C90BB6D; Wed, 20 Aug 1997 14:14:39 -0800
Message-ID: <F001.0C90BB6D.19970820141439@fatcity.com>
X-Comment: OpenGL Game Developers Mailing List
X-Sender: steve@mred.bgm.link.com (Steve Baker)
Reply-To: OPENGL-GAMEDEV-L@fatcity.com
Errors-To: ML-ERRORS@fatcity.com
Mime-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Organization: Fat City Network Services, San Diego, California
X-ListServer: v1.0d, build 55; ListGuru (c) 1996-1997 Bruce A. Bergman
Precedence: bulk
From: steve@mred.bgm.link.com (Steve Baker)
Sender: root@fatcity.com
To: Multiple recipients of list OPENGL-GAMEDEV-L <OPENGL-GAMEDEV-L@fatcity.com>
Subject: Re: culling with view frustrum before view transformation
Date: Wed, 20 Aug 1997 14:14:39 -0800
> >Brian Hook wrote:
> >> You can do bounding spheres,
> >> bounding boxes, or a combination of both (sphere first, then box).
> >
> >Which is faster to test for being completely inside, outside, or
> >partial, of the view frustrum?
>
> Obviously bounding sphere will be the fastest, but since it's, well, a
> sphere, it's not going to be particularly accurate (since it's rotationally
> invariant).
>
> if ( distance( obj.position, plane ) >= obj_sphere.radius )
> trivial_reject = true;
>
> (I assume you also check the sign of the distance)
I echo your sentiments that bounding spheres are the fastest approach to
culling to FOV frustum - also for some kinds of collision detection.
The most important thing to bear in mind about culling is that the first
trivial-reject test you apply is by far the most time-critical. This test
is always applied to more nodes than any of the subsequent tests.
So, do the cheapest test first.
This is typically the NEAR plane test. Everything behind the viewers head
gets chopped out - and it's an especially cheap test.
if ( obj_sphere.center.z < near_plane - obj_sphere.radius )
REJECT!!
...next do the second cheapest test (assuming you know that your database
could possibly beyond the far clip plane)...
if ( obj_sphere.center.z - obj_sphere.radius > far_plane )
REJECT!!
...and *then* do...
if ( distance( obj.position, plane ) >= obj_sphere.radius )
REJECT!!
It's also useful to know that in many applications, you cull more objects from
the left and right faces of the frustum than you do from the top and bottom - so
test left, then right, then bottom then top.
Also, with bounding sphere tests, you shouldn't forget to do total-accept
as well as total-reject tests. Once you know that an object's sphere is
TOTALLY on screen, you don't have to descend into the daughter objects to
cull-test them...you *know* they are all on-screen.
Another way to look at that it to remember which of the six possible plane tests
didn't even touch the sphere - as you work your way down the object hierarchy,
you can accumulate those flags and avoid even testing those planes that a parent
sphere has already cleanly passed. If you do this then a vast percentage of
your spheres will only need to be tested against one plane.
Sphere-based culling can be extremely cost-effective. It's so cheap that even if
you feel the need to use a bounding cubeoid (or even a yet more complex shape),
it's still worth doing a sphere-based cull first just to get rid of the trivial
accept and reject cases.
Steve Baker 817-619-1361 (Vox-Lab)
Hughes Training Inc. 817-619-8776 (Vox-Office/Vox-Mail)
2200 Arlington Downs Road 817-619-4028 (Fax)
Arlington, Texas. TX 76005-6171 Steve@MrEd.bgm.link.com (eMail)
http://www.hti.com http://web2.airmail.net/sjbaker1 (personal)
** Beware of Geeks bearing GIF's. **
--
Author: Steve Baker
INET: steve@mred.bgm.link.com
Fat City Network Services -- (619) 538-5030
San Diego, California -- Public Internet Access
-------------------------------------------------------------------
To REMOVE yourself from this mailing list, send an E-Mail message
to: ListGuru@fatcity.com (note EXACT spelling of 'ListGuru') and in
the message BODY, include a line containing: UNSUB OPENGL-GAMEDEV-L
(or the name of mailing list you want to be removed from).
From fatcity!root@news.cts.com Thu Aug 21 09:19:20 1997
X-VM-v5-Data: ([nil nil nil nil nil nil nil nil nil]
["2834" "Thu" "21" "August" "1997" "07:00:54" "-0800" "Steve Baker" "steve@mred.bgm.link.com" nil "77" "Re: culling with view FRUSTUM before view transformation" "^From:" nil nil "8" nil nil nil nil nil]
nil)
Received: from mailhub.cts.com (mailhub.cts.com [204.216.216.130])
by meserv.me.umn.edu (8.8.6/8.8.6) with SMTP id JAA02567
for <curt@me.umn.edu>; Thu, 21 Aug 1997 09:19:20 -0500 (CDT)
Received: from donews.cts.com(really [192.188.72.21]) by mailhub.cts.com
via smail with smtp
id <m0x1Y1o-000Wd7a@mailhub.cts.com>
for <curt@me.umn.edu>; Thu, 21 Aug 97 07:16:00 -0700 (PDT)
(Smail-3.1.92 1996-Mar-19 #3 built 1996-Apr-21)
Received: from fatcity by donews.cts.com with uucp
(Smail3.1.29.1 #5) id m0x1Y1f-0000Qaa; Thu, 21 Aug 97 07:15 PDT
Received: by fatcity.com (06-Aug-97/v1.0d-b55/bab) via UUCP id 0C90BDD1; Thu, 21 Aug 1997 07:00:54 -0800
Message-ID: <F001.0C90BDD1.19970821070054@fatcity.com>
X-Comment: OpenGL Game Developers Mailing List
X-Sender: steve@mred.bgm.link.com (Steve Baker)
Reply-To: OPENGL-GAMEDEV-L@fatcity.com
Errors-To: ML-ERRORS@fatcity.com
Mime-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Organization: Fat City Network Services, San Diego, California
X-ListServer: v1.0d, build 55; ListGuru (c) 1996-1997 Bruce A. Bergman
Precedence: bulk
From: steve@mred.bgm.link.com (Steve Baker)
Sender: root@fatcity.com
To: Multiple recipients of list OPENGL-GAMEDEV-L <OPENGL-GAMEDEV-L@fatcity.com>
Subject: Re: culling with view FRUSTUM before view transformation
Date: Thu, 21 Aug 1997 07:00:54 -0800
> OK, this is probably explained in books etc., but what is the fastest way
> to find the distance between a point and a plane?
A plane can be represented by the equation
Ax + By + Cz + D = 0 ;
A,B,C is just the surface normal of the plane and D is the shortest
distance from the origin to the plane.
So, if you need to find the distance of a point from the plane, just
imagine a new plane that goes through your test point and is parallel
to the plane you want to test. The plane equation of that new plane would be:
A'x + B'y + C'z + D' = 0 ;
Since the two planes are parallel, their surface normals are the same, so
A' == A
B' == B
C' == C
D' == D + distance_between_the_two_planes
...the only thing that's different is their D values - which differ by the
distance of your test point from the original plane.
So, for a point (x,y,z), the distance from the plane (A,B,C,D) is
dist = D' - D
= -A'x - B'y - C'z - D
= -Ax - By - Cz - D
= -( [ABC]dot[xyz] + D )
That's the general result - but culling to the view frustum is a very
special case...if you are working in eye-relative coordinates (IMHO this
is best), then since all top,bot,left,right planes of the frustum meet
at the eye - and since the eye is at the origin (by definition), then
D is always zero for those plane and that saves you a subtract.
If you are feeling even more in need of optimisation - then you can save one
multiply per plane by realising that (for rectangular screens) one of the
three components of the plane equation will always be zero.
eg for the LEFT clip plane, the Y component of the normal of the plane
is zero, so the distance to the left or right plane is just
- ( A x' + C z' )
and to the top or bottom plane it's just:
- ( A x' + B y' )
Since you are only using this for culling, you don't need the minus sign
so the cost of a test can be as little as two multiplies and one add
per plane.
Steve Baker 817-619-1361 (Vox-Lab)
Hughes Training Inc. 817-619-8776 (Vox-Office/Vox-Mail)
2200 Arlington Downs Road 817-619-4028 (Fax)
Arlington, Texas. TX 76005-6171 Steve@MrEd.bgm.link.com (eMail)
http://www.hti.com http://web2.airmail.net/sjbaker1 (personal)
** Beware of Geeks bearing GIF's. **
--
Author: Steve Baker
INET: steve@mred.bgm.link.com
Fat City Network Services -- (619) 538-5030
San Diego, California -- Public Internet Access
-------------------------------------------------------------------
To REMOVE yourself from this mailing list, send an E-Mail message
to: ListGuru@fatcity.com (note EXACT spelling of 'ListGuru') and in
the message BODY, include a line containing: UNSUB OPENGL-GAMEDEV-L
(or the name of mailing list you want to be removed from).
From fatcity!root@news.cts.com Fri Aug 22 08:51:10 1997
X-VM-v5-Data: ([nil nil nil nil nil nil nil nil nil]
["2087" "Fri" "22" "August" "1997" "06:31:24" "-0800" "Steve Baker" "steve@mred.bgm.link.com" nil "47" "Re: culling with view FRUSTUM before view transformation" "^From:" nil nil "8" nil nil nil nil nil]
nil)
Received: from mailhub.cts.com (mailhub.cts.com [204.216.216.130])
by meserv.me.umn.edu (8.8.6/8.8.6) with SMTP id IAA21767
for <curt@me.umn.edu>; Fri, 22 Aug 1997 08:51:09 -0500 (CDT)
Received: from donews.cts.com(really [192.188.72.21]) by mailhub.cts.com
via smail with smtp
id <m0x1u2d-000Wk7a@mailhub.cts.com>
for <curt@me.umn.edu>; Fri, 22 Aug 97 06:46:19 -0700 (PDT)
(Smail-3.1.92 1996-Mar-19 #3 built 1996-Apr-21)
Received: from fatcity by donews.cts.com with uucp
(Smail3.1.29.1 #5) id m0x1u2a-0000PHa; Fri, 22 Aug 97 06:46 PDT
Received: by fatcity.com (06-Aug-97/v1.0d-b55/bab) via UUCP id 0C90C1C4; Fri, 22 Aug 1997 06:31:24 -0800
Message-ID: <F001.0C90C1C4.19970822063124@fatcity.com>
X-Comment: OpenGL Game Developers Mailing List
X-Sender: steve@mred.bgm.link.com (Steve Baker)
Reply-To: OPENGL-GAMEDEV-L@fatcity.com
Errors-To: ML-ERRORS@fatcity.com
Mime-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Organization: Fat City Network Services, San Diego, California
X-ListServer: v1.0d, build 55; ListGuru (c) 1996-1997 Bruce A. Bergman
Precedence: bulk
From: steve@mred.bgm.link.com (Steve Baker)
Sender: root@fatcity.com
To: Multiple recipients of list OPENGL-GAMEDEV-L <OPENGL-GAMEDEV-L@fatcity.com>
Subject: Re: culling with view FRUSTUM before view transformation
Date: Fri, 22 Aug 1997 06:31:24 -0800
> > > Actually, I find it easier to scale the whole such that D = 1, then you
> > > only need to store the non-degenerate (A', B', C') vector (i.e., A' =
> > > A/D, etc...). Storing a already-normalized (A, B, C) + D quadruple is
> > > worth it only if you know before hand that the planes will never be
> > > scaled before their normals are used. In the general case where a
> > > scaling is possible, you'll have to renormalize anyway.
> >
> > Normally, I might agree with you - but in the case of Frustum clipping,
> > scaling the normal by dividing by 'D' is a bad move since D==0 in the
> > case of all four 'interesting' planes. :-)
>
> Interesting point. This is of course only true when the eyepoint is in
> the origin, which brings us back to the issue of clipping before or
> after the modelview transformation.
Well - that's a dangerous thing to assume - I mean, the eye might just happen
to move to the true world coordinate origin (by flook) and crash your program
with a bunch of divide by zero errors.
In any case, you are going to run into nasty precision problems as your eye
approaches the origin - even if it doesn't reach it.
> Learn something new every day.... :-)
...Forget something important every night... :-)
Steve Baker 817-619-1361 (Vox-Lab)
Hughes Training Inc. 817-619-8776 (Vox-Office/Vox-Mail)
2200 Arlington Downs Road 817-619-4028 (Fax)
Arlington, Texas. TX 76005-6171 Steve@MrEd.bgm.link.com (eMail)
http://www.hti.com http://web2.airmail.net/sjbaker1 (personal)
** Beware of Geeks bearing GIF's. **
--
Author: Steve Baker
INET: steve@mred.bgm.link.com
Fat City Network Services -- (619) 538-5030
San Diego, California -- Public Internet Access
-------------------------------------------------------------------
To REMOVE yourself from this mailing list, send an E-Mail message
to: ListGuru@fatcity.com (note EXACT spelling of 'ListGuru') and in
the message BODY, include a line containing: UNSUB OPENGL-GAMEDEV-L
(or the name of mailing list you want to be removed from).

View file

@ -1,71 +0,0 @@
From fatcity!root@news.cts.com Fri May 15 08:52:18 1998
X-VM-v5-Data: ([nil nil nil nil nil nil nil nil nil]
["1426" "Fri" "15" "May" "1998" "06:30:53" "-0800" "Steve Baker" "sbaker@link.com" nil "39" "Re: Endian swapping" "^From:" nil nil "5" nil nil nil nil nil]
nil)
Received: from mh2.cts.com (root@mh2.cts.com [205.163.24.68])
by meserv.me.umn.edu (8.8.8/8.8.8) with ESMTP id IAA18883
for <curt@me.umn.edu>; Fri, 15 May 1998 08:52:18 -0500 (CDT)
Received: from king.cts.com (root@king.cts.com [198.68.168.21]) by mh2.cts.com (8.8.7/8.8.5) with ESMTP id GAA12800; Fri, 15 May 1998 06:52:14 -0700 (PDT)
Received: from donews.cts.com (root@donews.cts.com [192.188.72.21])
by king.cts.com (8.8.7/8.8.7) with SMTP id GAA18786;
Fri, 15 May 1998 06:52:13 -0700 (PDT)
Received: from fatcity by donews.cts.com with uucp
(Smail3.1.29.1 #5) id m0yaKtA-00001sa; Fri, 15 May 98 06:51 PDT
Received: by fatcity.com (10-Feb-1998/v1.0f-b64/bab) via UUCP id 00027B2C; Fri, 15 May 1998 06:30:53 -0800
Message-ID: <F001.00027B2C.19980515063053@fatcity.com>
X-Comment: OpenGL Game Developers Mailing List
X-Sender: Steve Baker <sbaker@link.com>
Reply-To: OPENGL-GAMEDEV-L@fatcity.com
Errors-To: ML-ERRORS@fatcity.com
Organization: Fat City Network Services, San Diego, California
X-ListServer: v1.0f, build 64; ListGuru (c) 1996-1998 Bruce A. Bergman
Precedence: bulk
Mime-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Content-Transfer-Encoding: 7bit
From: Steve Baker <sbaker@link.com>
Sender: root@fatcity.com
To: Multiple recipients of list OPENGL-GAMEDEV-L <OPENGL-GAMEDEV-L@fatcity.com>
Subject: Re: Endian swapping
Date: Fri, 15 May 1998 06:30:53 -0800
On Fri, 15 May 1998, Sean L. Palmer wrote:
> I'm trying to make this library as cross-platform as humanly possible with
> my limited resources, so if anyone has any code to detect whether the target
> is Big- or Little-endian, please e-mail it my way.
/*
Return TRUE if this machine is little endian,
FALSE otherwise.
*/
int is_little_endian ()
{
int i = 1 ;
return *((char *) &i) ;
}
...this works because the address of an integer on a little-endian machine is
the address of the low order byte (whose value is 1) and on a big-endian machine,
it's the address of the high order byte (whose value is 0).
Steve Baker (817)619-8776 (Vox/Vox-Mail)
Raytheon Systems Inc. (817)619-4028 (Fax)
Work: SBaker@link.com http://www.hti.com
Home: SJBaker1@airmail.net http://web2.airmail.net/sjbaker1
--
Author: Steve Baker
INET: sbaker@link.com
Fat City Network Services -- (619) 538-5051 FAX: (619) 538-5051
San Diego, California -- Public Internet access / Mailing Lists
--------------------------------------------------------------------
To REMOVE yourself from this mailing list, send an E-Mail message
to: ListGuru@fatcity.com (note EXACT spelling of 'ListGuru') and in
the message BODY, include a line containing: UNSUB OPENGL-GAMEDEV-L
(or the name of mailing list you want to be removed from). You may
also send the HELP command for other information (like subscribing).

View file

@ -1,186 +0,0 @@
From owner-flight-gear@me.umn.edu Thu Apr 23 08:45:16 1998
X-VM-v5-Data: ([nil nil nil nil nil nil nil nil nil]
["7258" "Thu" "23" "April" "1998" "09:44:56" "-0500" "Steve Baker" "sbaker@link.com" nil "158" "Re: [FGFS] lighting question" "^From:" nil nil "4" nil nil nil nil nil]
nil)
Received: (from majordom@localhost)
by meserv.me.umn.edu (8.8.8/8.8.8) id IAA05148
for flight-gear-outgoing; Thu, 23 Apr 1998 08:45:16 -0500 (CDT)
X-Authentication-Warning: meserv.me.umn.edu: majordom set sender to owner-flight-gear@me.umn.edu using -f
Received: from lfkw10.bgm.link.com (bgm.link.com [130.210.2.10])
by meserv.me.umn.edu (8.8.8/8.8.8) with ESMTP id IAA05144
for <flight-gear@me.umn.edu>; Thu, 23 Apr 1998 08:45:10 -0500 (CDT)
Received: from sutcliffe.bgm.link.com (sutcliffe.bgm.link.com [130.210.236.18])
by lfkw10.bgm.link.com (8.8.6/HTI-Hack-8.8.4) with SMTP
id IAA29813 for <flight-gear@me.umn.edu>; Thu, 23 Apr 1998 08:44:39 -0500 (CDT)
X-Sender: steve@sutcliffe.bgm.link.com
In-Reply-To: <199804230119.UAA13239@kenai.me.umn.edu>
Message-ID: <Pine.SGI.3.96.980423090051.6888D-100000@sutcliffe.bgm.link.com>
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Precedence: bulk
Reply-To: flight-gear@me.umn.edu
From: Steve Baker <sbaker@link.com>
Sender: owner-flight-gear@me.umn.edu
To: flight-gear@me.umn.edu
Subject: Re: [FGFS] lighting question
Date: Thu, 23 Apr 1998 09:44:56 -0500 (CDT)
On Wed, 22 Apr 1998, Curtis L. Olson wrote:
> Here's a lighting question for someone.
>
> Let's say it's noon-ish. If I set the ambient light component to
> about 0.3 and the diffuse light component to about 1.0 I get a
> reasonably bright scene with good contrast in the shadowy areas.
>
> Now, I'm running into problems when the sun is low in the sky. Even
> with a high diffuse lighting component (1.0) the angle the sun light
> makes with the horizontal ground is very small so the diffuse lighting
> component ends up being virtually nothing. I'm fiddling around with
> trying to increase the ambient component to 1.0, but I still get a
> very dark scene.
...simple question - long answer - sorry...
First the "Why does this look bad?" answer...
Well, when the sun is low in the sky, that is exactly what really
does happen - the angle between sun and (flattish) ground gets small
and it gets dark.
The problem is that our eyes have automatic gain control. When the
world gets darker, we increase our pupil apartures to increase the
amount of light we allow in. That only works when the whole world
goes darker - and not in a room in normal daylight containing a
small, dim CRT.
Also, in the real world, the sun lights things much more brightly
than a CRT phosphor can reproduce. When you drop that brightness
by (say) a factor of ten because it's dusk then the sun is still
pretty bright - but 1/10th the brightness on a CRT phosphor is pretty
dim.
If you watch your sunset scenes in a darkened room, they'll look
much better. However, for a desktop simulation, that may not help.
The other reason there is a problem is that the CRT phosphor is
not a linear device - if you double the number for the pixel
brightness - you don't get twice the brightness coming out the
other side. This non-linearity is *supposed* to be corrected
by a process called 'gamma correction' which works by boosting
the contrast of the dark pixels and reducing the contrast of
the bright ones.
Fixing the gamma will help noon-time scenes as well as dusk
and dawn since the amount of stuff you can see in shadowed
areas will be better if the gamma is set right.
The required amount of gamma modification changes with the
age of the CRT and which particular choice of phosphor layer
the CRT manufacturer made. You may also need more gamma correction
in (say) the BLUE channel than in RED or GREEN.
Fancy machines like SGI ONYX's have hardware gamma tables on
the output of the machine to do this correction - I doubt that
all the PC-based 'toy' 3D cards have this feature.
Now, the "What can we do to improve matters?" answer...
Well, you seem to be on the right track - you basically have to increase
the ambient light to make up for the missing light on the horizontal
surfaces. However, this tends to reduce the amount of contrast between
the dark regions and the vertical surfaces that are being brightly lit
just as the sun goes down. That is the opposite of the real world since
the shadows are much more contrasty late in the day than they are at noon.
(That is a subjective thing - I could be wrong about that)
You said:
> I'm fiddling around with trying to increase the ambient component to 1.0,
> but I still get a very dark scene.
...that suprises me - you ought to be getting a very bright scene
with ambient==1.0 since all surfaces are being lit with a very bright
light that is ignoring their orientation. The scene should be brighter
than at noon.
Perhaps you don't have the ambient component of the glMaterial set
up right?
On the gamma front, there are two experiments you can try:
Curt: I know you have access to an SGI RE2 machine - and that
you can run FGFS on it. So, run FGFS up and set the time of
day to dusk - so you have the too-dark scene. Now open another
shell window and try running 'gamma 1.0' then 'gamma 1.5' then
'gamma 2.0'. If I'm right about the gamma setting being the problem
then gamma 1.0 should look just like it does on the PC, and
(depending on the age of your CRT), 1.5 or 2.0 (or something like
that) should make it look much better.
If you can't get to an SGI machine then do a screen dump of your
image into a file, then load that file into Xview (under Linux)
or something like photoshop. Image processing programs like this
usually let you change the gamma for an image interactively by
recomputing the pixels (this eliminates the need for gamma hardware).
In XView, pick the colour editor window and click on the gamma
button next to the intensity graph. Type in 2.0 (or whatever) and
you'll notice that the curve in the window looks like this:
****
**
*
*
*
*
*
*
*
(pardon the ASCII art)
....which means that the dark areas have been increased in contrast
and the light areas reduced in contrast.
If either of these tests shows that gamma is indeed your problem then
you need to think about how to set the gamma on your hardware.
For software OpenGL with Mesa - I think Mesa has a gamma setting
extension (or an environment variable or something) - the 3Dfx
card (IIRC) has a way to set the gamma too - although I don't
know how. The general way to set the gamma is not through OpenGL,
so doing this in a portable way from inside FGFS is going to be hard.
You may have to rely on the user setting it up in some external
tool (a windoze control panel most likely).
> I may have something fouled up, or may not understand something
> correctly, but does anyone have any suggestions as to what the ambient
> and diffuse lighting components ought to be set to in order for the
> scenery to be "realistically" lit when the sun is low in the sky?
Well, 'realistically' is a hard thing - the human eye can discern detail
in a scene lit at a gazillion candelas - all the way down to a gazillionth
of a candela, lots of orders of magnitude. A CRT can only display the
number of brightness levels provided in the frame buffer (256 if you are
lucky - a mere 2.5 orders of magnitude) - and is VERY dim in any case.
Getting 'realistic' brightnesses just isn't going to happen on a desktop
display system - so it's all a matter of compromise.
On 'real' flight simulators, the fight for better contrast and brightness
and more orders of magnitude of brightness variation is a continual battle
that results in some pretty exotic display technologies. (Things like
shining an arc-lamp onto a million tiny mirrors that are tilted using
pizo-electric effects to modulate the brightness...ugh!)
Steve Baker (817)619-8776 (Vox/Vox-Mail)
Raytheon Systems Inc. (817)619-4028 (Fax)
Work: SBaker@link.com http://www.hti.com
Home: SJBaker1@airmail.net http://web2.airmail.net/sjbaker1
-------------------------------------
Please visit the FGFS web page: http://www.menet.umn.edu/~curt/fgfs/
For help on using this list (especially unsubscribing), send a message to
"flight-gear-request@me.umn.edu" with a single line of text: "help".

View file

@ -1,73 +0,0 @@
From owner-fgfs-devel@flightgear.org Mon Sep 14 10:44:02 1998
X-VM-v5-Data: ([nil nil nil nil nil nil nil nil nil]
["1542" "Mon" "14" "September" "1998" "10:41:38" "-0500" "Steve Baker" "sbaker@link.com" nil "42" "Re: FGFS: Windows Joystick support" "^From:" nil nil "9" nil nil nil nil nil]
nil)
Received: from mailhub.woodsoup.org (IDENT:root@anduin.physics.iastate.edu [129.186.82.1])
by meserv.me.umn.edu (8.9.1a/8.9.1) with ESMTP id KAA21095
for <curt@me.umn.edu>; Mon, 14 Sep 1998 10:44:00 -0500 (CDT)
Received: from majordom by mailhub.woodsoup.org with local (Exim 1.92 #1)
for fgfs-devel-outgoing@flightgear.org
id 0zIamX-0005os-00; Mon, 14 Sep 1998 10:43:13 -0500
Received: from bgm.link.com ([130.210.2.10] helo=lfkw10.bgm.link.com)
by mailhub.woodsoup.org with esmtp (Exim 1.92 #1)
for fgfs-devel@flightgear.org
id 0zIamW-0005ok-00; Mon, 14 Sep 1998 10:43:12 -0500
Received: from samantha.bgm.link.com (samantha.bgm.link.com [130.210.65.19])
by lfkw10.bgm.link.com (8.8.6/RSC-RTI-1.0) with SMTP
id KAA21757; Mon, 14 Sep 1998 10:42:23 -0500 (CDT)
X-Sender: steve@samantha.bgm.link.com
Reply-To: Steve Baker <sbaker@link.com>
In-Reply-To: <3.0.5.32.19980913154136.007e8440@umr.edu>
Message-ID: <Pine.SGI.3.96.980914103259.11905A-100000@samantha.bgm.link.com>
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Precedence: bulk
From: Steve Baker <sbaker@link.com>
Sender: owner-fgfs-devel@flightgear.org
To: William Riley <riley@technologist.com>
cc: fgfs-devel@flightgear.org
Subject: Re: FGFS: Windows Joystick support
Date: Mon, 14 Sep 1998 10:41:38 -0500 (CDT)
On Sun, 13 Sep 1998, William Riley wrote:
> Is anyone working on joystick support for Win9x/NT? I'm a fledgling
> programmer and was thinking about tacking this task. If anyone has started
> (or finished) please email me directly or through the list. Thanks.
There is basic joystick support in GLUT - I presume the simplest thing
to do to start with is to use that since the result will be portable to
all of our target systems.
The downside is that IIRC, GLUT only supports a very simple joystick
setup (single stick, two axes, two buttons).
Whatever API we finally choose needs to consider the portability issues.
IMHO, it would be better to extend GLUT and offer any improvements back
into the general Freeware community rather than to settle on an ad'hoc
FGFS-specific solution.
Joystick info for Linux can be found here:
http://atrey.karlin.mff.cuni.cz/~vojtech/joystick/
Joystick programming info for Windoze is here:
http://www.hut.fi/Misc/Electronics/docs/joystick/pc_joystick.html#programming
That same site has a TON of interesting joystick info:
http://www.hut.fi/Misc/Electronics/docs/joystick/
GLUT's joystick support is not documented yet since it's only present in the
very latest GLUT 3.7 beta. However, if you check the source code for that
release of GLUT, you'll see how it's done there.
Steve Baker (817)619-2657 (Vox/Vox-Mail)
Raytheon Systems Inc. (817)619-4028 (Fax)
Work: SBaker@link.com http://www.hti.com
Home: SJBaker1@airmail.net http://web2.airmail.net/sjbaker1

View file

@ -1,288 +0,0 @@
From curt@infoplane.com Fri Nov 13 06:10:29 1998
X-VM-v5-Data: ([nil nil nil nil nil nil nil nil nil]
["6615" "Fri" "13" "November" "1998" "06:10:23" "-0600" "curt@infoplane.com" "curt@infoplane.com" nil "271" "fuzzy-light-effect" "^From:" nil nil "11" nil nil nil nil nil]
nil)
Received: from dorthy.state.net (dorthy.state.net [209.234.62.254])
by meserv.me.umn.edu (8.9.1a/8.9.1) with ESMTP id GAA15847
for <curt@me.umn.edu>; Fri, 13 Nov 1998 06:10:28 -0600 (CST)
Received: from sledge.infoplane.com (curt@sledge.infoplane.com [204.120.151.21]) by dorthy.state.net (8.8.8/8.7.2) with ESMTP id GAA25998 for <curt@me.umn.edu>; Fri, 13 Nov 1998 06:10:08 -0600 (CST)
Received: (from curt@localhost)
by sledge.infoplane.com (8.8.8/8.8.8/Debian/GNU) id GAA24798
for curt@me.umn.edu; Fri, 13 Nov 1998 06:10:23 -0600
Message-Id: <199811131210.GAA24798@sledge.infoplane.com>
From: curt@infoplane.com
To: curt@me.umn.edu
Subject: fuzzy-light-effect
Date: Fri, 13 Nov 1998 06:10:23 -0600
/* stars - draws a twisting sphere of eerie lights
Copyright (C) 1998 James Bowman
stars 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, or (at your option)
any later version.
gpasm 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 gpasm; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h> /* for cos(), sin(), and sqrt() */
#include <assert.h>
#ifdef WIN32
#include <time.h>
#else
#include <sys/time.h>
#endif
#include <GL/glut.h>
static int phi; /* Global clock */
static int texWidth = 64; /* 64x64 is plenty */
/************************************************************************/
/* Generate a pleasing, light-shaped texture. */
static void
setTexture(void)
{
int texSize;
void *textureBuf;
GLubyte *p;
int i,j;
double radius;
texSize = texWidth*texWidth;
textureBuf = malloc(texSize);
if (NULL == textureBuf) return;
p = (GLubyte *)textureBuf;
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));
} else
*p = 0x00;
p++;
}
}
gluBuild2DMipmaps(GL_TEXTURE_2D, 1, texWidth, texWidth,
GL_LUMINANCE,
GL_UNSIGNED_BYTE, textureBuf);
free(textureBuf);
}
/************************************************************************/
static int W, H;
#define NUM_STARS 100
#define frand() ((float)(rand() & 0xfff) / (float)0x1000) /* 0.0 - 1.0 */
#define frand2() (1.0f - (2.0f * frand())) /* -1 - +1 */
/* Normalise the input vector */
static void vecNormalise(float *vv)
{
double mag;
mag = sqrt((vv[0] * vv[0]) + (vv[1] * vv[1]) + (vv[2] * vv[2]));
vv[0] /= mag;
vv[1] /= mag;
vv[2] /= mag;
}
void
redraw_viewing(void)
{
static int cold = 1;
static float stars[NUM_STARS * 3];
GLfloat fb_buffer[NUM_STARS * 4];
int i;
if (cold) {
/* Position all the stars more-or-less randomly on the surface
* of a unit sphere. */
for (i = 0; i < NUM_STARS; i++) {
stars[3 * i + 0] = frand2();
stars[3 * i + 1] = frand2();
stars[3 * i + 2] = frand2();
vecNormalise(&stars[3 * i]);
}
cold = 0;
}
glClear(GL_COLOR_BUFFER_BIT);
/* First use feedback to determine the screen positions of the
stars. */
glFeedbackBuffer(NUM_STARS * 4, GL_3D, fb_buffer);
glRenderMode(GL_FEEDBACK);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glRotatef(phi % 360, 0.0f, 1.0f, 0.0f); /* Constant spin */
glRotatef(sin((double)phi / 300.0) * 150.0, /* Periodic twist */
0.1f, 0.6f, -0.5f);
glBegin(GL_POINTS);
for (i = 0; i < NUM_STARS; i++)
glVertex3fv(&stars[3 * i]);
glEnd();
glPopMatrix();
glRenderMode(GL_RENDER); /* No more feedback */
/* Now draw the stars as sprites. */
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND); /* Simple additive blend is fine */
glBlendFunc(GL_ONE, GL_ONE);
/* Choose a color triple like this so that when the sprites overlap
* and the color saturates, red will clamp first, then green, then
* blue. */
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glColor3f(1.0f, 0.75f, 0.5f);
/* Set up projection and modelview matrix that gives us a 1:1
* mapping to screen coordinates. */
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glScalef(2.0f / (GLfloat)W, 2.0f / (GLfloat)H, 1.0f);
glTranslatef(0.5f * -(GLfloat)W, 0.5f * -(GLfloat)H, 0.0f);
{
float width;
float x, y, z;
int i;
glBegin(GL_QUADS);
for (i = 0; i < NUM_STARS; i++) {
/* Skip the GL_POINT_TOKEN */
x = fb_buffer[4 * i + 1];
y = fb_buffer[4 * i + 2];
z = fb_buffer[4 * i + 3];
width = 10.0 * (2.0 - z); /* Arbitrary distance attenuation */
glTexCoord2f(0.0f, 0.0f);
glVertex2f(x - width, y - width);
glTexCoord2f(1.0f, 0.0f);
glVertex2f(x + width, y - width);
glTexCoord2f(1.0f, 1.0f);
glVertex2f(x + width, y + width);
glTexCoord2f(0.0f, 1.0f);
glVertex2f(x - width, y + width);
}
glEnd();
}
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glutSwapBuffers();
}
void
reshape_viewing(int w, int h)
{
glViewport(0, 0, w, h);
W = w;
H = h;
}
/************************************************************************/
void
animate(void)
{
phi++;
redraw_viewing();
}
void
key(unsigned char key, int x, int y)
{
switch (key) {
case 27:
case 'q':
exit(0);
}
}
int
main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowSize(640, 480);
glutCreateWindow("stars");
glutReshapeFunc(reshape_viewing);
glutDisplayFunc(redraw_viewing);
glutIdleFunc(animate);
glutKeyboardFunc(key);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glMatrixMode(GL_MODELVIEW);
setTexture();
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MIN_FILTER,
GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MAG_FILTER,
GL_LINEAR);
glMatrixMode(GL_PROJECTION);
gluPerspective( /* field of view in degree */ 40.0f,
/* aspect ratio */ 1.0f,
/* Z near */ 3.0f,
/* Z far */ 5.0f);
glMatrixMode(GL_MODELVIEW);
gluLookAt(0.0f, 0.0f, 4.0f, /* eye position */
0.0f, 0.0f, 0.0f, /* looking at */
0.0f, 1.0f, 0.0f); /* up vector */
glutMainLoop();
return 0; /* ANSI C requires main to return int. */
}

View file

@ -1,118 +0,0 @@
From sbaker@link.com Thu Mar 12 22:51:27 1998
X-VM-v5-Data: ([nil nil nil nil t nil nil nil nil]
["4342" "Thu" "12" "March" "1998" "22:50:07" "-0600" "Steve Baker" "sbaker@link.com" "<Pine.SGI.3.96.980312222643.15355F-100000@lechter.bgm.link.com>" "95" "Re: Texturing (finally)" "^From:" nil nil "3" nil nil nil nil nil]
nil)
Received: from lfkw10.bgm.link.com (bgm.link.com [130.210.2.10])
by meserv.me.umn.edu (8.8.8/8.8.8) with ESMTP id WAA13969
for <curt@me.umn.edu>; Thu, 12 Mar 1998 22:51:26 -0600 (CST)
Received: from lechter.bgm.link.com (lechter.bgm.link.com [130.210.239.45])
by lfkw10.bgm.link.com (8.8.6/HTI-Hack-8.8.4) with SMTP
id WAA25775 for <curt@me.umn.edu>; Thu, 12 Mar 1998 22:50:51 -0600 (CST)
X-Sender: steve@lechter.bgm.link.com
Reply-To: Steve Baker <sbaker@link.com>
In-Reply-To: <199803121856.MAA05616@kenai.me.umn.edu>
Message-ID: <Pine.SGI.3.96.980312222643.15355F-100000@lechter.bgm.link.com>
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Status: RO
From: Steve Baker <sbaker@link.com>
To: "Curtis L. Olson" <curt@me.umn.edu>
Subject: Re: Texturing (finally)
Date: Thu, 12 Mar 1998 22:50:07 -0600 (CST)
On Thu, 12 Mar 1998, Curtis L. Olson wrote:
> Steve Baker writes:
> > So you have the texture into OpenGL using glGenTextures /
> > glBindTexture and you have a number for each texture? Does the
> > routine generate the MIPmaps for you?
>
> I found some code that looks like it might do the mipmapping ... I'll
> fiddle around with that a bit if I get a chance.
Once you have an image in memory, the code in the RedBook is all you need.
There is a glu function for generating the MIPmaps. It works OK for
starters - but eventually you'll want to rewrite it. Since the sources
for glu are provided with Mesa (and they work with ANY OpenGL), you
can easily take the standard glu code and hack it yourself later.
The main thing that I find I need to do with MIPmapping is to control
the final alpha value of MIPmapped transparency textures. Simply averaging
all the high level texel Alpha's together to get the lowest LOD doesn't
work very well in some applications for translucent texture.
However, that won't matter to you for a LONG while yet - so just steal
the RedBook examples.
> > As a starter (just to get something going), you could simply divide
> > the latitude and longitude of each terrain vertex by some suitable
> > constant and use that as the texture coordinate. Alternatively, you
> > could let OpenGL do the work using glTexGenf.
>
> Tell me more about glTexGenf().
I have to come clean here and mention that I have never actually used
glTexGenf.
Basically, it provides a mechanism where OpenGL will generate the
texture coordinates for you automatically using other vertex information.
I forget all the modes it has - but IIRC, one of them allows you to specify
the equation of a plane (A,B,C,D where: Ax+By+Cz+D==0) - and the texture
coordinates are computed by projecting each vertex (x,y,z) onto that
plane.
If you set that plane to be a plane that is tangential to the earth
at the center of the terrain tile that you are rendering, then the
texture would 'drape' itself nicely over the terrain - but there would
be seams at the edge of each tile.
> All my coordinates come off the disk
> in (X, Y, Z) so it would take some computational effort to convert
> back to lon/lat ...
Yes - you'd need to store (X,Y,Z,S,T) for each vertex on disk and compute
the texture coordinates in the terrain tool. You'd need to do that
eventually anyway since the number you use to multiply the lat/long
to convert to S,T will be different for each kind of texture map - and
for databases at different latitudes (otherwise the texture gets all
squashed up near the poles).
I guess if you don't want to change your file format that much, you
could store a matrix at the top of the file that could be used to
transform (X,Y,Z) into (S,T,garbage). But that's really the same
thing as using glTexGen to do the work - and you'll still get seams
at the edge of every terrain tile whenever the matrix changes.
Since OpenGL supports the idea of a texture matrix, you could simply
load your per-tile matrix onto the OpenGL texture matrix stack and
use glTexCoord3f(x,y,z) [where (x,y,z) is the same vertex coordinate
that you pass to glVertex3f()].
However, in your quest to DO THE RIGHT THING, there is little choice
but to store the texture S,T in the file along with the other vertex
information - any other approach is going to produce seams in the texture
and sooner or later, you'll get dissatisfied with that.
I suggest that in the short term, you use the texture matrix approach
since that gets you a textured image *quickly*. It will also let you
debug the texture loader, the MIPmapping, the glTexBind, etc stuff
and so on. You'll be able to find some nice textures and make some
new (and v.cool) screen shots. Switching to stored (S,T) coords is
something you can attack later when the seams get too annoying.
> Right now I'm using fg_random() to specify
> texture coordinates :-) It seems to work, but has some strange
> effects. :-)
Strange!!...I'm not suprised!
Steve Baker 817-619-8776 (Vox/Vox-Mail)
Raytheon Systems Inc. 817-619-4028 (Fax)
2200 Arlington Downs Road SBaker@link.com (eMail)
Arlington, Texas. TX 76005-6171 SJBaker1@airmail.net (Personal eMail)
http://www.hti.com http://web2.airmail.net/sjbaker1 (personal)
** Beware of Geeks bearing GIF's. **

View file

@ -1,101 +0,0 @@
From curt@me.umn.edu Fri Nov 13 17:02:31 1998
X-VM-v5-Data: ([nil nil nil nil nil nil nil nil nil]
["209" "Fri" "13" "November" "1998" "17:02:29" "-0600" "Curtis L. Olson" "curt@me.umn.edu" nil "6" "nmea stuff 3" "^From:" nil nil "11" nil nil nil nil nil]
nil)
Received: from kenai.me.umn.edu (curt@kenai.me.umn.edu [134.84.18.22])
by meserv.me.umn.edu (8.9.1a/8.9.1) with ESMTP id RAA29774
for <curt@me.umn.edu>; Fri, 13 Nov 1998 17:02:31 -0600 (CST)
Received: (from curt@localhost)
by kenai.me.umn.edu (8.9.1/8.9.1) id RAA32468;
Fri, 13 Nov 1998 17:02:30 -0600
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Message-ID: <13900.47749.734021.549964@kenai.me.umn.edu>
X-Mailer: VM 6.61 under Emacs 19.34.1
From: "Curtis L. Olson" <curt@me.umn.edu>
To: curt@me.umn.edu
Subject: nmea stuff 3
Date: Fri, 13 Nov 1998 17:02:29 -0600 (CST)
http://www.marinesoft.com/Navigation/Technical/index.htm
--
Curtis Olson University of MN, ME Dept.
curt@me.umn.edu
http://www.menet.umn.edu/~curt Try Linux!
From curt@me.umn.edu Fri Nov 13 16:41:49 1998
X-VM-v5-Data: ([nil nil nil nil nil nil nil nil nil]
["730" "Fri" "13" "November" "1998" "16:41:47" "-0600" "Curtis L. Olson" "curt@me.umn.edu" nil "21" "nmea stuff 2" "^From:" nil nil "11" nil nil nil nil nil]
nil)
Received: from kenai.me.umn.edu (curt@kenai.me.umn.edu [134.84.18.22])
by meserv.me.umn.edu (8.9.1a/8.9.1) with ESMTP id QAA29467
for <curt@me.umn.edu>; Fri, 13 Nov 1998 16:41:48 -0600 (CST)
Received: (from curt@localhost)
by kenai.me.umn.edu (8.9.1/8.9.1) id QAA32325;
Fri, 13 Nov 1998 16:41:47 -0600
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Message-ID: <13900.46507.212248.131431@kenai.me.umn.edu>
X-Mailer: VM 6.61 under Emacs 19.34.1
From: "Curtis L. Olson" <curt@me.umn.edu>
To: curt@me.umn.edu
Subject: nmea stuff 2
Date: Fri, 13 Nov 1998 16:41:47 -0600 (CST)
http://www.fet.uni-hannover.de/~purnhage/gps/gps.html
garman hacking project
http://www.abnormal.com/~thogard/gps/grmnhack.html
nmea code documents
http://www.oce.orst.edu/Wecoma/Docs/Computing/XMidas/Formatter_ID.html
http://www.oce.orst.edu/Wecoma/Docs/Computing/XMidas/NMEA_0183_Format.html
http://www.cl.cam.ac.uk/users/ijl20/nmea.txt
http://www.cl.cam.ac.uk/users/ijl20/gps_file.html
(*) http://vancouver-webpages.com/pub/peter/index.html
http://vancouver-webpages.com/pub/peter/idx_nmeadoc.html
http://vancouver-webpages.com/pub/peter/nmeafaq.txt
--
Curtis Olson University of MN, ME Dept.
curt@me.umn.edu
http://www.menet.umn.edu/~curt Try Linux!
From curt@me.umn.edu Fri Nov 13 15:10:29 1998
X-VM-v5-Data: ([nil nil nil nil nil nil nil nil nil]
["376" "Fri" "13" "November" "1998" "15:10:27" "-0600" "Curtis L. Olson" "curt@me.umn.edu" nil "14" "nmea stuff" "^From:" nil nil "11" nil nil nil nil nil]
nil)
Received: from kenai.me.umn.edu (curt@kenai.me.umn.edu [134.84.18.22])
by meserv.me.umn.edu (8.9.1a/8.9.1) with ESMTP id PAA27473
for <curt@me.umn.edu>; Fri, 13 Nov 1998 15:10:28 -0600 (CST)
Received: (from curt@localhost)
by kenai.me.umn.edu (8.9.1/8.9.1) id PAA31952;
Fri, 13 Nov 1998 15:10:27 -0600
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Message-ID: <13900.41027.169267.293790@kenai.me.umn.edu>
X-Mailer: VM 6.61 under Emacs 19.34.1
From: "Curtis L. Olson" <curt@me.umn.edu>
To: curt@me.umn.edu
Subject: nmea stuff
Date: Fri, 13 Nov 1998 15:10:27 -0600 (CST)
http://pfranc.com/projects/g45contr/assemb.htm
http://pfranc.com/ - gps connector
http://pfranc.com/projects/g45contr/beans.htm
http://www.thecapn.com/
http://www.thecapn.com/nmea.htm
http://vancouver-webpages.com/peter/
--
Curtis Olson University of MN, ME Dept.
curt@me.umn.edu
http://www.menet.umn.edu/~curt Try Linux!

View file

@ -1,60 +0,0 @@
Original Article: http://www.egroups.com/list/opengl-gamedev-l/?start=11533
Ben Carter writes:
>
> Hmm.. Here's a question - is it worth optimising out redundant state
> changes? In other words, if I do :
>
> glEnable(GL_TEXTURE_2D);
> <something>
> glEnable(GL_TEXTURE_2D);
> <something else>
Generally, yes. There's usually a validation step that's scheduled
after a call to glEnable(). It updates the internals caches and what
not based on state that was set prior to the enable call. Its difficult
to estimate what every driver does, but there's still internal updating
that probably occurs.
Additionally, its much better to write, for example:
glLightfv( GL_LIGHT0, ... );
glLightfv( GL_LIGHT0, ... );
glLightfv( GL_LIGHT0, ... );
glEnable( GL_LIGHT0 );
glEnable( GL_LIGHTING );
than the opposite. Its less important to do this in initialization, but
if you're dynamically changing things like lighting or texturing, you'll
only validate on the glEnable(), as compared to each glLight() call if
you glEnable() first.
> Is there going to be a performance hit from the second glEnable call?
> Would it be worthwhile writing a wrapper around the state system that
> kept the current state somewhere and only made calls that were
> necessary, or are the drivers smart enough to do that?
Some drivers might be smart enough, but I think the underlying
assumption is that its easier to just reprocess like something's
changed, than actually try to keep track of which state's changed, and
localize that validation.
The wrapper idea could be useful; I guess it depends if the apps
design can't guard against it. FWIW.
Thanx,
Dave
---------------------------------------------------------------------
Dave Shreiner <shreiner@sgi.com>
Silicon Graphics, Inc. (650) 933-4899
-----
FAQ and OpenGL Resources at:
http://www.geocities.com/SiliconValley/Hills/9956/OpenGL
--
Author: Dave Shreiner
INET: shreiner@sgi.com
Fat City Network Services -- (619) 538-5051 FAX: (619) 538-5051
San Diego, California -- Public Internet access / Mailing Lists

View file

@ -1,358 +0,0 @@
From fatcity!root@news.cts.com Thu Mar 26 17:57:48 1998
X-VM-v5-Data: ([nil nil nil nil nil nil nil nil nil]
["8204" "Thu" "26" "March" "1998" "15:32:55" "-0800" "akin@pobox.com" "akin@pobox.com" nil "162" "Re: poly offset " "^From:" nil nil "3" nil nil nil nil nil]
nil)
Received: from mh2.cts.com (root@mh2.cts.com [205.163.24.68])
by meserv.me.umn.edu (8.8.8/8.8.8) with ESMTP id RAA07001
for <curt@me.umn.edu>; Thu, 26 Mar 1998 17:57:43 -0600 (CST)
Received: from king.cts.com (root@king.cts.com [198.68.168.21]) by mh2.cts.com (8.8.7/8.8.5) with ESMTP id PAA05457; Thu, 26 Mar 1998 15:55:40 -0800 (PST)
Received: from donews.cts.com (root@donews.cts.com [192.188.72.21])
by king.cts.com (8.8.7/8.8.7) with SMTP id PAA21507;
Thu, 26 Mar 1998 15:55:38 -0800 (PST)
Received: from fatcity by donews.cts.com with uucp
(Smail3.1.29.1 #5) id m0yIMSJ-0000NEa; Thu, 26 Mar 98 15:53 PST
Received: by fatcity.com (10-Feb-1998/v1.0f-b64/bab) via UUCP id 00016F4B; Thu, 26 Mar 1998 15:32:55 -0800
Message-ID: <F001.00016F4B.19980326153255@fatcity.com>
X-Comment: OpenGL Game Developers Mailing List
X-Sender: akin@pobox.com
Reply-To: OPENGL-GAMEDEV-L@fatcity.com
Errors-To: ML-ERRORS@fatcity.com
Organization: Fat City Network Services, San Diego, California
X-ListServer: v1.0f, build 64; ListGuru (c) 1996-1998 Bruce A. Bergman
Precedence: bulk
Mime-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
From: akin@pobox.com
Sender: root@fatcity.com
To: Multiple recipients of list OPENGL-GAMEDEV-L <OPENGL-GAMEDEV-L@fatcity.com>
Subject: Re: poly offset
Date: Thu, 26 Mar 1998 15:32:55 -0800
Bryan Gibson-Winge wrote:
| I was curious to see if anyone would describe a method of using poly offset
| that didn't eventually conclude with "and mess with the numbers 'till it
| works".
There is such a method, but since it's not in any of the usual OpenGL
literature it's not widely discussed. I'll try to summarize it; maybe
the result could go into the FAQ.
The purpose of polygon offset is to separate two or more primitives
by just enough distance in Z that they can be depth-buffered without
artifacts caused by depth computation roundoff errors, differences in
sampling algorithms for different types of primitives, etc.
The ``factor'' argument provides separation in the case where the
primitives are not parallel. The factor value to use depends on the
screen sizes of the primitives involved.
The canonical example is highlighting the edge of a triangle
by drawing a line between the two associated triangle vertices.
The depth value for each pixel on the line depends only on the
depth values at the two vertices of the triangle edge. However,
the depth value for each pixel in the triangle depends on all
three of the triangle's vertices. Since lines and triangles are
sampled differently (e.g. diamond-exit rule for lines vs. point
sampling for triangles), at a given pixel the depth computed
for the edge line usually differs from the depth computed
for the underlying triangle. This can cause ``stitching'' or
other unpleasant artifacts in the image, because depth buffering
sometimes places the line in front of the triangle and sometimes
behind it.
How much separation is needed to ensure that the line is always
in front of the triangle? If you look at the rasterization
arithmetic or play with a few diagrams, you can see that at some
pixels the depth value for the triangle is computed at a point
almost one pixel away from the ideal edge (which produces the
depth values for the line). Since the triangle can have an almost
arbitrarily large depth slope, there is no fixed offset that will
guarantee separation between the two primitives in all cases.
However, a (variable) separation of 1.0 times the depth slope of
the triangle is always sufficient. (For the purposes of this
discussion, the depth slope is max(|dz/dx|,|dz/dy|). The spec
has additional information.) It's sometimes more than you need,
but it's always large enough to work.
If the line were two pixels wide rather than one, then 1.0
times the depth slope wouldn't be enough separation, because
some pixels on the line might have depth values derived from an
edge point more than one pixel away from the underlying point
on the triangle. 2.0 would be sufficient, though.
So now you understand the factor argument. It should be
nonzero when you're attempting to separate two primitives that
aren't parallel, and its value should be roughly the size of
the screen-space overlap (measured in pixels) between the two
primitives. For any given triangle, the factor is multiplied
by the triangle's depth slope to compute the amount of separation.
The ``units'' or ``bias'' argument provides separation in the case
where the primitives are roughly parallel. The value to use
depends on how many primitives you're trying to stack up.
Consider the edged-triangle case again. What happens when the
depth slope of the triangle is zero? Since the depth slope is
zero, no matter what the factor argument is, you won't get any
separation between the triangle and the edge line. However,
you still want some separation between the two primitives,
so that you get a consistent result (i.e., one that doesn't
depend on the order in which you draw things or on whether the
depth-comparison function tests for equality).
The bias argument guarantees a little separation even in the case
where the depth slope is zero. Furthermore, it generalizes to
the case where the depth slopes of the primitives are nonzero,
but the primitives are roughly parallel (for example, when using
one polygon as a decal on another).
The original version of polygon offset allowed you to specify
a bias that was simply added to the depth value at each pixel.
However, it was quite difficult to choose an appropriate value,
because the choice depends not only on the number of bits in the
depth buffer (offsets smaller than the depth buffer precision
don't do you much good!) but also on the precision of various
computations inside the OpenGL driver and the hardware.
Perspective projection can also make a difference, since
resolution is better at the near clipping plane than it is at
the far clipping plane.
The current version of polygon offset specifies the bias in
multiples of a ``minimum resolvable difference,'' which is some
value determined by the driver developer. The minimum resolvable
difference is sufficient to separate two parallel primitives,
taking into account the perspective projection, size of the
depth buffer, hardware precision, etc.
Since one unit is sufficient to separate two primitives, you
can use more than one unit to separate additional primitives.
For example, by using bias values of 1, 2, 3, ... you can stack
up an arbitrary set of polygons on a base polygon.
Since some OpenGL implementations add the bias before the
perspective divide, a bias of 1.0 unit might be much larger
than is needed for primitives close to the near clipping plane.
If your app is smart enough to know exactly how the driver
behaves, and roughly where in the view volume the primitives
will fall, then it can use a bias of less than 1.0 to separate
primitives close to the near clipping plane. Most of the time
this is *not* worth the effort, though.
Some practical examples:
Drawing lines of width 1.0 pixel on the edge of a triangle
should use a factor of 1.0 (to guarantee separation when the
triangle depth slope is nonzero) and a bias of 1.0 (to guarantee
separation when the triangle depth slope is zero).
Drawing wider lines requires larger factors. A good rule of
thumb might be to use a factor equal to ceil(lineWidth/2 + 0.5).
Drawing decal polygons needs a zero factor and a nonzero bias,
provided that you can guarantee that all of the vertices of
the decal polygons are on the same side of the plane of the
base polygon, and not on that plane. (If intersections occur,
you might need a nonzero factor, because the depth slopes of
the primitives might be different.) Use a bias of 1.0 for the
lowest-level decal (the one closest to the base), 2.0 for the
next-highest, and so on.
Positive factors and biases push primitives in one direction;
negative factors and biases push primitives in the other
direction. Sometimes it makes a difference (for example, if you
want to use the values in the depth buffer for a subsequent pass).
If you run into trouble, the most likely cause is that the driver
developer underestimated the value of the minimum resolvable difference.
(I know of no way to predict this value; I think you just have to
measure it. The basic idea is to binary-search across the range of depth
values, drawing two parallel polygons at each stage and determining if
depth-buffering artifacts occur. Do this once at the near plane, and
once at the far plane, and take the largest result. Repeat for extreme
depthrange values.) Tweaking the bias argument is probably the only
way to resolve this. :-)
Finally, as Steve Baker and I have discussed in the past, the
reference_plane extension is often a cleaner solution than polygon offset,
if your OpenGL implementation supports it.
Allen
--
Author:
INET: akin@pobox.com
Fat City Network Services -- (619) 538-5051 FAX: (619) 538-5051
San Diego, California -- Public Internet access / Mailing Lists
--------------------------------------------------------------------
To REMOVE yourself from this mailing list, send an E-Mail message
to: ListGuru@fatcity.com (note EXACT spelling of 'ListGuru') and in
the message BODY, include a line containing: UNSUB OPENGL-GAMEDEV-L
(or the name of mailing list you want to be removed from). You may
also send the HELP command for other information (like subscribing).
From fatcity!root@news.cts.com Fri Jan 16 04:45:15 1998
X-VM-v5-Data: ([nil nil nil nil nil nil nil nil nil]
["1385" "Fri" "16" "January" "1998" "02:06:11" "-0800" "Mark Kilgard" "mjk@fangio.engr.sgi.com" nil "43" "Re: glPolygonOffset" "^From:" nil nil "1" nil nil nil nil nil]
nil)
Received: from mh2.cts.com (root@mh2.cts.com [205.163.24.68])
by meserv.me.umn.edu (8.8.8/8.8.6) with ESMTP id EAA19075
for <curt@me.umn.edu>; Fri, 16 Jan 1998 04:45:14 -0600 (CST)
Received: from king.cts.com (root@king.cts.com [198.68.168.21]) by mh2.cts.com (8.8.7/8.8.5) with ESMTP id CAA19264; Fri, 16 Jan 1998 02:39:16 -0800 (PST)
Received: from donews.cts.com (root@donews.cts.com [192.188.72.21])
by king.cts.com (8.8.7/8.8.7) with SMTP id CAA07365;
Fri, 16 Jan 1998 02:39:07 -0800 (PST)
Received: from fatcity by donews.cts.com with uucp
(Smail3.1.29.1 #5) id m0xt8sd-00008Sa; Fri, 16 Jan 98 02:20 PST
Received: by fatcity.com (02-Jan-98/v1.0f-b63/bab) via UUCP id 0C92BDFF; Fri, 16 Jan 1998 02:06:11 -0800
Message-ID: <F001.0C92BDFF.19980116020611@fatcity.com>
X-Comment: OpenGL Game Developers Mailing List
X-Sender: mjk@fangio.engr.sgi.com (Mark Kilgard)
Reply-To: OPENGL-GAMEDEV-L@fatcity.com
Errors-To: ML-ERRORS@fatcity.com
Organization: Fat City Network Services, San Diego, California
X-ListServer: v1.0f, build 63; ListGuru (c) 1996-1998 Bruce A. Bergman
Precedence: bulk
Mime-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
From: mjk@fangio.engr.sgi.com (Mark Kilgard)
Sender: root@fatcity.com
To: Multiple recipients of list OPENGL-GAMEDEV-L <OPENGL-GAMEDEV-L@fatcity.com>
Subject: Re: glPolygonOffset
Date: Fri, 16 Jan 1998 02:06:11 -0800
opengl-gamedev,
> At one time I came across web site with example for glPolygonOffset, but I
> can not find it again. Does anybody know web site.
Polygon offset is used to "lift" the projected planar shadows off of
the floor to avoid Z fighting in my dinoshade.c example. See:
http://reality.sgi.com/mjk/tips/TexShadowReflectLight.html
Other cool OpenGL rendering techniques are shown at:
http://reality.sgi.com/mjk/tips/
There are also several polygon offset examples in the GLUT 3.6 source
code distribution. See:
http://reality.sgi.com/mjk/glut3/glut3.html
In particular, look at:
progs/examples/origami.c
progs/examples/surfgrid.c
progs/examples/dinoshade.c
progs/examples/halomagic.c
progs/redbook/polyoff.c
progs/advanced/haloed.c
I hope this helps.
- Mark
--
Author: Mark Kilgard
INET: mjk@fangio.engr.sgi.com
Fat City Network Services -- (619) 538-5030 FAX: (619) 538-5051
San Diego, California -- Public Internet Access
--------------------------------------------------------------------
To REMOVE yourself from this mailing list, send an E-Mail message
to: ListGuru@fatcity.com (note EXACT spelling of 'ListGuru') and in
the message BODY, include a line containing: UNSUB OPENGL-GAMEDEV-L
(or the name of mailing list you want to be removed from). You may
also send the HELP command for other information (like subscribing).
From sjbaker@hti.com Mon Jun 14 08:52:00 1999
X-VM-v5-Data: ([nil nil nil nil nil nil nil nil nil]
["2439" "Mon" "14" "June" "1999" "08:51:06" "-0500" "Stephen J Baker" "sjbaker@hti.com" "<Pine.SGI.3.96.990614083347.20686H-100000@samantha.bgm.link.com>" "65" "Re: glPolygonOffset()" "^From:" nil nil "6" nil nil nil nil nil]
nil)
Received: from issun6.hti.com (sunmgr.hti.com [130.210.206.69])
by meserv.me.umn.edu (8.9.1a/8.9.1) with ESMTP id IAA24327
for <curt@me.umn.edu>; Mon, 14 Jun 1999 08:51:59 -0500 (CDT)
Received: from issun5.hti.com ([130.210.202.3]) by issun6.hti.com
(Netscape Messaging Server 3.6) with ESMTP id AAA3DCD
for <curt@me.umn.edu>; Mon, 14 Jun 1999 08:51:27 -0500
Received: from samantha.bgm.link.com ([130.210.66.11]) by issun5.hti.com
(Netscape Messaging Server 3.6) with SMTP id AAA4A5D
for <curt@me.umn.edu>; Mon, 14 Jun 1999 08:51:26 -0500
X-Sender: steve@samantha.bgm.link.com
Reply-To: Steve Baker <sjbaker@hti.com>
In-Reply-To: <14177.35403.456685.793490@kenai.me.umn.edu>
Message-ID: <Pine.SGI.3.96.990614083347.20686H-100000@samantha.bgm.link.com>
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
From: "Stephen J Baker" <sjbaker@hti.com>
To: "Curtis L. Olson" <curt@me.umn.edu>
Subject: Re: glPolygonOffset()
Date: Mon, 14 Jun 1999 08:51:06 -0500 (CDT)
On Fri, 11 Jun 1999, Curtis L. Olson wrote:
> What's the current recommendation for doing glPolygonOffset() type
> stuff.
It doesn't work on 3Dfx hardware at all.
I have been trying to get David B. to implement it in the FXMesa
driver - but I'm not sure if he plans to do it in Mesa 3.1 or not.
> I think I'm going to need to do something with this in the forseeable
> future. Either with roads and streams, or with runway markings, or
> night lighting ...
Yep.
I have been using the kludge of moving the near/far clip planes
just a tad. This has a similar effect to glPolygonOffset and it
works on 3Dfx hardware.
Under Mesa 3.0, doing this trick is pretty fast too.
Unfortunately, I kindof screwed myself on this one though.
I found a Mesa bug in the fog code - and part of the fix
increased the cost of doing fog density changes (so what!).
Then both David B and I noticed that there was a bug that
prevented the fog density from being recomputed when the
near/far clip range was changed....and the fix for *that*
makes my near/far kludge run pretty slowly.
So, I'm working on the basis that I'll use the near/far
hack on Mesa 3.0 and switch to glPolygonOffset for 3.1.
Of course glPolygonOffset might well work for Mesa 3.0
on non-3Dfx machines - and it certainly should work under
Windoze with the OpenGL's supplied by the hardware vendors.
Regrettably, the value of the two parameters to glPolygonOffset
are likely to vary from card to card. Also, the older SGI
machines (running OpenGL 1.0) don't have glPolygonOffset, and
their glPolygonOffsetEXT has a different definition for the
two glPolygonOffset parameters.
Ugh!
> I want to handle some tile paging issues. I want to try drawing
> all the terrain in immediate mode rather than doing display lists.
That's probably not such a bad idea. Compiled Vertex arrays (in
immediate mode) are the trendy solution (ie that's what Quake III does),
you might want to investigate that.
> Anyways, assuming I get that stuff handled, the next major thing I
> hope to do would be along the lines of airports, or roads, or ground
> lights ...
Yep. Light aircraft pilots often navigate by roads/rivers/railroads
and having those in the scene will certainly help.
Steve Baker (817)619-2657 (Vox/Vox-Mail)
Raytheon Systems Inc. (817)619-2466 (Fax)
Work: sjbaker@hti.com http://www.hti.com
Home: sjbaker1@airmail.net http://web2.airmail.net/sjbaker1

View file

@ -1,331 +0,0 @@
From fatcity!root@news.cts.com Mon Jan 5 14:50:59 1998
X-VM-v5-Data: ([nil nil nil nil t nil nil nil nil]
["1623" "Mon" "5" "January" "1998" "12:03:38" "-0800" "Chris Schoeneman" "crs@millpond.engr.sgi.com" "<F001.0C927564.19980105120338@fatcity.com>" "41" "Re: [Q] OpenGL + Arbitrary display mode in Win32" "^From:" nil nil "1" nil nil nil nil nil]
nil)
Received: from mh2.cts.com (root@mh2.cts.com [205.163.24.68])
by meserv.me.umn.edu (8.8.8/8.8.6) with ESMTP id OAA05604
for <curt@me.umn.edu>; Mon, 5 Jan 1998 14:50:58 -0600 (CST)
Received: from king.cts.com (root@king.cts.com [198.68.168.21]) by mh2.cts.com (8.8.7/8.8.5) with ESMTP id MAA20781; Mon, 5 Jan 1998 12:43:38 -0800 (PST)
Received: from donews.cts.com (root@donews.cts.com [192.188.72.21])
by king.cts.com (8.8.7/8.8.7) with SMTP id MAA01273;
Mon, 5 Jan 1998 12:41:39 -0800 (PST)
Received: from fatcity by donews.cts.com with uucp
(Smail3.1.29.1 #5) id m0xpJ0S-0000Hga; Mon, 5 Jan 98 12:20 PST
Received: by fatcity.com (02-Jan-98/v1.0f-b63/bab) via UUCP id 0C927564; Mon, 05 Jan 1998 12:03:38 -0800
Message-ID: <F001.0C927564.19980105120338@fatcity.com>
X-Comment: OpenGL Game Developers Mailing List
X-Sender: crs@millpond.engr.sgi.com (Chris Schoeneman)
Reply-To: OPENGL-GAMEDEV-L@fatcity.com
Errors-To: ML-ERRORS@fatcity.com
Organization: Fat City Network Services, San Diego, California
X-ListServer: v1.0f, build 63; ListGuru (c) 1996-1998 Bruce A. Bergman
Precedence: bulk
Mime-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 8bit
From: crs@millpond.engr.sgi.com (Chris Schoeneman)
Sender: root@fatcity.com
To: Multiple recipients of list OPENGL-GAMEDEV-L <OPENGL-GAMEDEV-L@fatcity.com>
Subject: Re: [Q] OpenGL + Arbitrary display mode in Win32
Date: Mon, 05 Jan 1998 12:03:38 -0800
Doty, Lee wrote:
>
> Any sound gurus out there? I agree that if we could get 3d sound in
> there, life would get exponentially happier.
I'm willing to donate the sound code from bzflag. It's supports:
arbitrary number of simultaneous sounds (limited by CPU speed)
attenuation with distance
propagation delay
doppler effects
stereo panning
It runs in a separate thread and has a very simple interface. I have
it running on Windows 95/NT and Irix, and Daryll Strauss ported it to
Linux. The Windows version would work better if DirectSound didn't
suck so bad, but it works reasonably well now.
A drawback is that it can suck up a lot of CPU time since it has to
do its own filtering and mixing. It also needs support for a better
HRTF, reverb with distance, high-frequency rolloff with distance, and
a way to set the volume on individual sounds. That last one is trivial
but the others are more involved.
Mark, you interested? I've also got fullscreen and resolution changing
code for Irix.
Cheers,
-chris
--
Author: Chris Schoeneman
INET: crs@millpond.engr.sgi.com
Fat City Network Services -- (619) 538-5030 FAX: (619) 538-5051
San Diego, California -- Public Internet Access
--------------------------------------------------------------------
To REMOVE yourself from this mailing list, send an E-Mail message
to: ListGuru@fatcity.com (note EXACT spelling of 'ListGuru') and in
the message BODY, include a line containing: UNSUB OPENGL-GAMEDEV-L
(or the name of mailing list you want to be removed from). You may
also send the HELP command for other information (like subscribing).
From crs@millpond.engr.sgi.com Mon Jan 5 15:36:10 1998
X-VM-v5-Data: ([nil nil nil nil t nil nil nil nil]
["1034" "Mon" "5" "January" "1998" "13:35:59" "-0800" "Chris Schoeneman" "crs@millpond.engr.sgi.com" "<199801052135.NAA21198@millpond.engr.sgi.com>" "23" "Re: bzflag sound playing code" "^From:" nil nil "1" nil nil nil nil nil]
nil)
Received: from sgi.sgi.com (SGI.COM [192.48.153.1])
by meserv.me.umn.edu (8.8.8/8.8.6) with SMTP id PAA07002
for <curt@me.umn.edu>; Mon, 5 Jan 1998 15:36:07 -0600 (CST)
Received: from cthulhu.engr.sgi.com (cthulhu.engr.sgi.com [192.26.80.2]) by sgi.sgi.com (950413.SGI.8.6.12/970507) via ESMTP id NAA08189
for <@sgi.engr.sgi.com:curt@me.umn.edu>; Mon, 5 Jan 1998 13:36:04 -0800
env-from (crs@millpond.engr.sgi.com)
Received: from millpond.engr.sgi.com (millpond.engr.sgi.com [150.166.55.67]) by cthulhu.engr.sgi.com (950413.SGI.8.6.12/960327.SGI.AUTOCF) via ESMTP id NAA07557 for <@cthulhu.engr.sgi.com:curt@me.umn.edu>; Mon, 5 Jan 1998 13:36:00 -0800
Received: (from crs@localhost) by millpond.engr.sgi.com (950413.SGI.8.6.12/960327.SGI.AUTOCF) id NAA21198 for curt@me.umn.edu; Mon, 5 Jan 1998 13:35:59 -0800
Message-Id: <199801052135.NAA21198@millpond.engr.sgi.com>
In-Reply-To: <199801052103.PAA30512@kenai.me.umn.edu> from "Curtis L. Olson" at Jan 5, 98 03:03:52 pm
X-Mailer: ELM [version 2.4 PL23]
MIME-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 8bit
From: crs@millpond.engr.sgi.com (Chris Schoeneman)
To: curt@me.umn.edu (Curtis L. Olson)
Subject: Re: bzflag sound playing code
Date: Mon, 5 Jan 1998 13:35:59 -0800 (PST)
Curtis L. Olson wrote:
>
> Is the licensing of the bzflag sound code such that I could use it to
> build in sounds support for our project? We would want to have a
> continuously looping engine sound (plus wind sound, and maybe rain
> hitting the windshield sound.) Then we'd need to intersperse the
> other sounds such as flaps, stall horn, landing gear, thunder, crash,
> etc. It sounds like it might be exactly the sort of thing we need.
Hmm, it's not a perfect match. Most of your sounds are purely local,
so you don't need the stereo panning, propagation delay, and doppler
effect. However, that's no reason not to try it!
Ripping my sound code out from bzflag shouldn't be too much work
but I'm really busy at the moment. Could you wait about a week?
BTW, as far as licensing goes I'd just want the copyright notice to
stay on the source files (we'll have to tweek the legal notice) and
a mention in the credits, if you have a credits list. A right to
use enhancements to the code would be cool, too.
Cheers,
-chris
From crs@millpond.engr.sgi.com Mon Jan 5 16:22:27 1998
X-VM-v5-Data: ([nil nil nil nil t nil nil nil nil]
["1125" "Mon" "5" "January" "1998" "14:22:22" "-0800" "Chris Schoeneman" "crs@millpond.engr.sgi.com" "<199801052222.OAA21481@millpond.engr.sgi.com>" "27" "Re: bzflag sound playing code" "^From:" nil nil "1" nil nil nil nil nil]
nil)
Received: from sgi.sgi.com (SGI.COM [192.48.153.1])
by meserv.me.umn.edu (8.8.8/8.8.6) with SMTP id QAA08463
for <curt@me.umn.edu>; Mon, 5 Jan 1998 16:22:26 -0600 (CST)
Received: from cthulhu.engr.sgi.com (cthulhu.engr.sgi.com [192.26.80.2]) by sgi.sgi.com (950413.SGI.8.6.12/970507) via ESMTP id OAA22876
for <@sgi.engr.sgi.com:curt@me.umn.edu>; Mon, 5 Jan 1998 14:22:25 -0800
env-from (crs@millpond.engr.sgi.com)
Received: from millpond.engr.sgi.com (millpond.engr.sgi.com [150.166.55.67]) by cthulhu.engr.sgi.com (950413.SGI.8.6.12/960327.SGI.AUTOCF) via ESMTP id OAA25764 for <@cthulhu.engr.sgi.com:curt@me.umn.edu>; Mon, 5 Jan 1998 14:22:22 -0800
Received: (from crs@localhost) by millpond.engr.sgi.com (950413.SGI.8.6.12/960327.SGI.AUTOCF) id OAA21481 for curt@me.umn.edu; Mon, 5 Jan 1998 14:22:22 -0800
Message-Id: <199801052222.OAA21481@millpond.engr.sgi.com>
In-Reply-To: <199801052204.QAA31163@kenai.me.umn.edu> from "Curtis L. Olson" at Jan 5, 98 04:04:44 pm
X-Mailer: ELM [version 2.4 PL23]
MIME-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 8bit
From: crs@millpond.engr.sgi.com (Chris Schoeneman)
To: curt@me.umn.edu (Curtis L. Olson)
Subject: Re: bzflag sound playing code
Date: Mon, 5 Jan 1998 14:22:22 -0800 (PST)
Curtis L. Olson wrote:
>
> Does your code support continuously looping sounds? Or would this be
> fairly straight forward to implement? I've done virtually nothing
> with sound in my life other than listen to it. :-)
It does/should. bzflag doesn't use this code though so it may suffer
from bit rot. I used it to test the Doppler effect.
There may also be some issues around having a very large world. Imagine
the sound as a spherical shell. Outside the shell, sound hasn't reached
you yet; inside the shell, the sound has passed by. In bzflag I need
to keep sounds around for as long as any part of the shell is inside the
world because it's possible to move from one place to another instantly.
Seems to me you have this same situation if you want external views.
The sound engine is clever enough not to process sounds unless you're in
the shell, so a large world probably won't cause any problems. I'm just
not sure at the moment.
> This all sounds completely reasonable. All our stuff is released
> under the basic "GPL".
Should be fine. I've no problem releasing my code under the GPL.
Cheers,
-chris
From crs@millpond.engr.sgi.com Mon Jan 5 17:33:03 1998
X-VM-v5-Data: ([nil nil nil nil t nil nil nil nil]
["660" "Mon" "5" "January" "1998" "15:32:53" "-0800" "Chris Schoeneman" "crs@millpond.engr.sgi.com" "<199801052332.PAA21873@millpond.engr.sgi.com>" "18" "Re: bzflag sound playing code" "^From:" nil nil "1" nil nil nil nil nil]
nil)
X-VM-Message-Order:
(1 2 3 4 6 5 7 8 9 10 11 12 13 14 15
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
61 62 63 64)
X-VM-Summary-Format: "%n %*%a %-17.17F %-3.3m %2d %4l/%-5c %I\"%s\"\n"
X-VM-Labels: ("r")
X-VM-VHeader: ("Resent-" "From:" "Sender:" "To:" "Apparently-To:" "Cc:" "Subject:" "Date:") nil
X-VM-Bookmark: 57
Received: from sgi.sgi.com (SGI.COM [192.48.153.1])
by meserv.me.umn.edu (8.8.8/8.8.6) with SMTP id RAA10765
for <curt@me.umn.edu>; Mon, 5 Jan 1998 17:33:01 -0600 (CST)
Received: from cthulhu.engr.sgi.com (cthulhu.engr.sgi.com [192.26.80.2]) by sgi.sgi.com (950413.SGI.8.6.12/970507) via ESMTP id PAA14176
for <@sgi.engr.sgi.com:curt@me.umn.edu>; Mon, 5 Jan 1998 15:33:00 -0800
env-from (crs@millpond.engr.sgi.com)
Received: from millpond.engr.sgi.com (millpond.engr.sgi.com [150.166.55.67]) by cthulhu.engr.sgi.com (950413.SGI.8.6.12/960327.SGI.AUTOCF) via ESMTP id PAA19353 for <@cthulhu.engr.sgi.com:curt@me.umn.edu>; Mon, 5 Jan 1998 15:32:53 -0800
Received: (from crs@localhost) by millpond.engr.sgi.com (950413.SGI.8.6.12/960327.SGI.AUTOCF) id PAA21873 for curt@me.umn.edu; Mon, 5 Jan 1998 15:32:53 -0800
Message-Id: <199801052332.PAA21873@millpond.engr.sgi.com>
In-Reply-To: <199801052322.RAA32525@kenai.me.umn.edu> from "Curtis L. Olson" at Jan 5, 98 05:22:08 pm
X-Mailer: ELM [version 2.4 PL23]
MIME-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 8bit
From: crs@millpond.engr.sgi.com (Chris Schoeneman)
To: curt@me.umn.edu (Curtis L. Olson)
Subject: Re: bzflag sound playing code
Date: Mon, 5 Jan 1998 15:32:53 -0800 (PST)
Curtis L. Olson wrote:
>
> Our code is all GPL'd, so if you can keep within those license
> restrictions feel free to borrow code. (Or does bzflag take place a
> long time ago in a galaxy far, far away ... I haven't tried running it
> yet myself.) :-)
Actually, it's already got accurate sun, moon, and stars. The star
magnitudes are relatively okay (there's not enough dynamic range on
a monitor anyway). You can specify any position on the earth, and
the positions are accurately based on the time and date. Great minds
think alike, eh?
I don't have the planets as I thought I'd gone overboard myself. Guess
I hadn't gone far enough!
Cheers,
-chris
From curt@me.umn.edu Thu Apr 30 09:02:28 1998
X-VM-v5-Data: ([nil nil nil nil nil nil nil nil nil]
["3542" "" "30" "April" "1998" "09:02:26" "-0500" "Curtis L. Olson" "curt@me.umn.edu" nil "88" "[comp.os.linux.announce] Enlightened Sound Daemon version 0.2" "^From:" nil nil "4" nil nil nil nil nil]
nil)
Received: from kenai.me.umn.edu (curt@kenai.me.umn.edu [134.84.18.22])
by meserv.me.umn.edu (8.8.8/8.8.8) with ESMTP id JAA10406
for <curt@me.umn.edu>; Thu, 30 Apr 1998 09:02:28 -0500 (CDT)
Received: (from curt@localhost)
by kenai.me.umn.edu (8.8.5/8.8.5) id JAA19157;
Thu, 30 Apr 1998 09:02:27 -0500
Message-ID: <u87m47v24t.fsf@kenai.me.umn.edu>
Lines: 88
X-Mailer: Gnus v5.3/Emacs 19.34
From: curt@me.umn.edu (Curtis L. Olson)
Sender: curt@me.umn.edu
To: curt@me.umn.edu
Subject: [comp.os.linux.announce] Enlightened Sound Daemon version 0.2
Date: 30 Apr 1998 09:02:26 -0500
--
Curtis Olson University of MN, ME Dept.
curt@me.umn.edu
http://www.menet.umn.edu/~curt Try Linux!
------- Start of forwarded message -------
From: "Eric B. Mitchell" <emitchell@altaira.com>
Newsgroups: comp.os.linux.announce
Subject: Enlightened Sound Daemon version 0.2
Followup-To: comp.os.linux.misc
Date: Thu, 30 Apr 1998 08:25:43 GMT
Organization: Altair Aerospace Corporation
Message-ID: <pycola.893924743.30806@laulujoutsen.pc.helsinki.fi>
Reply-To: emitchell@altaira.com
-----BEGIN PGP SIGNED MESSAGE-----
I am pleased to announce the preliminary release of the
Enlightened Sound Daemon (EsounD version 0.2) for Linux.
More details at <URL:http://www.netcom.com/~ericmit/EsounD.html>.
This program is designed to mix together several digitized
audio streams for playback by a single device. The current
list of features includes the following functionality:
o A simple authentication scheme is implemented. The first
process to present a 16 byte key to the daemon determines
the ownership of the daemon. The owner of the daemon may
allow or disallow connections from other keys. If a HUP
signal is received, ownership of the daemon is reset.
o Playback of multiple digital samples simultaneously is
supported. The daemon uses a raw sample format which
is easily generated by the SOX utility from many other
data formats.
o The mixed audio data may be output from the daemon as a
"monitor" stream.
o Recording from the current input of the sound device is
supported. Full duplex operation (simultaneous recording
and playback) is supported.
o Client connections may cache samples for playback by an
assigned identification number. For example, a window
manager may cache samples in the server for playback on
various events, and play them back without replaying the
full audio stream for the sample. Samples may be looped
until the server receives a "stop sample" message.
Currently, the only platform supported is Linux. It is intended
that this program support multiple platforms. I have limited
access to other Unix platforms, so any help in porting the
Enlightened Sound Daemon to other platforms is appreciated.
The amp program, by Tomislav Uzelac may be a good reference
for porting the audio interface to other platforms.
This is to be considered an alpha release, as functionality
remains to be implemented.
- -- ebm
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=+
| __ a.k.a. Eric B. Mitchell |
| |_) . _ _| _| _ ericmit@ix.netcom.com |
| | \ ( (_ (_| (_| (_| (/_ www.netcom.com/~ericmit |
| How's My Programming? Call: 1 - 800 - DEV - NULL |
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=+
- --
This article has been digitally signed by the moderator, using PGP.
http://www.iki.fi/mjr/cola-public-key.asc has PGP key for validating signature.
Send submissions for comp.os.linux.announce to: linux-announce@news.ornl.gov
PLEASE remember a short description of the software and the LOCATION.
This group is archived at http://www.iki.fi/mjr/linux/cola.html
-----BEGIN PGP SIGNATURE-----
Version: 2.6.3ia
Charset: latin1
iQCVAgUBNUg1h1rUI/eHXJZ5AQHjSwP/aGb9U1fIgnUA6qMaD6x/JeTM2IJVRLDa
YxXoZ9EbENIKCbV9lV0PcGogW0+eA2zAZq3tQFu9P9B+eFX6jcVD2FhDekvFI5ZS
j44u74PbNU45LIuw2xxiaBAgfZcnZ9XZ3uy6Z9Yu3Xd+xkZ5k9nxafP1+tkPztmA
y5okM7m4rEs=
=Y1B3
-----END PGP SIGNATURE-----
------- End of forwarded message -------

View file

@ -1,85 +0,0 @@
From owner-fgfs-devel@flightgear.org Fri Mar 12 12:57:31 1999
X-VM-v5-Data: ([nil nil nil nil t nil nil nil nil]
["1824" "Fri" "12" "March" "1999" "12:55:14" "-0600" "Stephen J Baker" "sjbaker@hti.com" "<Pine.SGI.3.96.990312123905.8630A-100000@samantha.bgm.link.com>" "53" "[FGFS-Devel] Scene graph API." "^From:" nil nil "3" nil nil nil nil nil]
nil)
Received: from mailhub.woodsoup.org (IDENT:root@anduin.physics.iastate.edu [129.186.82.1])
by meserv.me.umn.edu (8.9.1a/8.9.1) with ESMTP id MAA10391
for <curt@me.umn.edu>; Fri, 12 Mar 1999 12:57:30 -0600 (CST)
Received: from majordom by mailhub.woodsoup.org with local (Exim 1.92 #1)
for fgfs-devel-outgoing@flightgear.org
id 10LX6P-0003CG-00; Fri, 12 Mar 1999 12:56:09 -0600
Received: from sunmgr.hti.com ([130.210.206.69] helo=issun6.hti.com)
by mailhub.woodsoup.org with esmtp (Exim 1.92 #1)
for fgfs-devel@flightgear.org
id 10LX6O-0003C8-00; Fri, 12 Mar 1999 12:56:08 -0600
Received: from issun5.hti.com ([130.210.202.3]) by issun6.hti.com
(Netscape Messaging Server 3.6) with ESMTP id AAAEEB
for <fgfs-devel@flightgear.org>; Fri, 12 Mar 1999 12:55:26 -0600
Received: from samantha.bgm.link.com ([130.210.65.19]) by issun5.hti.com
(Netscape Messaging Server 3.6) with SMTP id AAA6D20
for <fgfs-devel@flightgear.org>; Fri, 12 Mar 1999 12:55:25 -0600
X-Sender: steve@samantha.bgm.link.com
Message-ID: <Pine.SGI.3.96.990312123905.8630A-100000@samantha.bgm.link.com>
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Precedence: bulk
Reply-To: fgfs-devel@flightgear.org
From: "Stephen J Baker" <sjbaker@hti.com>
Sender: owner-fgfs-devel@flightgear.org
To: Flight Gear Mailing List <fgfs-devel@flightgear.org>
Subject: [FGFS-Devel] Scene graph API.
Date: Fri, 12 Mar 1999 12:55:14 -0600 (CST)
I have just posted an early (pre-alpha - whatever) version of my
new Scene Graph API and simple matrix/vector math library onto my
web site:
http://www.woodsoup.org/~sbaker/ssg
...and...
http://www.woodsoup.org/~sbaker/sg
...these are the libraries that I'm using in my Tux-the-Penguin
game - so they *work* pretty well - but may not be as complete
or well-structured as they should be. There are also no example
programs (apart from the game itself) and the only file loader
is for an obscure ASCII format that nobody is likely to want
as a standard. I hope to fix that somewhat over then next few
weeks - but I'm on vacation next week.
I think these libraries could be applicable to FGFS in several
areas:
1) 3D instrument panels.
2) BUildings and other hand-created features like airfields,
detailed city areas and so forth.
3) Other aircraft.
There are some issues about how this would all integrate into
Curts terrain rendering scheme - but I think it's do-able.
Anyway, it would be nice if people would read the manuals
and email me some comments, criticisms, suggestions, etc.
Like I said though - these are really early cuts so don't
go out and write 100,000 lines of code that depend on
them - OK?
Since I'm going to be out in the wilds of Arkansas for the
next week (Do they have email out there? I *think* they
have phones), don't expect a quick answer to any questions.
Steve Baker (817)619-2657 (Vox/Vox-Mail)
Raytheon Systems Inc. (817)619-2466 (Fax)
Work: sjbaker@hti.com http://www.hti.com
Home: sjbaker1@airmail.net http://web2.airmail.net/sjbaker1
--
Please visit the FGFS web page: http://www.flightgear.org
For help on using this list (especially unsubscribing), send a message to
"fgfs-devel-request@flightgear.org" with a single line of text: "help".

View file

@ -1,66 +0,0 @@
From kaszeta@me.umn.edu Tue Apr 27 12:25:04 1999
X-VM-v5-Data: ([nil nil nil nil nil nil nil nil nil]
["1377" "Tue" "27" "April" "1999" "12:25:03" "-0500" "Richard Kaszeta" "kaszeta@me.umn.edu" nil "46" "Screen Dump under OpenGL" "^From:" nil nil "4" nil nil nil nil nil]
nil)
Received: from bofh.me.umn.edu (kaszeta@bofh.me.umn.edu [134.84.18.23])
by meserv.me.umn.edu (8.9.1a/8.9.1) with ESMTP id MAA17257
for <curt@me.umn.edu>; Tue, 27 Apr 1999 12:25:04 -0500 (CDT)
Received: (from kaszeta@localhost)
by bofh.me.umn.edu (8.9.1/8.9.1) id MAA32360;
Tue, 27 Apr 1999 12:25:04 -0500
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Message-ID: <14117.62191.861894.721574@bofh.me.umn.edu>
X-Mailer: VM 6.47 under Emacs 19.34.1
From: Richard Kaszeta <kaszeta@me.umn.edu>
To: curt@me.umn.edu
Subject: Screen Dump under OpenGL
Date: Tue, 27 Apr 1999 12:25:03 -0500 (CDT)
Dumps the framebuffer to a .ppm file:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <GL/glut.h>
#define RGB 3 /* 3 bytes of color info per pixel */
#define RGBA 4 /* 4 bytes of color+alpha info */
void my_glDumpWindow(const char * filename, int win_width, int win_height) {
int i, j, k, q;
GLubyte *buffer;
unsigned char *ibuffer;
FILE *fp;
buffer = (GLubyte *) malloc(win_width*win_height*RGBA);
ibuffer = (unsigned char *) malloc(win_width*win_height*RGB);
/* read window contents from color buffer with glReadPixels */
glFinish();
glReadPixels(0, 0, win_width, win_height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
fp = fopen(filename, "w");
fprintf(fp, "P6\n# CREATOR: glReadPixel()\n%d %d\n%d\n",
win_width, win_height, UCHAR_MAX);
q = 0;
for (i = 0; i < win_height; i++)
for (j = 0; j < win_width; j++)
for (k = 0; k < RGB; k++)
ibuffer[q++] = (unsigned char)
*(buffer + (RGBA*((win_height-1-i)*win_width+j)+k));
fwrite(ibuffer, sizeof(unsigned char), RGB*win_width*win_height, fp);
fclose(fp);
free(buffer);
free(ibuffer);
printf("wrote file (%d x %d pixels, %d bytes)\n",
win_width, win_height, RGB*win_width*win_height);
}
--
Richard W Kaszeta PhD. Candidate and Sysadmin
bofh@me.umn.edu University of MN, ME Dept
http://www.menet.umn.edu/~kaszeta

View file

@ -1,178 +0,0 @@
From owner-fgfs-devel@flightgear.org Tue Jun 15 12:24:35 1999
X-VM-v5-Data: ([nil nil nil nil t nil nil nil nil]
["5330" "Tue" "15" "June" "1999" "12:24:25" "-0500" "Stephen J Baker" "sjbaker@hti.com" "<Pine.SGI.3.96.990615115046.5472A-100000@lechter.bgm.link.com>" "145" "RE: [FGFS-Devel] Towards a Binary Scenery Format" "^From:" nil nil "6" nil nil nil nil nil]
nil)
Received: from mailhub.woodsoup.org (IDENT:root@anduin.physics.iastate.edu [129.186.82.1])
by meserv.me.umn.edu (8.9.1a/8.9.1) with ESMTP id MAA00346
for <curt@me.umn.edu>; Tue, 15 Jun 1999 12:24:34 -0500 (CDT)
Received: from majordom by mailhub.woodsoup.org with local (Exim 1.92 #1)
for fgfs-devel-outgoing@flightgear.org
id 10twwQ-0005Iu-00; Tue, 15 Jun 1999 12:24:06 -0500
Received: from sunmgr.hti.com ([130.210.206.69] helo=issun6.hti.com)
by mailhub.woodsoup.org with esmtp (Exim 1.92 #1)
for fgfs-devel@flightgear.org
id 10twwP-0005Ia-00; Tue, 15 Jun 1999 12:24:05 -0500
Received: from issun5.hti.com ([130.210.202.3]) by issun6.hti.com
(Netscape Messaging Server 3.6) with ESMTP id AAA5868
for <fgfs-devel@flightgear.org>; Tue, 15 Jun 1999 12:23:32 -0500
Received: from lechter.bgm.link.com ([130.210.63.22]) by issun5.hti.com
(Netscape Messaging Server 3.6) with SMTP id AAA40B9
for <fgfs-devel@flightgear.org>; Tue, 15 Jun 1999 12:23:31 -0500
X-Sender: steve@lechter.bgm.link.com
In-Reply-To: <14182.32328.710469.293159@kenai.me.umn.edu>
Message-ID: <Pine.SGI.3.96.990615115046.5472A-100000@lechter.bgm.link.com>
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Precedence: bulk
Reply-To: fgfs-devel@flightgear.org
From: "Stephen J Baker" <sjbaker@hti.com>
Sender: owner-fgfs-devel@flightgear.org
To: fgfs-devel@flightgear.org
Subject: RE: [FGFS-Devel] Towards a Binary Scenery Format
Date: Tue, 15 Jun 1999 12:24:25 -0500 (CDT)
On Tue, 15 Jun 1999, Curtis L. Olson wrote:
> With what you know about our current terrain scheme, do we have any
> chance of doing things like having object cast shadows on the ground
> ... especially our own plane? How about landing lights illuminating
> the ground?
Well, ownship shadow is do-able so long as people don't get too picky.
General shadows are impossible. Shadows for a few specialised things
might be doable if they are really important to you. (We need them
for things like Night-Vision-Goggles (NVG's) where shadows cast by
the moon are CRITICAL to military operations).
For ownship shadows,
You can figure out the intersection of the ray from the sun through
the center of the plane onto the ground polygons - that's not too
hard.
Then take a texture mapped quad containing a plan-view shadow and
rotate it to the same heading as ownship but with the roll/pitch
driven by the terrain.
That looks OK for 99% of the time and is probably 'good enough'.
I do this in my Tux game - with a circular shadow texture,
there are LOTS of cases where it fails, nobody noticed yet!
Caveats:
* It doesn't take account of ownship roll/pitch - although
for small angles, you can perhaps kludge it by squashing the
shadow polygon in width/length.
* It won't shadow things like buildings or other aircraft.
(because the shadow is projected onto the terrain beneath
them).
* It won't split across terrain polygons - so it tends to
momentarily vanish in concavities and momentarily float
above convexities.
* You need a different shadow texture for each aircraft type.
* It's not easy to produce umbra/penumbra effects as a
function of ownship altitude...but you could maybe
kludge something with glAlphaFunc.
Helicopter and VTOL pilots use the ownship shadow as an
important height cue - so you need to get it right for
them. However, they tend not to land with 60 degree
bank angles! I believe that Navy pilots learn to use
the shadow as a height cue when ditching in the ocean.
Landing lights are a pain. In OpenGL, you can define a light
source for each landing light (not many planes need more than
the half dozen or so that OpenGL guarantees to support).
The problem is that lighting is only computed at polygon
vertices. When you are on approach, there are likely to
be polygons that are MUCH larger than the puddle of light
that the landing light projects.
You can decimate polygons either dynamically (hard) or
statically (easier).
Statically, just make runway/taxiway/apron polygons that
are modelled so as to be switched into 'high detail' at
close range using an LOD node (ssgRangeSelector in SSG).
That's not really great because you can't land on a road
or in a field that the database prep tools didn't think
you'd want to land in because your lights won't work well.
You'll also get bad things happening when you fly low
over general terrain with your landing lights on.
Dynamically is REALLY hard to code with any generality.
Instead of using OpenGL lights, you could use multi-pass
rendering or make use of Multi-texture (if your hardware
supports it). In this way, you can render a daylight
scene and on a second pass render a black anti-light
texture over the entire scene.
In the past, that was REALLY COSTLY because it halved
your frame rate. However, the latest generation of
PC cards can do multi-texture which should greatly
speed that up. On a Voodoo-3, the second pass is
essentialy free.
Multipass is great for single landing lights - but
if you have a wingman who is landing in formation,
or if you are flying a 747 with half a dozen
landing lights - then you need one OpenGL rendering
pass PER LIGHT - plus the original...now you are
screwed and will lose framerate.
A *REALLY* cheesy solution that I used once in a
railroad simulator was to render the scene with
dense black fog applied to all of the terrain and
buildings - but not to lights and the sky. The
result was an omni-directional light source that
didn't cast nice pools of light - but which was
utterly free.
Using a second texture pass, it's hard to get the
light to attenuate nicely with range - so you tend
to light up mountains that are 40 miles away with
your super-bright landing lights! The kludge to
fix that is to add the cheesy black fog trick to
the light-texture pass.
I think that of all of these, statically diced
polygons works best. However, it rather relies
on the fact that:
* Light aircraft don't often fly low over
open country at night.
* Big aircraft don't fly low over open
country at all.
* Airforce planes don't fly with landing
lights on at all unless they are on
final approach. This would be stoopid
in combat - and they are taught to fly
that way at all times.
* Navy pilots are even taught to land without
landing lights.
If FGFS pilots want to land on freeways at night,
then their landing lights would look *terrible*.
Steve Baker (817)619-2657 (Vox/Vox-Mail)
Raytheon Systems Inc. (817)619-2466 (Fax)
Work: sjbaker@hti.com http://www.hti.com
Home: sjbaker1@airmail.net http://web2.airmail.net/sjbaker1
--
Please visit the FGFS web page: http://www.flightgear.org
For help on using this list (especially unsubscribing), send a message to
"fgfs-devel-request@flightgear.org" with a single line of text: "help".

244
Hints/ssg
View file

@ -1,244 +0,0 @@
From owner-fgfs-devel@flightgear.org Thu May 20 08:36:54 1999
X-VM-v5-Data: ([nil nil nil nil nil nil nil nil nil]
["8912" "Thu" "20" "May" "1999" "08:35:37" "-0500" "Stephen J Baker" "sjbaker@hti.com" nil "210" "Re: [FGFS-Devel] Things to do list" "^From:" nil nil "5" nil nil nil nil nil]
nil)
Received: from mailhub.woodsoup.org (IDENT:root@anduin.physics.iastate.edu [129.186.82.1])
by meserv.me.umn.edu (8.9.1a/8.9.1) with ESMTP id IAA09534
for <curt@me.umn.edu>; Thu, 20 May 1999 08:36:53 -0500 (CDT)
Received: from majordom by mailhub.woodsoup.org with local (Exim 1.92 #1)
for fgfs-devel-outgoing@flightgear.org
id 10kSzs-0005Sv-00; Thu, 20 May 1999 08:36:28 -0500
Received: from sunmgr.hti.com ([130.210.206.69] helo=issun6.hti.com)
by mailhub.woodsoup.org with esmtp (Exim 1.92 #1)
for fgfs-devel@flightgear.org
id 10kSzq-0005SX-00; Thu, 20 May 1999 08:36:26 -0500
Received: from issun5.hti.com ([130.210.202.3]) by issun6.hti.com
(Netscape Messaging Server 3.6) with ESMTP id AAA3BC4
for <fgfs-devel@flightgear.org>; Thu, 20 May 1999 08:35:55 -0500
Received: from samantha.bgm.link.com ([130.210.66.11]) by issun5.hti.com
(Netscape Messaging Server 3.6) with SMTP id AAA3FBA
for <fgfs-devel@flightgear.org>; Thu, 20 May 1999 08:35:54 -0500
X-Sender: steve@samantha.bgm.link.com
In-Reply-To: <14147.454.803438.762388@pinky.infoplane.com>
Message-ID: <Pine.SGI.3.96.990520073715.2204E-100000@samantha.bgm.link.com>
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Precedence: bulk
Reply-To: fgfs-devel@flightgear.org
From: "Stephen J Baker" <sjbaker@hti.com>
Sender: owner-fgfs-devel@flightgear.org
To: fgfs-devel@flightgear.org
Subject: Re: [FGFS-Devel] Things to do list
Date: Thu, 20 May 1999 08:35:37 -0500 (CDT)
On Wed, 19 May 1999, Curtis L. Olson wrote:
> Flight Gear world coordinate system:
>
> (0, 0, 0) is at the center of the earth. Z is up through the north
> pole, X is out through point where the zero meridian intersects the
> equator (somewhere in africa). Y is out where the 90th meridian
> intersects the equator (somewhere in the indian ocean.) Here's a
> picture:
>
> http://www.flightgear.org/Docs/Scenery/CoordinateSystem/img8.gif
>
> However, using this coordinate system directly to render the scenery
> in OpenGL leads to all sorts of precision problems. So, for actual
> rendering in OpenGL, I use a coordinate system that is aligned exactly
> the same, but is translated so that (0, 0, 0) is at the center of the
> current tile's bounding sphere. This means that all the coordinates
> I'm feeding to opengl are "near" (0, 0, 0) within a couple thousand
> meters.
But each tile must have a translation matrix pushed on the OpenGL
stack before it is rendered - right? Does that translation
operate:
* Relative to ownship.
* Relative to some arbitary origin (like the center of the 'current'
tile) that moves periodically (eg when you cross a tile boundary).
* Some other way.
> My "embarrassing problem" is that I don't understand enough about ssg
> to know if it could be made to mesh well with the current flight gear
> coordinate system.
Well, I think the problem of point features on the terrain is a different
one from moving models like aircraft.
For aircraft, we can have an SSG scene graph, with each aircraft
model positioned under a ssgTransform node and an ssgSelector node.
Something like this:
o ssgRoot for all of our
| moving models
_________|_________
| | | | |
o o o o o ssgSelector nodes
| | | | |
o o o o o ssgTransform nodes
| | | | |
cessna pitts C130 F16 747 Aircraft models loaded
from disk.
(It would be more complex if - for example - we wanted three
747's in the scenario - but wanted to use the same polygonal
model for all three of them...still, it's not too bad)
The ssgSelector nodes allow the planes to be turned on and off
as needed in the scenario we are playing. The ssgTransform nodes
let us position them relative to some arbitary origin.
Each frame, we pick up the location of each model (Lat/Lon/Alt/
Heading/Pitch/Roll) from some FGFS data structure somewhere.
We do a very quick and dirty check to see if it is within (say)
20 miles of the eyepoint (you can do that just be comparing lat/long
with ownship lat/long using an approximate table to convert degrees
longitude into meters depending on your latitude).
If the aircraft is too far away, use it's ssgSelector node to turn
it off - this saves the expense of a costly LLA->XYZ conversion and
makes culling cheaper for SSG when there are a lot of aircraft in
the managed scene.
We need to pick a 'current local origin'. This could be the center
of the nearest terrain tile, it could be a point vertically below
the ownship at sea level...somewhere close by.
If the aircraft is reasonably close, compute the location of the aircraft
relative to the current local origin. This entails some double-precision
math but it's not all that hard - and it boils down to a 'float' 4x4 matrix.
I imagine the math for this is already there to compute the eyepoint
transform for the ownship.
Put that matrix into the ssgTransform node and turn on the ssgSelector
for that plane.
At some point (probably after the terrain is rendered) you tell SSG
where the ownship is relative to the current local origin and cull
and draw the SSG scene.
All done.
At present, the aircraft models have to be in AC3D format - because
that's the only file loader. However, there is work in progress
(check the PLIB mailing list for details) to produce a VRML-2 loader,
which should make it possible for anyone to build or convert aircraft
models using a variety of modelling tools.
For now, I think there is at least one AC3D format plane model on
the AC3D demo distribution that will allow us to get all the
FGFS code up and running.
> Thinking about ground objects for instance (buildings, radio towers,
> etc.) Basically we'd need to be able to rotate these ssh objects so
> that they are aligned with the up vector for where ever they are being
> placed. This rotation matrix can be generated directly from the
> object's latitude and longitude.
There could be a separate SSG scene graph for each terrain tile.
Placing an ssgTransform at the top of that scene graph would allow
you to apply the same transform to all the features on the terrain
tile as to the terrain itself. The objects beneath that transform
could then be positioned on the tile using the same kinds of mechanisms
that you use to create the terrain skin.
I presume that you have some code to turn a lat/lon/alt/heading/pitch/roll
into a matrix (I guess the ownship positioning code must need that).
Using that routine to generate the location of objects on the skin
(in your offline tools) would allow you to generate a terrain feature
set from a pre-built library.
So, you'd get this:
In your source data:
There is a power plant at lat=L1, lon=L2, heading=H
In your tools you'll need to figure out the height of the terrain skin
at (L1,L2) and use that resulting Lat/Lon/Alt/Heading/0/0 to compute
(in double-precision) the transform needed to position that object
relative to the center of the earth. Subtract the origin of the terrain
tile from the translation part of that - and you have something that
you can reduce to 'float' precision.
Also offline, decide which of a standard set of pre-built "library"
models best represents a power plant.
In your output terrain tile file:
There is an instance of object number 1234 at the location
described by [4x4 matrix] relative to the terrain tile's
local origin.
There are four ways (I guess) we could do the next part:
1) We could use SSG to cull the entire scene (including
terrain skin) - discarding your existing culling routines
and creating new SSG nodes for your terrain skin.
2) We could build an SSG scene graph structure that has
an ssgTransform for each terrain tile - but have that
contain only the point features for that tile. You'd
render your terrain with the existing code and then
call SSG to cull and draw the point features.
3) We could build a separate SSG scene graph for each
terrain tile and call the cull and draw routine for
each tile only if the existing terrain tile passes
the terrain cull test.
4) Don't use SSG, just extend the existing terrain renderer
to do the point features.
It seems to me that (2) is not very efficient since the
culling process is happening twice for each terrain tile,
once in the terrain renderer and again inside SSG.
I'm not sure that SSG is mature enough to do (1) yet since
it doesn't sort by material property yet. However, that is
work that will ultimately need to be done anyway - so maybe
we just live with the inefficiency for now. If SSG had
existed before the existing terrain renderer had been
written, we should certainly have gone this way.
(3) is possible. It seems a little messy to have two sets
of culling routines layered on top of each other - and I
can concieve of a problem when a point feature object is
on the very edge of a terrain tile...hanging just off
the edge in fact...the terrain culling routines might
discard the terrain tile - and hence the SSG scene
graph would never be evaluated and the point feature
would not be drawn - even though it might be partially
on-screen. That would be a bad problem for hand-built
airfields for example.
(4) might well turn out to be easiest - but Curt would
have to write loaders for VRML and other file formats
and considerably change the existing terrain rendering
code. That would be pretty wasteful and writing good
VRML loaders would duplicate the work already being
done for SSG.
Evidently this requires more thought and discussion
between Curt and myself.
> Can ssg do these sorts of things?
In principle. SSG can be changed if needed. It's my
project and I'll do whatever it takes to make it useful.
Whether I can do that to a schedule that suits FGFS
is not certain.
Steve Baker (817)619-2657 (Vox/Vox-Mail)
Raytheon Systems Inc. (817)619-2466 (Fax)
Work: sjbaker@hti.com http://www.hti.com
Home: sjbaker1@airmail.net http://web2.airmail.net/sjbaker1
--
Please visit the FGFS web page: http://www.flightgear.org
For help on using this list (especially unsubscribing), send a message to
"fgfs-devel-request@flightgear.org" with a single line of text: "help".

View file

@ -1,153 +0,0 @@
From: Bernie Bright <bbright@c031.aone.net.au>
Sender: owner-fgfs-devel@flightgear.org
To: fgfs-devel@flightgear.org
Subject: Re: [FGFS-Devel] Another problem compiling Flightgear 0.55
Date: Mon, 02 Nov 1998 14:31:05 +1100
Arno Dabekaussen wrote:
>
> Hi Curt,
>
> Thanks for answerring my former post, but unfortunately the compilation
> blew up again.
> Here is the relevant information.
>
> With kind regards,
>
> Arno Dabekaussen
>
> Making all in Time
> make[2]: Entering directory
> `/home/arno/applications/FlightGear-0.55/Simulator/Time'
> c++ -DHAVE_CONFIG_H -I. -I../../././Simulator/Time -I../../Include
> -DHAVE_DAYLIGHT -DHAVE_TIMEZONE -I../.. -I../../Lib -I../../Simulator
> -I/usr/local/include -I/usr/X11R6/include -g -O2 -c event.cxx
> In file included from /usr/include/g++/std/bastring.h:571,
> from /usr/include/g++/std/string.h:6,
> from /usr/include/g++/string:5,
> from event.hxx:42,
> from event.cxx:48:
> /usr/include/g++/std/sinst.h:60: ambiguous template instantiation for
> `operator !=(const char *, const
> basic_string<char,string_char_traits<char> > &)' requested
[snip]
This is a known problem with the string class in g++ 2.7.x and is not
limited to FG. I've attached an unofficial patch to that fixes the
problem. Note, you'll need root access to apply the patch.
Cheers
Bernie.>From khan@xraylith.wisc.edu Wed Mar 05 02:21:24 1997
Path: news.mel.aone.net.au!news.mel.connect.com.au!munnari.OZ.AU!news.ecn.uoknor.edu!feed1.news.erols.com!newsfeeds.sol.net!uwm.edu!newsspool.doit.wisc.edu!news.doit.wisc.edu!khan
From: khan@xraylith.wisc.edu (Mumit Khan)
Newsgroups: gnu.g++.help
Subject: Re: Compiling with strings & vectors
Date: 4 Mar 1997 16:21:24 GMT
Organization: Center for X-ray Lithography, UW-Madison
Lines: 100
Message-ID: <5fhi64$lsa@news.doit.wisc.edu>
References: <5ffoh9$v2a$1@quartz.inquo.net>
NNTP-Posting-Host: modi.xraylith.wisc.edu
In article <5ffoh9$v2a$1@quartz.inquo.net>,
Travis Jensen <taj@viewpoint.com> wrote:
>I am trying to use a 'string' in a program compiled with 2.7.2.2
>and libg++ 2.7.2. If I just
>
> #include <string>
>
>and use it, I have no problems. However, if I
>
> #include <vector.h>
^^^^^^^^^^^^^^^^^^^
should be
#include <vector>
> #include <string>
>
>Is there something special I have to do to use strings and vectors
>together?
>
I've posted an unofficial patch to libstdc++ headers (no re-compilation
necessary, so it's easy!) something like 19 times so far. Here is a copy
of an old posting:
=====================================================================
If you're using GNU STL that comes with libg++-2.7.1, must apply the
following patch (no recompilation necessary):
% cd /usr/local/lib/g++-include/std
% patch -s -p0 < /tmp/libg++-2.7.1-patch
==== LIBG++ patch
*** bastring.h.org Sun Dec 3 10:51:44 1995
--- bastring.h Sun Dec 3 10:51:43 1995
***************
*** 523,529 ****
}
// Kludge this until g++ supports the new template overloading semantics.
! #if !defined(FUNCTION_H)
template <class charT, class traits>
inline bool
operator!= (const basic_string <charT, traits>& lhs,
--- 523,529 ----
}
// Kludge this until g++ supports the new template overloading semantics.
! #if !defined(FUNCTION_H) && !defined(OS_STL_FUNCTION_H)
template <class charT, class traits>
inline bool
operator!= (const basic_string <charT, traits>& lhs,
*** cinst.h.org Sun Dec 3 10:51:48 1995
--- cinst.h Sun Dec 3 10:51:47 1995
***************
*** 84,92 ****
--- 84,94 ----
__DO2(operator==,__B,__CCR,__CCR)
__DO2(operator==,__B,__CCR,__F)
__DO2(operator==,__B,__F,__CCR)
+ #if !defined(FUNCTION_H) && !defined(OS_STL_FUNCTION_H)
__DO2(operator!=,__B,__CCR,__CCR)
__DO2(operator!=,__B,__CCR,__F)
__DO2(operator!=,__B,__F,__CCR)
+ #endif
__DO1(abs,__F,__CCR)
__DO1(arg,__F,__CCR)
__DO2(polar,__C,__F,__F)
*** sinst.h.org Thu Feb 29 11:20:52 1996
--- sinst.h Thu Feb 29 11:21:22 1996
***************
*** 57,67 ****
--- 57,71 ----
// __DOPR (op, bool, wchar_t, __W)
__DOB (==)
+ #if !defined(FUNCTION_H) && !defined(OS_STL_FUNCTION_H)
__DOB (!=)
+ #endif
__DOB (<)
+ #if !defined(FUNCTION_H) && !defined(OS_STL_FUNCTION_H)
__DOB (>)
__DOB (<=)
__DOB (>=)
+ #endif
#undef __S
//#undef __W
==== END LIBG++ patch
Enjoy
Mumit -- khan@xraylith.wisc.edu
http://www.xraylith.wisc.edu/~khan/
Cc: gnu.g++.help,
Travis Jensen <taj@viewpoint.com>

View file

@ -1,251 +0,0 @@
From fatcity!root@news.cts.com Sun Apr 12 22:32:55 1998
X-VM-v5-Data: ([nil nil nil nil nil nil nil nil nil]
["2122" "Sun" "12" "April" "1998" "19:50:31" "-0800" "Steve Baker" "sbaker@link.com" nil "47" "Re: Strips vs Fans ..." "^From:" nil nil "4" nil nil nil nil nil]
nil)
Received: from mh2.cts.com (root@mh2.cts.com [205.163.24.68])
by meserv.me.umn.edu (8.8.8/8.8.8) with ESMTP id WAA20847
for <curt@me.umn.edu>; Sun, 12 Apr 1998 22:32:52 -0500 (CDT)
Received: from king.cts.com (root@king.cts.com [198.68.168.21]) by mh2.cts.com (8.8.7/8.8.5) with ESMTP id UAA22193; Sun, 12 Apr 1998 20:31:45 -0700 (PDT)
Received: from donews.cts.com (root@donews.cts.com [192.188.72.21])
by king.cts.com (8.8.7/8.8.7) with SMTP id UAA00319;
Sun, 12 Apr 1998 20:31:43 -0700 (PDT)
Received: from fatcity by donews.cts.com with uucp
(Smail3.1.29.1 #5) id m0yOZX9-00000Wa; Sun, 12 Apr 98 20:03 PDT
Received: by fatcity.com (10-Feb-1998/v1.0f-b64/bab) via UUCP id 0001C21E; Sun, 12 Apr 1998 19:50:31 -0800
Message-ID: <F001.0001C21E.19980412195031@fatcity.com>
X-Comment: OpenGL Game Developers Mailing List
X-Sender: Steve Baker <sbaker@link.com>
Reply-To: OPENGL-GAMEDEV-L@fatcity.com
Errors-To: ML-ERRORS@fatcity.com
Organization: Fat City Network Services, San Diego, California
X-ListServer: v1.0f, build 64; ListGuru (c) 1996-1998 Bruce A. Bergman
Precedence: bulk
Mime-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Content-Transfer-Encoding: 7bit
From: Steve Baker <sbaker@link.com>
Sender: root@fatcity.com
To: Multiple recipients of list OPENGL-GAMEDEV-L <OPENGL-GAMEDEV-L@fatcity.com>
Subject: Re: Strips vs Fans ...
Date: Sun, 12 Apr 1998 19:50:31 -0800
On Sat, 11 Apr 1998, Edward M Povazan wrote:
> I've been following threads here about auto strip generation, and am
> starting to wonder, why not do fans. I did a small paper test ... a regular
> triangle grid.
> case : transforms per case : percentage less than seperate triangles
> seperate triangles : 144 : 0
> fans : 77 : 53%
> strips : 56 : 39%
>
> OK so strips win here. But on a general mesh (especially one optimized for
> rt3d) the strip runs are not as long. In fact, there are cases when fans
> produce less transforms than strips (this is the case in my landscape
> engine).
The other thing that leads me to get more excited about fans than
strips is that they tend to be more compact - spatially that is -
becuase they are all sharing that one vertex.
This is useful for pre-OpenGL culling since it greatly increases the
probablility that a fan will cleanly come out wither entirely inside
or entirely outside the view frustum. If (like me) you are using a
bounding sphere test to accept or reject entire strip/fan primitives
then it's easy to visualise how fans fit better into a neat sphere
than those long wandering strips.
I'm still struggling to convert an old terrain system which was based
around IRISGL primitives (alas, no fans) - and the wins for fans
seem pretty significant.
Steve Baker (817)619-8776 (Vox/Vox-Mail)
Raytheon Systems Inc. (817)619-4028 (Fax)
Work: SBaker@link.com http://www.hti.com
Home: SJBaker1@airmail.net http://web2.airmail.net/sjbaker1
--
Author: Steve Baker
INET: sbaker@link.com
Fat City Network Services -- (619) 538-5051 FAX: (619) 538-5051
San Diego, California -- Public Internet access / Mailing Lists
--------------------------------------------------------------------
To REMOVE yourself from this mailing list, send an E-Mail message
to: ListGuru@fatcity.com (note EXACT spelling of 'ListGuru') and in
the message BODY, include a line containing: UNSUB OPENGL-GAMEDEV-L
(or the name of mailing list you want to be removed from). You may
also send the HELP command for other information (like subscribing).
From sbaker@link.com Sun Aug 16 00:55:44 1998
X-VM-v5-Data: ([nil nil nil t t nil nil nil nil]
["1920" "Sun" "16" "August" "1998" "00:52:12" "-0500" "Steve Baker" "sbaker@link.com" "<Pine.SGI.3.96.980816003848.24029A-100000@lechter.bgm.link.com>" "41" "Re: strips vs. fans" "^From:" nil nil "8" nil nil nil nil nil]
nil)
Received: from lfkw10.bgm.link.com (bgm.link.com [130.210.2.10])
by meserv.me.umn.edu (8.9.1a/8.9.1) with ESMTP id AAA14434
for <curt@me.umn.edu>; Sun, 16 Aug 1998 00:55:43 -0500 (CDT)
Received: from lechter.bgm.link.com (lechter.bgm.link.com [130.210.63.22])
by lfkw10.bgm.link.com (8.8.6/RSC-RTI-1.0) with SMTP
id AAA05219 for <curt@me.umn.edu>; Sun, 16 Aug 1998 00:55:12 -0500 (CDT)
X-Sender: steve@lechter.bgm.link.com
Reply-To: Steve Baker <sbaker@link.com>
In-Reply-To: <199808152138.QAA27557@kenai.me.umn.edu>
Message-ID: <Pine.SGI.3.96.980816003848.24029A-100000@lechter.bgm.link.com>
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
From: Steve Baker <sbaker@link.com>
To: "Curtis L. Olson" <curt@me.umn.edu>
Subject: Re: strips vs. fans
Date: Sun, 16 Aug 1998 00:52:12 -0500 (CDT)
On Sat, 15 Aug 1998, Curtis L. Olson wrote:
> At one point did you suggest that I might have comperable performance
> with fans vs. tri-strips?
Yes. We went down the path of changing our terrain tools to use
fans - the performance was essentially unchanged.
In the end, it depends on the average number of vertices per triangle.
For very long tristrips, or for very large fans, the average tends
towards 1 vertex per triangle. In this respect, there is no performance
difference between strips and fans. However, there are two reasons
to prefer strips and one reason to prefer fans:
1) Strips are allegedly implemented in hardware for Voodoo-2, and
when Mesa supports that, there could be some savings to be had
in triangle setup times. I have not heard that the same is true
for tri-fans - but it's possible.
2) Strips can potentially contain more triangles than fans because
they are not limited to having all their triangles share that
one start vertex. If you can actually make your strips longer
for practical data then strips should win. However, it's quite
hard to get an average strip strip length more than four or
five when your terrain has features like lakes, rivers, forest,
etc embedded in it.
3) Fans have one theoretical advantage - since all the triangles
share that first vertex, fans tend to be spatially compact.
This means that crude bounding sphere culling will be more
effective at reducing the number of triangles sent to OpenGL
than it might be with tri-strips.
My practical experience so far seems to suggest that these
various effects are either so tiny as to make no difference - or
somehow cancel out. However, it's work-in-progress.
Steve Baker (817)619-2657 (Vox/Vox-Mail)
Raytheon Systems Inc. (817)619-4028 (Fax)
Work: SBaker@link.com http://www.hti.com
Home: SJBaker1@airmail.net http://web2.airmail.net/sjbaker1
From sbaker@link.com Tue Aug 18 08:57:29 1998
X-VM-v5-Data: ([nil nil nil nil nil nil nil nil nil]
["4108" "Tue" "18" "August" "1998" "08:56:05" "-0500" "Steve Baker" "sbaker@link.com" nil "87" "Re: strips vs. fans" "^From:" nil nil "8" nil nil nil nil nil]
nil)
Received: from lfkw10.bgm.link.com (bgm.link.com [130.210.2.10])
by meserv.me.umn.edu (8.9.1a/8.9.1) with ESMTP id IAA10259
for <curt@me.umn.edu>; Tue, 18 Aug 1998 08:57:27 -0500 (CDT)
Received: from samantha.bgm.link.com (samantha.bgm.link.com [130.210.65.19])
by lfkw10.bgm.link.com (8.8.6/RSC-RTI-1.0) with SMTP
id IAA11753 for <curt@me.umn.edu>; Tue, 18 Aug 1998 08:56:48 -0500 (CDT)
X-Sender: steve@samantha.bgm.link.com
Reply-To: Steve Baker <sbaker@link.com>
In-Reply-To: <199808172109.QAA25296@kenai.me.umn.edu>
Message-ID: <Pine.SGI.3.96.980818074747.24918A-100000@samantha.bgm.link.com>
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
From: Steve Baker <sbaker@link.com>
To: "Curtis L. Olson" <curt@me.umn.edu>
Subject: Re: strips vs. fans
Date: Tue, 18 Aug 1998 08:56:05 -0500 (CDT)
On Mon, 17 Aug 1998, Curtis L. Olson wrote:
> So do just use a "greedy" algorithm to build fans, or do you do
> something more sophisticated?
Well, we have to consider the larger issues.
* From the point of view of OpenGL, the more triangles in the strip/fan
the better.
* From the point of view of FOV culling, the more compact the strip/fan
the better.
* From the point of view of intersection testing, the shorter the strip/fan
the better.
We use a variety of stripping algorithms depending on the cicumstance.
Sometimes we just do the 'greedy' algorithm, sometimes we impose a limit
on the maximum strip length which tends to cut down on the number of
single triangles (which are especially costly on SGI hardware for some
reason). Sometimes we use an algorithm that has an estimate of the
relative costs of transforming strips of length 1, 2, 3, 4, ... which
tries many different ways to strip/fan until it finds one with a cost
per-triangle that is less than some user-specified limit - and the
ultimate algorithm simply does a totally exhaustive search for the cheapest
overall set of strips.
The last few algorithms can take days to run on even relatively simple
objects - and we use those only for the simplest of objects when that object
is re-used a gazillion times in the database. For example, we did a
model of Yellowstone national park where the customer needed the highest
possible density of single, individual trees. We built a set of tree
cluster models and ran the tri-stripper at maximum optimisation on them
all to get down the cost of transforming all those thousands of trees to
the absolute minimum.
However, when we have the whole of North America to tstrip, we can't
afford the CPU hours to do anything much more than the very basic
limited-length-greedy algorithm.
Limiting the maximum strip length helps the FOV culling so much that
we pretty much always limit the length to a dozen of so triangles.
That's principally due to SGI hardware which gains performance as the
strip length increases - up to about 10 triangles - beyond which it
doesn't really help any.
It's MUCH better (on SGI ONYX hardware) to generate two strips of 5
triangles each than it is to generate one strip of 9 and one single
triangle.
For us, there are yet other considerations. We don't currently drive
OpenGL directly - we use the Performer scene graph API as a layer on
top. Performer can optimise the case where all the triangles in the
strip share the same surface normal and/or colour. In that case, it
generates just one glNormal and glColor command for each strip. These
are called 'Flat-Tri-strips'. For man-made objects, we can often win
by having shorter strips that are flat rather than longer strips that
are non-flat because the cost of transforming the normals is not
negligable.
Some of the SGI machines also optimise for the case when there is only
a single, infinite light source by only doing illumination per-normal
rather than per-vertex - this also makes flat strips worth having.
Some of these optimisations are actually pessimisations on some machines,
so you have to optimise the database for the hardware.
As you can see, this is another incredibly complicated issue if you
want to get absolutely *ALL* the performance you can.
It's unreasonable to expect FGFS to do this with the limited effort
available. We have two or three full-time staff thinking about
database tools - and we have been working with OpenGL for five
years now.
> > 1) Strips are allegedly implemented in hardware for Voodoo-2, and
> > when Mesa supports that, there could be some savings to be had in
> > triangle setup times. I have not heard that the same is true for
> > tri-fans - but it's possible.
>
> I would think that if they did strips, they could easily do fans ...
I just asked the question on the 3Dfx newsgroup - we'll get a definitive
answer there.
Steve Baker (817)619-2657 (Vox/Vox-Mail)
Raytheon Systems Inc. (817)619-4028 (Fax)
Work: SBaker@link.com http://www.hti.com
Home: SJBaker1@airmail.net http://web2.airmail.net/sjbaker1

View file

@ -1,8 +0,0 @@
"Christian Mayer" <Vader@t-online.de>
http://home.t-online.de/home/vader/internet.zip
http://home.t-online.de/home/vader/myones.zip
http://home.t-online.de/home/vader/nz_tex.zip
Note: some of these textures may have specific copyrights and restrictions
on their use. Please view and follow the documentation/readme that comes
with these.

File diff suppressed because it is too large Load diff

View file

@ -1,72 +0,0 @@
From sbaker@link.com Tue May 26 07:55:03 1998
X-VM-v5-Data: ([nil nil nil nil nil nil nil nil nil]
["1540" "Tue" "26" "May" "1998" "07:54:04" "-0500" "Steve Baker" "sbaker@link.com" nil "40" "Re: Question" "^From:" nil nil "5" nil nil nil nil nil]
nil)
X-VM-Last-Modified: (13793 54640 649954)
X-VM-IMAP-Retrieved: nil
X-VM-POP-Retrieved: nil
X-VM-Message-Order:
(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
16 17 18 19 20 21 22 23 24 25 26)
X-VM-Summary-Format: "%n %*%a %-17.17F %-3.3m %2d %4l/%-5c %I\"%s\"\n"
X-VM-Labels: ("r")
X-VM-VHeader: ("Resent-" "From:" "Sender:" "To:" "Apparently-To:" "Cc:" "Subject:" "Date:") nil
X-VM-Bookmark: 20
Received: from lfkw10.bgm.link.com (bgm.link.com [130.210.2.10])
by meserv.me.umn.edu (8.8.8/8.8.8) with ESMTP id HAA28563
for <curt@me.umn.edu>; Tue, 26 May 1998 07:55:02 -0500 (CDT)
Received: from borgus.bgm.link.com (borgus.bgm.link.com [130.210.236.13])
by lfkw10.bgm.link.com (8.8.6/HTI-Hack-8.8.4) with SMTP
id HAA00068 for <curt@me.umn.edu>; Tue, 26 May 1998 07:54:55 -0500 (CDT)
X-Sender: steve@borgus.bgm.link.com
Reply-To: Steve Baker <sbaker@link.com>
In-Reply-To: <199805230429.XAA10965@kenai.me.umn.edu>
Message-ID: <Pine.SGI.3.96.980526074643.2282C-100000@borgus.bgm.link.com>
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
From: Steve Baker <sbaker@link.com>
To: "Curtis L. Olson" <curt@me.umn.edu>
Subject: Re: Question
Date: Tue, 26 May 1998 07:54:04 -0500 (CDT)
On Fri, 22 May 1998, Curtis L. Olson wrote:
> I'm running into floating point problems again where my scenery tiles
> sometimes have a pixel gap between them. I was wondering if you had
> any ideas ...
It's a problem that plagues us too.
I can't say that I have a magic solution.
One thing I have *considered* is to do everything in integers (for
the terrain skin at least).
This sounds counter-intuitive - but the source data for your
terrain is certainly not accurate to better than a meter - and
integers have the huge advantage that they don't suffer from
roundoff error providing all you do is add and subtract them.
However, I havn't had the nerve to try this yet - right now, we
kludge the edges of each terrain tile to make it a teeny-tiny bit
too big. The resulting overlap is very small - but enough to get
rid of the cracks.
> Anyways, what this forces me to do is for each tile I must
> glTranslate() by center_of_tile_to_be_drawn - center_of_tile_I'm_in.
> But, up until this point everything was done in double's so I was
> hoping the final translate about which is on the order of 20,000 -
> 30,000 meters would be ok.
But that translate could be done in integer meters.
> Anyways, I just thought I'd see if you had any brilliant thoughts on
> the subject.
Nope - it's a continual problem for me too.
Steve Baker (817)619-8776 (Vox/Vox-Mail)
Raytheon Systems Inc. (817)619-4028 (Fax)
Work: SBaker@link.com http://www.hti.com
Home: SJBaker1@airmail.net http://web2.airmail.net/sjbaker1

View file

@ -1,67 +0,0 @@
>-----Original Message-----
>From: Antoine Leca [mailto:Antoine.Leca@renault.fr]
>Sent: Thursday, April 01, 1999 4:51 AM
>To: Lee Geoff
>Cc: tz@elsie.nci.nih.gov
>Subject: Re: storing timestamp data
>
>
>Lee Geoff wrote:
>>
>> I'm interested in storing date/time data in Ingres
>> databases which are running on Unix servers. We are
>recording timed events
>> on Unix servers as well as Windows 3.1 and NT PCs. I have
>had problems with
>> the apparent miss-handling of data when viewed before or after a DST
>> transition.
>
>We had this kind of problems when setting up a Internet
>standard for exchanging
>calendars, agendas and schedules (it ends up in RFC2245, if you mind).
>
>The net result was: either use UTC, or local time + offset from UTC.
>Do not use local time without UTC offset, as no reliable method can be
>set up to correctly retrieve the exact point of time
>afterwards (as you may
>have experienced).
>
>Using UTC times is native on Unix and NT (AFAIK), so this is
>the basic choice
>there. The problem comes with Windows non-NT PCs, since they
>run local clocks.
>IMHO, and to be consistent with the above, no data that are
>not tagged with
>the (best approximation of) UTC offset should leave the PC.
>
>Traditional way of finding the best approximation are (in order):
> - search for an (up to date) Olson's package to interpret the
>information,
> perhaps by searching $(DJDIR)/zoneinfo/localtime in addition to
> $(TZDIR)/localtime
> - if running on Windows 95/98, search the information in the registry
> - setting a mechanism dedicated to it (but it will end with one more
> mechanism, which tends to upset users)
> - ask the TZ environment variable
> - search the information on related softwares that may be
>present on the PCs
> (examples are mailing systems, e.g. Notes, and IP
>connectivity packages)
>
>Do not use:
> - tzset and timezone, as it defaults to PST8PDT or EST5EDT on
>most compilers,
> without being reliably accurate on most workstations by lack of TZ
> - if your users are not Americans, do not rely on US-based
>rules; they are
> almost correct for Europeans (except that for example, this
>week, my UTC
> offset is wrong because my mail software is brocken on this
>respect...)
>
>
>Hope it helps,
>
>Antoine
>
>

View file

@ -1,986 +0,0 @@
From sbaker@link.com Thu Jan 29 23:16:07 1998
X-VM-v5-Data: ([nil nil nil nil t nil nil nil nil]
["5377" "Thu" "29" "January" "1998" "23:16:36" "-0600" "Steve Baker" "sbaker@link.com" "<Pine.SGI.3.96.980129224404.29062A-100000@lechter.bgm.link.com>" "139" "Re: View frustum culling" "^From:" nil nil "1" nil nil nil nil nil]
nil)
Received: from lfkw10.bgm.link.com (bgm.link.com [130.210.2.10])
by meserv.me.umn.edu (8.8.8/8.8.6) with ESMTP id XAA03024
for <curt@me.umn.edu>; Thu, 29 Jan 1998 23:16:06 -0600 (CST)
Received: from lechter.bgm.link.com (lechter.bgm.link.com [130.210.239.45])
by lfkw10.bgm.link.com (8.8.6/HTI-Hack-8.8.4) with SMTP
id XAA18220 for <curt@me.umn.edu>; Thu, 29 Jan 1998 23:15:35 -0600 (CST)
X-Sender: steve@lechter.bgm.link.com
Reply-To: Steve Baker <sbaker@link.com>
In-Reply-To: <199801292145.PAA04212@kenai.me.umn.edu>
Message-ID: <Pine.SGI.3.96.980129224404.29062A-100000@lechter.bgm.link.com>
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
From: Steve Baker <sbaker@link.com>
To: "Curtis L. Olson" <curt@me.umn.edu>
Subject: Re: View frustum culling
Date: Thu, 29 Jan 1998 23:16:36 -0600 (CST)
On Thu, 29 Jan 1998, Curtis L. Olson wrote:
> Questions ...
>
> Let's say I know the following:
>
> Eye pt. = (0, 0, 0)
> "look at" vector
> "view up" vector
> field of view angle
> Assume a "square" view volume cross section (i.e. the far clip plane
> would be a square)
(That is almost never the case since you want the image to fit the
screen shape - but OK - for argument's sake, same HFOV as VFOV).
> I can calcuation the near and far clip planes pretty easily with this
> info.
Assuming you know the near and far clip ranges - yes.
> Now, to calculate the left and right planes I could rotate the look at
> vector about the view up vector by -1/2 * fov and +1/2 * fov
> respectively. The view up vector already lies in both these planes,
> so then I'd have two vectors in each plane and then I could calculate
> the normals to get the equations of these planes
Yes, that would work.
> Then to calculate the top and bottom planes I could rotate the view up
> vector by 90 degrees about the look at vector to get a vector in both
> these planes, then I could rotate the look at vector about this new
> vector by -1/2 * fov and +1/2 * fov to get the second vector in each
> of these planes, and crunch the math just like I did for the left and
> right planes.
...or you could just rotate the left or right plane normal by 90 degrees
about the lookat vector (but only for your hypothetical square FOV).
> Does this sound reasonable, or am I missing some obvious tricks?
It's *reasonable* if you want the view planes in the coordinate system
of the world. However, I'd argue about that premise.
I did the opposite - I keep the view frustum in the coordinate system
of the eye and rotate the world into that coordinate system. This
costs at most one extra transform (by the inverse of the eye-rel-world
matrix) per frame (at the root of the database tree).
The advantages are *huge* in the clipping code (which is where I
assume you are going with this question) since the plane equations
for the near and far planes (in eye coordinates) are trivial:
General Equation of a Plane:
Ax + By + Cz + D == 0
Far clip plane:
A == 0 ;
B == 0 ;
C == -1 ;
D == far_clip_range ;
Near clip plane:
A == 0 ;
B == 0 ;
C == 1 ;
D == -near_clip_range ;
Also, since the left and right clip planes are now vertical, we
know that B==0 and for the top and bottom planes, A==0.
In addition, because of symmetry about the Z axis, the A of
the left plane is equal to -A for the right, and the B of
the top plane is equal to -B of the bottom.
Furthermore, since D is just the distance of the closest
point of the plane to the origin - and all four planes
go through the eyepoint - and that *is* the origin - that
means that the 'D' component of all four edge equations is
always zero.
Notice that since the frustum is in eye coordinates,
there is no need to worry about lookat or viewup vectors
since these are 0,0,1 and 0,1,0 respectively - and the
eye point is always at 0,0,0 by definition. This also
means that you only need to calculate those plane equations
once - rather than once per frame as with your scheme.
When you come to ask the question: "Is this bounding sphere
cleanly inside the frustum, cleanly outside the frustum or
(annoyingly) straddling it?", you will want to insert the
x,y,z of the center of the sphere (relative to the eye
in the 'eye' coordinate system) into each of the
six plane equations in turn to compute the distance from the
sphere center to the plane - and compare that to the radius
of the sphere. When you write out the math for this, using
the full plane equations (as you would have to do with your
scheme), you find that all those zeros and symmetry effects
result in some pretty amazing optimisations.
Additionally, this is the OpenGL way. You stuff your frustum
matrix into the 'PROJECTION_MATRIX', put the inverse of
your eyepoint transform into the MODELVIEW_MATRIX and proceed
to push/multiply/pop the transforms of each of the models onto
that same matrix. Notice that the frustum is never transformed
into world space.
I suggest you go back and re-read the last L-O-N-G email I
sent about clipping, I explain my suggested method there
in more detail.
Note that I'm not saying that what you propose is wrong -
just that IMHO (and *only* IMHO), my way is going to be
a lot simpler and cheaper to implement. However, there may
be other reasons to want to do it your way.
The complexity of MANY 3D graphics problems often depends
critically on your choice of coordinate system. For
clipping, doing the math in the eye coordinate system
results in a *tiny* amount of math per sphere tested.
If you ever need to do lighting calculations, then
carrying them out in a coordinate system with the
light source at the origin makes life a gazillion
times easier too. The same kinds of things will also
crop up in collision detection as well.
Steve Baker 817-619-8776 (Vox/Vox-Mail)
Raytheon Systems Inc. 817-619-4028 (Fax)
2200 Arlington Downs Road SBaker@link.com (eMail)
Arlington, Texas. TX 76005-6171 SJBaker1@airmail.net (Personal eMail)
http://www.hti.com http://web2.airmail.net/sjbaker1 (personal)
** Beware of Geeks bearing GIF's. **
From sbaker@link.com Fri Jan 30 14:08:05 1998
X-VM-v5-Data: ([nil nil nil nil t nil nil nil nil]
["4594" "Fri" "30" "January" "1998" "14:08:27" "-0600" "Steve Baker" "sbaker@link.com" "<Pine.SGI.3.96.980130135437.20130B-100000@lechter.bgm.link.com>" "120" "Re: View frustum culling" "^From:" nil nil "1" nil nil nil nil nil]
nil)
Received: from lfkw10.bgm.link.com (bgm.link.com [130.210.2.10])
by meserv.me.umn.edu (8.8.8/8.8.6) with ESMTP id OAA21393
for <curt@me.umn.edu>; Fri, 30 Jan 1998 14:08:03 -0600 (CST)
Received: from lechter.bgm.link.com (lechter.bgm.link.com [130.210.239.45])
by lfkw10.bgm.link.com (8.8.6/HTI-Hack-8.8.4) with SMTP
id OAA10811 for <curt@me.umn.edu>; Fri, 30 Jan 1998 14:07:27 -0600 (CST)
X-Sender: steve@lechter.bgm.link.com
Reply-To: Steve Baker <sbaker@link.com>
In-Reply-To: <199801301948.NAA25718@kenai.me.umn.edu>
Message-ID: <Pine.SGI.3.96.980130135437.20130B-100000@lechter.bgm.link.com>
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
From: Steve Baker <sbaker@link.com>
To: "Curtis L. Olson" <curt@me.umn.edu>
Subject: Re: View frustum culling
Date: Fri, 30 Jan 1998 14:08:27 -0600 (CST)
On Fri, 30 Jan 1998, Curtis L. Olson wrote:
> Steve Baker writes:
> > I did the opposite - I keep the view frustum in the coordinate
> > system of the eye and rotate the world into that coordinate
> > system. This costs at most one extra transform (by the inverse of
> > the eye-rel-world matrix) per frame (at the root of the database
> > tree).
> >
> > I suggest you go back and re-read the last L-O-N-G email I sent
> > about clipping, I explain my suggested method there in more detail.
>
> Yes I have that in front of me. I guess it wasn't clear to me that
> you were using this greatly simplifed view frustum specially placed in
> eye coordinates.
That's the key to doing this stuff *quickly*.
> > The complexity of MANY 3D graphics problems often depends critically
> > on your choice of coordinate system. For clipping, doing the math in
> > the eye coordinate system results in a *tiny* amount of math per
> > sphere tested.
>
> Yes ... your description all makes sense and looks like it makes view
> frustum culling very simple to implement.
>
> Ok, so now I'm going to try to zero in a bit more on the source of my
> confusion, which involves getting from my world to your eye
> coordinates.
Let's adopt a naming convention for matrices here:
A_rel_B
means the matrix that positions objects in A relative to
the object B.
Some facts:
B_rel_A is just the inverse of A_rel_B.
A_rel_B * B_rel_C == A_rel_C
Hence: (for a flat-earth world - just for the moment)
If the eyepoint is 10km east of the origin (eyepoint.x == 10,000)
then:
eye_rel_world is a matrix that translates by 10000m in the X
direction.
world_rel_eye is the inverse of eye_rel_world - which in this
case is just a matrix that translates by -10000m in X.
Taking the inverse of a general matrix isn't nice - but for simple
rotate/translate matrices it isn't too bad - and you only do it
once per frame anyway.
> Lets say that I have a bunch of scenery tiles that are properly
> oriented, but translated to near (0, 0, 0) to avoid problems with
> "float" precision.
>
> I assume based on your previous message that you define your view
> frustum once at the beginning of your program in eye coordinates to
> simplify all this math.
Yep - you *might* want to allow the user to change it sometimes - but
basically, it's always the same number unless you resize the window,
zoom the image, etc.
> This moves the "hard" part to generating a transformation matrix that
> maps world coordinates into eye coordinates.
But world_rel_eye is just the inverse of eye_rel_world - and that's
just the rotation/translation of the eyepoint relative to some
arbitary point.
> You say ...
>
> > Additionally, this is the OpenGL way. You stuff your frustum matrix
> > into the 'PROJECTION_MATRIX', put the inverse of your eyepoint
> > transform into the MODELVIEW_MATRIX and proceed to push/multiply/pop
> > the transforms of each of the models onto that same matrix. Notice
> > that the frustum is never transformed into world space.
>
> Ok, so does this mean that every iteration I have to generate the
> world -> eye transformation matrix by hand ... i.e. calculate the
> first translation matrix, calculate the rotation matrix, calculate the
> second translation matrix, calculate the shear matrix, calculate the
> scaling matrix, and then combine all these together, then invert it
> and stuff it on the MODELVIEW stack?
Yes - except that the eye_rel_world isn't usually scaled or sheared or
anything. Just heading/pitch/roll/x/y/z.
> Or is there a way to get OpenGL to do this work for me?
No - not really - there is no glInvertMatrix (AFAIK) - and in any
case, on machines with geometry accelleration doing a glGetMatrix
is *death* to performance.
> If not, can I at least use OpenGL's rotates,
> and transformations to avoid spending two weeks debugging picky math
> routines?
No - don't debug new math routines either - let me find some out on the
web for you. I'm sure I know of a good set. I'll email you from home
tonight - I'm a bit busy right now.
Flight Gear will definitely need a good, robust set of math routines -
better to have a solid library than to try to kludge something in OpenGL.
Steve Baker 817-619-8776 (Vox/Vox-Mail)
Raytheon Systems Inc. 817-619-4028 (Fax)
2200 Arlington Downs Road SBaker@link.com (eMail)
Arlington, Texas. TX 76005-6171 SJBaker1@airmail.net (Personal eMail)
http://www.hti.com http://web2.airmail.net/sjbaker1 (personal)
** Beware of Geeks bearing GIF's. **
From sbaker@link.com Fri Jan 30 22:51:59 1998
X-VM-v5-Data: ([nil nil nil nil nil nil nil nil nil]
["4301" "Fri" "30" "January" "1998" "22:52:31" "-0600" "Steve Baker" "sbaker@link.com" nil "103" "Re: View frustum culling" "^From:" nil nil "1" nil nil nil nil nil]
nil)
Received: from lfkw10.bgm.link.com (bgm.link.com [130.210.2.10])
by meserv.me.umn.edu (8.8.8/8.8.6) with ESMTP id WAA03743
for <curt@me.umn.edu>; Fri, 30 Jan 1998 22:51:58 -0600 (CST)
Received: from lechter.bgm.link.com (lechter.bgm.link.com [130.210.239.45])
by lfkw10.bgm.link.com (8.8.6/HTI-Hack-8.8.4) with SMTP
id WAA08997 for <curt@me.umn.edu>; Fri, 30 Jan 1998 22:51:26 -0600 (CST)
X-Sender: steve@lechter.bgm.link.com
Reply-To: Steve Baker <sbaker@link.com>
In-Reply-To: <199801302035.OAA26234@kenai.me.umn.edu>
Message-ID: <Pine.SGI.3.96.980130223546.27307A-100000@lechter.bgm.link.com>
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
From: Steve Baker <sbaker@link.com>
To: "Curtis L. Olson" <curt@me.umn.edu>
Subject: Re: View frustum culling
Date: Fri, 30 Jan 1998 22:52:31 -0600 (CST)
On Fri, 30 Jan 1998, Curtis L. Olson wrote:
> Steve Baker writes:
> > But world_rel_eye is just the inverse of eye_rel_world - and that's
> > just the rotation/translation of the eyepoint relative to some
> > arbitary point.
>
> Ok, from what you are saying, if I think about it, I've probably
> already got a suitable matrix or something close to it laying around
> someplace. I have a matrix that does the proper rotations to align
> world coordinates with the local "up" for the aircraft. I'd probably
> just need to pre-multiply the proper translation matrix with that
> rotate matrix, then invert it, and stuff it onto the MODELVIEW stack.
You *must* be doing the right thing at the start of the frame - or
how else would the graphics be coming out right? (Oh - unless you
are using that weird OpenGL 'lookat' function or something).
> > No - don't debug new math routines either - let me find some out on
> > the web for you. I'm sure I know of a good set. I'll email you from
> > home tonight - I'm a bit busy right now.
> >
> > Flight Gear will definitely need a good, robust set of math routines
> > - better to have a solid library than to try to kludge something in
> > OpenGL.
>
> You may scream when you hear this, or not, I'm not sure ... but I've
> been using the matrix and vector routines from SRGP and SPHIGS.
I don't know these - but it's hard to imagine how anyone could screw
up the implementation of a matrix math library - so they are probably OK.
I have accumulated by own matrix/quaternion library that I've used
for the last 10 years - every new project starts with it - and adds to
it, so now I don't even have to think about how to drive it. That's
a very liberating thing.
Another good source for a matrix lib is inside the Mesa sources. These
are particularly interesting because the latest Beta release has
super-optimised machine code for Intel CPU's under Linux as a conditional
compiled option. You'd need to copy and change the names of the routines
though to avoid the names clashing with the real Mesa routines.
One *IMPORTANT* thing is that when you invert the eye_rel_world matrix
to get world_rel_eye, don't use a general purpose matrix invert routine
since those are *REALLY* inefficient bits of code for matrices that
are guaranteed to be pure rotate/translate. Instead, just do this:
/*
This definition of a matrix is
easier to deal with than a float[16] -
but you can safely pass this kind
of matrix directly to OpenGL routines
like glMultMatrix and glLoadMatrix.
*/
typedef float fgMat [ 4 ][ 4 ] ;
/*
Transpose/Negate is a poor man's invert.
It can *only* be used when matrix is a
simple rotate-translate - but it's a
gazillion times faster than a full-blown
invert.
*/
void fgTransposeNegateMat( fgMat dst, fgMat src )
{
/* Transpose the 3x3 rotation sub-matrix */
dst[0][0] = src[0][0] ; dst[0][1] = src[1][0] ; dst[0][2] = src[2][0] ;
dst[1][0] = src[0][1] ; dst[1][1] = src[1][1] ; dst[1][2] = src[2][1] ;
dst[2][0] = src[0][2] ; dst[2][1] = src[1][2] ; dst[2][2] = src[2][2] ;
/* Negate the translate part */
dst[3][0] = -src[3][0] ; dst[3][1] = -src[3][1] ; dst[3][2] = -src[3][2] ;
/* Populate the rest */
dst[0][3] = dst[1][3] = dst[2][3] = 0.0f ; dst[3][3] = 1.0f ;
}
> Debugging the low level routines, though, is sometimes the easy part,
> debugging the usage of them is where it can often get hairy ... :-)
I agree - matrices are truly horrible to get your head around. Have
you looked into Quaternions yet? They are v.interesting for the
flight dynamics people because they don't suffer from 'gymbal lock'
like H,P,R angles and are easier to renormalize than matrices.
You don't want to use Quaternions for the main graphics code - but
it's easy to form a Matrix from a Quaternion - and Quaternions are
a much better way to represent rotation than the usual three angles.
Steve Baker 817-619-8776 (Vox/Vox-Mail)
Raytheon Systems Inc. 817-619-4028 (Fax)
2200 Arlington Downs Road SBaker@link.com (eMail)
Arlington, Texas. TX 76005-6171 SJBaker1@airmail.net (Personal eMail)
http://www.hti.com http://web2.airmail.net/sjbaker1 (personal)
** Beware of Geeks bearing GIF's. **
From owner-flight-gear@me.umn.edu Tue May 19 07:45:59 1998
X-VM-v5-Data: ([nil nil nil nil nil nil nil nil nil]
["4413" "Tue" "19" "May" "1998" "07:44:47" "-0500" "Steve Baker" "sbaker@link.com" nil "116" "Re: [FGFS] View Frustum Culling" "^From:" nil nil "5" nil nil nil nil nil]
nil)
Received: (from majordom@localhost)
by meserv.me.umn.edu (8.8.8/8.8.8) id HAA04944
for flight-gear-outgoing; Tue, 19 May 1998 07:45:59 -0500 (CDT)
X-Authentication-Warning: meserv.me.umn.edu: majordom set sender to owner-flight-gear@me.umn.edu using -f
Received: from lfkw10.bgm.link.com (bgm.link.com [130.210.2.10])
by meserv.me.umn.edu (8.8.8/8.8.8) with ESMTP id HAA04940
for <flight-gear@me.umn.edu>; Tue, 19 May 1998 07:45:55 -0500 (CDT)
Received: from borgus.bgm.link.com (borgus.bgm.link.com [130.210.236.13])
by lfkw10.bgm.link.com (8.8.6/HTI-Hack-8.8.4) with SMTP
id HAA29586 for <flight-gear@me.umn.edu>; Tue, 19 May 1998 07:45:23 -0500 (CDT)
X-Sender: steve@borgus.bgm.link.com
In-Reply-To: <199805182119.QAA04388@kenai.me.umn.edu>
Message-ID: <Pine.SGI.3.96.980519070916.5720B-100000@borgus.bgm.link.com>
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Precedence: bulk
Reply-To: flight-gear@me.umn.edu
From: Steve Baker <sbaker@link.com>
Sender: owner-flight-gear@me.umn.edu
To: flight-gear@me.umn.edu
Subject: Re: [FGFS] View Frustum Culling
Date: Tue, 19 May 1998 07:44:47 -0500 (CDT)
On Mon, 18 May 1998, Curtis L. Olson wrote:
> Steve Baker writes:
> > Are you only planning to cull at the tile level? You probably ought
> > to cull at the triangle strip level (at least on machines without
> > geometry hardware).
>
> You are always trying to make things more complicated ... :-)
It's my experience that things are perfectly capable of getting
more complicated without any help from me :-)
> > You can check a bounding sphere against the view frustum in about 4
> > multiplies and four additions - and you only need to do that for
> > spheres inside tiles that straddle the frustum. Each test that
> > excludes a tstrip will save a bunch of vertex transforms - so you
> > should get another big win in doing that.
>
> Ok, a couple of questions. Do you recommend pre-calculating and
> storing the bounding sphere info for each tri-strip in the data file,
> or should I calculate it at load time?
Well, since you only have one CPU to use for both rendering and
realtime database paging, you'll want to minimise the amount of
calculations when loading. The bounding sphere calculation
that most people do is very simple - you probably would want to do it
offline eventually - but you can probably do it on loading the database
for now just so you can get the culling stuff finished. So long as you
don't do it every frame you'll be OK in the short term.
The basic bounding sphere algorithm that most people (including me)
use is v.simple. Just find the maximum and minimum x, y and z values
in the data set, position the center of the sphere halfway between
the minimum and maximum in each axis - then go through the points
to find the one thats furthest from that center point - that distance
is the radius. (You can compare the square of the ranges to get the
longest range - so you only need to do one sqrt per sphere when you
need to compute the actual radius).
There has been some discussion of 'better' algorithms that (presumable)
produce tighter spheres than the simple method described above. On
my 'to do' list here at work is to evaluate these various algorithms to
see which actually produces the tightest spheres.
tighter spheres == better culling == lower polygon counts.
I'm pretty sceptical about these algorithms being *significantly*
better than the simple one - but even a few percent improvement
is worth having if I can do it offline and steal the code from
someone who can do 'math'.
This one looks interesting:
http://vision.ucsd.edu/~dwhite/ball.html
...although being iterative, I wouldn't want to do it in my
database loader code.
Same applies to this one:
http://cm.bell-labs.com/who/clarkson/center.html
Both have source code - which is just as well since I can't understand
the math behind either of them!
If your culling math starts to take too much time then you'll want to
do a hierarchical cull. If I were you though I'd probably just
do this:
for each terrain tile
{
if ( outside the frustum )
continue ;
if ( inside the frustum )
draw all the tristrips
else /* straddling the frustum */
{
for each tristrip
if ( inside or straddling the frustum )
draw the tristrip
}
}
(Of course 'draw the tristrip' might actually mean 'add the tristrip to
the appropriate bucket so we can draw it later')
> To impliment this sort of
> scheme I suppose I would need to keep each tri-strip in it's own
> display list.
Yep - but you need to do that so that you can....
> ...sort the objects into buckets by material properties.
Definitely. Switching material properties (especially texture map)
is very costly on most hardware OpenGL's. Sorting is an absolute
must once you start you use more than one kind of texture on the
terrain skin.
> I suppose this would entail defining material properties in the data
> file and otherwise sprucing up the data file format (and internal data
> structures) a bit.
Eventually.
Steve Baker (817)619-8776 (Vox/Vox-Mail)
Raytheon Systems Inc. (817)619-4028 (Fax)
Work: SBaker@link.com http://www.hti.com
Home: SJBaker1@airmail.net http://web2.airmail.net/sjbaker1
-------------------------------------
Please visit the FGFS web page: http://www.menet.umn.edu/~curt/fgfs/
For help on using this list (especially unsubscribing), send a message to
"flight-gear-request@me.umn.edu" with a single line of text: "help".
From sbaker@link.com Mon May 18 07:39:58 1998
X-VM-v5-Data: ([nil nil nil nil nil nil nil nil nil]
["10518" "Mon" "18" "May" "1998" "07:39:06" "-0500" "Steve Baker" "sbaker@link.com" nil "295" "Re: view frustum culling" "^From:" nil nil "5" nil nil nil nil nil]
nil)
Received: from lfkw10.bgm.link.com (bgm.link.com [130.210.2.10])
by meserv.me.umn.edu (8.8.8/8.8.8) with ESMTP id HAA01318
for <curt@me.umn.edu>; Mon, 18 May 1998 07:39:57 -0500 (CDT)
Received: from sutcliffe.bgm.link.com (sutcliffe.bgm.link.com [130.210.236.18])
by lfkw10.bgm.link.com (8.8.6/HTI-Hack-8.8.4) with SMTP
id HAA03232 for <curt@me.umn.edu>; Mon, 18 May 1998 07:39:26 -0500 (CDT)
X-Sender: steve@sutcliffe.bgm.link.com
Reply-To: Steve Baker <sbaker@link.com>
In-Reply-To: <199805152113.QAA12303@kenai.me.umn.edu>
Message-ID: <Pine.SGI.3.96.980518071249.21179A-100000@sutcliffe.bgm.link.com>
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
From: Steve Baker <sbaker@link.com>
To: "Curtis L. Olson" <curt@me.umn.edu>
Subject: Re: view frustum culling
Date: Mon, 18 May 1998 07:39:06 -0500 (CDT)
On Fri, 15 May 1998, Curtis L. Olson wrote:
> I was just planning to work out the math myself, but it's not coming
> out nearly as simple as what you had. The near/far clipping plane is
> trivial, but I was working through the sides and started to see a few
> sqrt()'s and such start to creep in, and I don't remember seeing this
> with your pseudo-code.
Certainly shouldn't need sqrt's.
How about this:
You said:
> Anyone know anything about view frustum culling?
Yep.
Two issues:
1) Scene hierarchy generation (offline).
2) Runtime culling.
Hierarchy:
==========
There are lots of ways to do this. I usually build an heirerchical description
of each terrain tile. I typically build a tree structure that's organized
as follows:
| The World.
|
___________________|___
| | | | | | |
* * * * * * * Terrain tiles currently loaded
| | | | | | |
|
|
_____|_____
| | | |
* * * * Quarter-tiles
| | | |
|
|
_____|_____
| | | |
* * * * Sixteenth-tiles
| | | |
...and so on down until the number of polygons in each 'object' gets 'small enough'.
When you do this, don't try to split polygons when they cross a quarter or a
sixteenth tile boundary - just dump each polygon into the nearest 'bucket' to
it's centroid.
Do your tri-stripping on the leaf nodes of this tree - so that each tristrip
is contained entirely within one bucket.
Eventually, you will need to include buildings, roads, rivers, etc. Since these
need to be culled by level of detail, it is often useful to put them into a separate
tree structure that parallels the terrain 'skin' structure.
Finally, compute a bounding sphere around each leaf node, find the best fit
sphere by finding the maximum and minimim x, y and z of the tristrips in that
leaf node, taking the mid-point and then finding the vertex that is furthest
from that center point and using it as the radius.
Compute the bounding sphere for each level in the tree (everywhere where there is
a '*' in my diagram).
Runtime:
========
At runtime, you walk that tree every frame, testing the bounding sphere against
the view frustum.
* If the sphere lies entirely outside the view frustum then stop traversal
for that node. There is no need to test any of the nodes beneath this one
(we know that none of their leaf tristrips are visible).
* If the sphere lies entirely inside the view frustum then traverse immediately
to all of the leaves below this node without doing any more sphere testing
on them - draw all of the tristrips that are there. (We know they are all visible)
* If the sphere straddles the view frustum then check each daughter node in
turn by applying this algorithm on them recursively. If a leaf node straddles
the view frustrum then it's bad luck, you just draw all the tristrips it
contains and let OpenGL do the work.
You might also want to put a 'transition range' onto each node and if it
lies beyond that range cull it. You can also use this to conveniently
switch levels of detail by having multiple versions of each object in
the tree.
Testing a sphere against the View Frustum:
==========================================
In most cases, we can describe the volume of space that you can see
through the little glass window on the front of your CRT using a
Frustum (frequently mis-spelled as Frustrum or Fustrum even in some
text books).
A frustum is a truncated pyramid - which typically bounded by six
planes called:
NEAR, FAR, LEFT, RIGHT, TOP, BOTTOM
There are applications that require additional clipping planes (eg for
non-rectangular screens) - extending the work described in this
to cater for that is not hard).
In principal, all six planes can be constructed as general plane
equations:
A x + B y + C z + D == 0
However, for most applications, NEAR and FAR are parallel to the
screen, LEFT, RIGHT,TOP and BOTTOM all meet at the eye and the eye lies
along a vector that extends out from the center of the screen and is
perpendicular to it. This simplifies the equations considerably for
practical applications.
Transforms.
~~~~~~~~~~~
It is easiest to perform culling in a coordinate system where the
eyepoint is at the origin and the line from the eye through the center
of the screen lies along one major axis with the edges of the screen
parallel to the remaining two axes. This coordinate system is called
'Eye Space'.
Testing a Sphere against a Frustum.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The most important thing to bear in mind about culling is that the
first trivial-reject test you apply is by far the most time-critical.
This test is always applied to more nodes than any of the subsequent
tests.
So, do the cheapest test first.
This is typically the NEAR plane test. Everything behind the viewers
head gets chopped out - and it's an especially cheap test.
if ( obj_sphere.center.z < near_plane - obj_sphere.radius )
REJECT!!
...next do the second cheapest test (assuming you know that your
database could possibly extend beyond the far clip plane)...
if ( obj_sphere.center.z - obj_sphere.radius > far_plane )
REJECT!!
...and *then* (for each of the other 4 planes) do...
if ( distance( obj.position, plane ) <= obj_sphere.radius )
REJECT!!
(The algorithm for computing that 'distance()' function is described
below).
It's also useful to know that in many applications, you cull more
objects from the left and right faces of the frustum than you do from
the top and bottom - so test left, then right, then bottom then top.
Also, with bounding sphere tests, you shouldn't forget to do
total-accept as well as total-reject tests. Once you know that an
object's sphere is TOTALLY on screen, you don't have to descend into
the daughter objects to cull-test them...you *know* they are all
on-screen.
Another way to look at that it to remember which of the six possible
plane tests didn't even touch the sphere - as you work your way down
the object hierarchy, you can accumulate those flags and avoid even
testing those planes that a parent sphere has already cleanly passed.
If you do this then a vast percentage of your spheres will only need to
be tested against one plane. However, for the normal case of a simple
frustum - when you examine the fully optimised
distance-of-point-from-plane code (below), you may well conclude that
this additional logic doesn't justify the paltry amount of additional
math that it might save.
Computing the Distance from Sphere Center to Clipping Plane.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A plane can be represented by the equation
Ax + By + Cz + D = 0 ;
A,B,C is just the surface normal of the plane and D is the shortest
distance from the origin to the plane.
So, if you need to find the distance of a point from the plane, just
imagine a new plane that goes through your test point and is parallel
to the plane you want to test. The plane equation of that new plane
would be:
A'x + B'y + C'z + D' = 0 ;
Since the two planes are parallel, their surface normals are the same,
so
A' == A B' == B C' == C D' == D + distance_between_the_two_planes
...the only thing that's different is their D values - which differ by
the distance of your test point from the original plane.
So, for a point (x,y,z), the distance 'd' from the plane (A,B,C,D) is
derived as:
d = D' - D
= -A'x - B'y - C'z - D
= -Ax - By - Cz - D
= -( [ABC]dot[xyz] + D )
A dot-product of the point and the surface normal of the plane, plus
the distance from the plane to the origin. Three multiplies, three
additions and a negation.
As an aside - if you consider the point (x,y,z) as a FOUR element
homogeneous vector (x,y,z,w) then 'w' is 1.0 and you can compute the
distance by simply taking the four element dot-product of (A,B,C,D)
with (x,y,z,w). If you have fast 4x4 matrix math hardware in your
machine then you can use it to compute the distance from a point to all
four planes in a single operation!
That's the general result for an arbitary plane - but culling to the
view frustum is a very special case. If you are working in eye-relative
coordinates (IMHO this is best), then since all TOP,BOTTOM,LEFT,RIGHT
planes of the frustum meet at the eye - and since the eye is at the
origin (by definition), then D is always zero for those planes and that
saves you a subtract.
If you are feeling even more in need of optimisation - then you can
save one multiply per plane by realising that (for rectangular screens)
one of the three components of the plane equation will always be zero.
So, for the LEFT clip plane, the Y component of the normal of the plane
is zero, so the distance to the left or right plane is just
d = -( Ax + Cz )
...and to the top or bottom plane it's just:
d = -( By + Cz )
Furthermore, we know that the A component for the LEFT plane is just
the negation of the A component of the RIGHT plane, and the C component
is the same for both LEFT and RIGHT (and similarly, the B component of
the TOP plane, is the negation of the B component for the BOTTOM plane
and the C component is the same for both TOP and BOTTOM). This means
that you only need four multiplies and four additions to do the entire
job. (Since you are only using this for culling, you don't need the
minus sign - just reverse the conditional).
The NEAR and FAR planes are typically parallel to the X/Y plane. That
means that A and B are both zero and C is one (or minus-one) - but D is
not zero, so the math boils down to an add and a negate:
d = -(z + D)
Conclusions.
~~~~~~~~~~~~
Sphere-based culling can be extremely cost-effective. It's so cheap
that even if you feel the need to use a bounding cubeoid (or even a yet
more complex shape), it's still worth doing a sphere-based cull first
just to get rid of the trivial accept and reject cases.
Steve Baker (817)619-8776 (Vox/Vox-Mail)
Raytheon Systems Inc. (817)619-4028 (Fax)
Work: SBaker@link.com http://www.hti.com
Home: SJBaker1@airmail.net http://web2.airmail.net/sjbaker1
From owner-flight-gear@me.umn.edu Tue May 26 08:43:36 1998
X-VM-v5-Data: ([nil nil nil nil nil nil nil nil nil]
["2090" "Tue" "26" "May" "1998" "08:42:09" "-0500" "Steve Baker" "sbaker@link.com" nil "69" "Re: [FGFS] View frustum culling" "^From:" nil nil "5" nil nil nil nil nil]
nil)
Received: (from majordom@localhost)
by meserv.me.umn.edu (8.8.8/8.8.8) id IAA29744
for flight-gear-outgoing; Tue, 26 May 1998 08:43:36 -0500 (CDT)
X-Authentication-Warning: meserv.me.umn.edu: majordom set sender to owner-flight-gear@me.umn.edu using -f
Received: from lfkw10.bgm.link.com (bgm.link.com [130.210.2.10])
by meserv.me.umn.edu (8.8.8/8.8.8) with ESMTP id IAA29740
for <flight-gear@me.umn.edu>; Tue, 26 May 1998 08:43:31 -0500 (CDT)
Received: from borgus.bgm.link.com (borgus.bgm.link.com [130.210.236.13])
by lfkw10.bgm.link.com (8.8.6/HTI-Hack-8.8.4) with SMTP
id IAA02170 for <flight-gear@me.umn.edu>; Tue, 26 May 1998 08:43:01 -0500 (CDT)
X-Sender: steve@borgus.bgm.link.com
In-Reply-To: <199805240245.VAA00603@kenai.me.umn.edu>
Message-ID: <Pine.SGI.3.96.980526083427.2282G-100000@borgus.bgm.link.com>
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Precedence: bulk
Reply-To: flight-gear@me.umn.edu
From: Steve Baker <sbaker@link.com>
Sender: owner-flight-gear@me.umn.edu
To: flight-gear@me.umn.edu
Subject: Re: [FGFS] View frustum culling
Date: Tue, 26 May 1998 08:42:09 -0500 (CDT)
On Sat, 23 May 1998, Curtis L. Olson wrote:
> Gene Buckle writes:
> > If you want to email me a cygnus/mesa binary, I'd be happy to give
> > you new speed figures.
>
> Gene,
>
> The new binaries expect a modified scenery format. My impression for
> now based on culled vs. drawn percentages is that there was a much
> bigger jump between no culling and tile culling, than between tile
> culling and fragment culling.
That's to be expected...
(The eye is in the center of the diagram - looking up:
No Culling - draw this much:
________\_____________/________
| | \ | / | |
| | \ | / | |
|_______|___\___|___/___|_______|
| | \ | / | |
| | \ | / | |
|_______|______\|/______|_______|
| | | | |
| | | | |
|_______|_______|_______|_______|
| | | | |
| | | | |
|_______|_______|_______|_______|
Tile culling - draw this much:
_\_____________/_
| \ | / |
| \ | / |
|___\___|___/___|
| \ | / |
| \ | / |
|______\|/______|
Tile *and* tstrip culling - draw maybe this much:
\_____________/_
|_\ | /_|
|_\ | / |
|_\___|___/__|
|\ | /_|
|_\ | /_|
|\|/|
Clearly most of the savings were in the tile culling, but providing the
culling itself is done reasonably efficiently, the tstrip culling is
still worth-while.
Steve Baker (817)619-8776 (Vox/Vox-Mail)
Raytheon Systems Inc. (817)619-4028 (Fax)
Work: SBaker@link.com http://www.hti.com
Home: SJBaker1@airmail.net http://web2.airmail.net/sjbaker1
-------------------------------------
Please visit the FGFS web page: http://www.menet.umn.edu/~curt/fgfs/
For help on using this list (especially unsubscribing), send a message to
"flight-gear-request@me.umn.edu" with a single line of text: "help".

View file

@ -1,86 +0,0 @@
From fatcity!root@news.cts.com Mon Apr 20 10:54:32 1998
X-VM-v5-Data: ([nil nil nil nil nil nil nil nil nil]
["2073" "Mon" "20" "April" "1998" "07:50:34" "-0800" "Steve Baker" "sbaker@link.com" nil "54" "Re: How To Q: Off-screen object culling." "^From:" nil nil "4" nil nil nil nil nil]
nil)
Received: from mh2.cts.com (root@mh2.cts.com [205.163.24.68])
by meserv.me.umn.edu (8.8.8/8.8.8) with ESMTP id KAA05163
for <curt@me.umn.edu>; Mon, 20 Apr 1998 10:54:29 -0500 (CDT)
Received: from king.cts.com (root@king.cts.com [198.68.168.21]) by mh2.cts.com (8.8.7/8.8.5) with ESMTP id IAA15636; Mon, 20 Apr 1998 08:51:20 -0700 (PDT)
Received: from donews.cts.com (root@donews.cts.com [192.188.72.21])
by king.cts.com (8.8.7/8.8.7) with SMTP id IAA29983;
Mon, 20 Apr 1998 08:51:19 -0700 (PDT)
Received: from fatcity by donews.cts.com with uucp
(Smail3.1.29.1 #5) id m0yRI5D-00000Xa; Mon, 20 Apr 98 08:02 PDT
Received: by fatcity.com (10-Feb-1998/v1.0f-b64/bab) via UUCP id 0001F042; Mon, 20 Apr 1998 07:50:34 -0800
Message-ID: <F001.0001F042.19980420075034@fatcity.com>
X-Comment: OpenGL Game Developers Mailing List
X-Sender: Steve Baker <sbaker@link.com>
Reply-To: OPENGL-GAMEDEV-L@fatcity.com
Errors-To: ML-ERRORS@fatcity.com
Organization: Fat City Network Services, San Diego, California
X-ListServer: v1.0f, build 64; ListGuru (c) 1996-1998 Bruce A. Bergman
Precedence: bulk
Mime-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Content-Transfer-Encoding: 7bit
From: Steve Baker <sbaker@link.com>
Sender: root@fatcity.com
To: Multiple recipients of list OPENGL-GAMEDEV-L <OPENGL-GAMEDEV-L@fatcity.com>
Subject: Re: How To Q: Off-screen object culling.
Date: Mon, 20 Apr 1998 07:50:34 -0800
On Sat, 18 Apr 1998, Jason Maskell wrote:
> This is probably an FAQ, but I'm to the point now where I need to be
> able to tell when one of my objects is offscreen and not even send it
> down the pipe. This would be pretty simple if I was using glFrustum,
> but I'm not at the moment. I could switch, but I haven't quite got my
> head around how to get the same results as I get using glPerspective..
> If someone can point me to some code that does some simple pre-culling,
> I would be most grateful.. >
Well, if you can do it with glFrustum then you can do it with
gluPerspective. Note that gluPerspective simply calls glFrustum.
It's like this:
void APIENTRY gluPerspective( GLdouble fovy, GLdouble aspect,
GLdouble zNear, GLdouble zFar )
{
GLdouble xmin, xmax, ymin, ymax;
ymax = zNear * tan( fovy * M_PI / 360.0 );
ymin = -ymax;
xmin = ymin * aspect;
xmax = ymax * aspect;
glFrustum( xmin, xmax, ymin, ymax, zNear, zFar );
}
[This is actually the source code for gluPerspective from the Mesa
library - but since it only involves regular OpenGL API, it should
work on any OpenGL implementation]
> BTW, I've bought the red book finally...
Always a good move. I have yet to hear anyone who regretted it.
Steve Baker (817)619-8776 (Vox/Vox-Mail)
Raytheon Systems Inc. (817)619-4028 (Fax)
Work: SBaker@link.com http://www.hti.com
Home: SJBaker1@airmail.net http://web2.airmail.net/sjbaker1
--
Author: Steve Baker
INET: sbaker@link.com
Fat City Network Services -- (619) 538-5051 FAX: (619) 538-5051
San Diego, California -- Public Internet access / Mailing Lists
--------------------------------------------------------------------
To REMOVE yourself from this mailing list, send an E-Mail message
to: ListGuru@fatcity.com (note EXACT spelling of 'ListGuru') and in
the message BODY, include a line containing: UNSUB OPENGL-GAMEDEV-L
(or the name of mailing list you want to be removed from). You may
also send the HELP command for other information (like subscribing).

View file

@ -1,112 +0,0 @@
From nhv@laserplot.com Mon Mar 16 14:16:34 1998
X-VM-v5-Data: ([nil nil nil nil t nil nil nil nil]
["1740" "Mon" "16" "March" "1998" "15:11:22" "-0500" "Norman Vine" "nhv@laserplot.com" "<01BD50EE.348AEBC0.nhv@laserplot.com>" "84" "RE: Today's patches" "^From:" nil nil "3" nil nil nil nil nil]
nil)
Received: from mail-out-0.tiac.net (mail-out-0.tiac.net [199.0.65.247])
by meserv.me.umn.edu (8.8.8/8.8.8) with ESMTP id OAA21951
for <curt@me.umn.edu>; Mon, 16 Mar 1998 14:16:33 -0600 (CST)
Received: from mail-out-2.tiac.net (mail-out-2.tiac.net [199.0.65.13])
by mail-out-0.tiac.net (8.8.8/8.8.8) with ESMTP id PAA20462
for <curt@me.umn.edu>; Mon, 16 Mar 1998 15:16:26 -0500 (EST)
(envelope-from nhv@laserplot.com)
Received: from nhv (p1.gw1.mashp.MA.tiac.com [206.119.240.34])
by mail-out-2.tiac.net (8.8.7/8.8.7) with SMTP id PAA26460
for <curt@me.umn.edu>; Mon, 16 Mar 1998 15:17:02 -0500 (EST)
(envelope-from nhv@laserplot.com)
Received: by localhost with Microsoft MAPI; Mon, 16 Mar 1998 15:14:25 -0500
Message-ID: <01BD50EE.348AEBC0.nhv@laserplot.com>
Reply-To: "nhv@laserplot.com" <nhv@laserplot.com>
X-Mailer: Microsoft Internet E-mail/MAPI - 8.0.0.4211
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
From: Norman Vine <nhv@laserplot.com>
To: "'Curtis L. Olson'" <curt@me.umn.edu>
Subject: RE: Today's patches
Date: Mon, 16 Mar 1998 15:11:22 -0500
On Monday, March 16, 1998 2:31 PM, Curtis L. Olson [SMTP:curt@me.umn.edu] wrote:
> Norm,
>
> I got both your patches. Thanks! The first one looks good, I'll
> forward that over to the HUD guys.
>
> For the second one, could you try a little bit different fix? It
> seemed to work for me anyways. Somewhere in fg_time.c you'll see the
> following four lines:
>
> #ifdef WIN32
> int daylight;
> long int timezone;
> #endif /* WIN32 */
>
> Could you just try moving them to the top of the file (outside of any
> functions) so they have a "global" scope? I put 'em right before
> fgTimeInit().
Seems to work :-)
>
> I just did a quick test of this and I didn't see the sun jumping
> around. I really wish I knew how to get the real daylight savings
> time info out of a win32 machine ...
following time related stuff from CygWin headers
<Windows32/ Structures.h>
typedef struct _TIME_ZONE_INFORMATION {
LONG Bias;
WCHAR StandardName[ 32 ];
SYSTEMTIME StandardDate;
LONG StandardBias;
WCHAR DaylightName[ 32 ];
SYSTEMTIME DaylightDate;
LONG DaylightBias;
} TIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION;
typedef struct _SYSTEMTIME {
WORD wYear;
WORD wMonth;
WORD wDayOfWeek;
WORD wDay;
WORD wHour;
WORD wMinute;
WORD wSecond;
WORD wMilliseconds;
} SYSTEMTIME, *LPSYSTEMTIME;
!!!!!!!!!!!!!!!!!!!!!!
<Windows32/ Functions.h>
DWORD
STDCALL
GetTimeZoneInformation(
LPTIME_ZONE_INFORMATION lpTimeZoneInformation
);
VOID
STDCALL
GetSystemTime(
LPSYSTEMTIME lpSystemTime
);
VOID
STDCALL
GetLocalTime(
LPSYSTEMTIME lpSystemTime
);
DWORD
STDCALL
GetTickCount(
VOID
);
See Ya
Norman

View file

@ -1,13 +0,0 @@
noinst_LIBRARIES = libBucket.a
libBucket_a_SOURCES = newbucket.cxx newbucket.hxx
# bin_PROGRAMS = testbucket
# testbucket_SOURCES = testbucket.cxx
# testbucket_LDADD = \
# $(top_builddir)/Lib/Bucket/libBucket.a \
# $(top_builddir)/Lib/Misc/libMisc.a
INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib

View file

@ -1,155 +0,0 @@
/**************************************************************************
* newbucket.hxx -- new bucket routines for better world modeling
*
* Written by Curtis L. 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$
**************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <math.h>
#include <Misc/fgpath.hxx>
#include "newbucket.hxx"
// Build the path name for this bucket
string FGBucket::gen_base_path() const {
// long int index;
int top_lon, top_lat, main_lon, main_lat;
char hem, pole;
char raw_path[256];
top_lon = lon / 10;
main_lon = lon;
if ( (lon < 0) && (top_lon * 10 != lon) ) {
top_lon -= 1;
}
top_lon *= 10;
if ( top_lon >= 0 ) {
hem = 'e';
} else {
hem = 'w';
top_lon *= -1;
}
if ( main_lon < 0 ) {
main_lon *= -1;
}
top_lat = lat / 10;
main_lat = lat;
if ( (lat < 0) && (top_lat * 10 != lat) ) {
top_lat -= 1;
}
top_lat *= 10;
if ( top_lat >= 0 ) {
pole = 'n';
} else {
pole = 's';
top_lat *= -1;
}
if ( main_lat < 0 ) {
main_lat *= -1;
}
sprintf(raw_path, "%c%03d%c%02d/%c%03d%c%02d",
hem, top_lon, pole, top_lat,
hem, main_lon, pole, main_lat);
FGPath path( raw_path );
return path.str();
}
// find the bucket which is offset by the specified tile units in the
// X & Y direction. We need the current lon and lat to resolve
// ambiguities when going from a wider tile to a narrower one above or
// below. This assumes that we are feeding in
FGBucket fgBucketOffset( double dlon, double dlat, int dx, int dy ) {
FGBucket result( dlon, dlat );
double clat = result.get_center_lat() + dy * FG_BUCKET_SPAN;
// walk dy units in the lat direction
result.set_bucket( dlon, clat );
// find the lon span for the new latitude
double span = bucket_span( clat );
// walk dx units in the lon direction
double tmp = dlon + dx * span;
while ( tmp < -180.0 ) {
tmp += 360.0;
}
while ( tmp >= 180.0 ) {
tmp -= 360.0;
}
result.set_bucket( tmp, clat );
return result;
}
// calculate the offset between two buckets
void fgBucketDiff( const FGBucket& b1, const FGBucket& b2, int *dx, int *dy ) {
// Latitude difference
double c1_lat = b1.get_center_lat();
double c2_lat = b2.get_center_lat();
double diff_lat = c2_lat - c1_lat;
#ifdef HAVE_RINT
*dy = (int)rint( diff_lat / FG_BUCKET_SPAN );
#else
if ( diff_lat > 0 ) {
*dy = (int)( diff_lat / FG_BUCKET_SPAN + 0.5 );
} else {
*dy = (int)( diff_lat / FG_BUCKET_SPAN - 0.5 );
}
#endif
// longitude difference
double c1_lon = b1.get_center_lon();
double c2_lon = b2.get_center_lon();
double diff_lon = c2_lon - c1_lon;
double span;
if ( bucket_span(c1_lat) <= bucket_span(c2_lat) ) {
span = bucket_span(c1_lat);
} else {
span = bucket_span(c2_lat);
}
#ifdef HAVE_RINT
*dx = (int)rint( diff_lon / span );
#else
if ( diff_lon > 0 ) {
*dx = (int)( diff_lon / span + 0.5 );
} else {
*dx = (int)( diff_lon / span - 0.5 );
}
#endif
}

View file

@ -1,351 +0,0 @@
/**************************************************************************
* newbucket.hxx -- new bucket routines for better world modeling
*
* Written by Curtis L. 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$
**************************************************************************/
#ifndef _NEWBUCKET_HXX
#define _NEWBUCKET_HXX
#include <Include/compiler.h>
#ifdef FG_HAVE_STD_INCLUDES
# include <cmath>
# include <cstdio> // sprintf()
# include <iostream>
#else
# include <math.h>
# include <stdio.h> // sprintf()
# include <iostream.h>
#endif
// I don't understand ... <math.h> or <cmath> should be included
// already depending on how you defined FG_HAVE_STD_INCLUDES, but I
// can go ahead and add this -- CLO
#ifdef __MWERKS__
# include <math.h> // needed fabs()
#endif
#include STL_STRING
FG_USING_STD(string);
#if ! defined( FG_HAVE_NATIVE_SGI_COMPILERS )
FG_USING_STD(ostream);
#endif
#include <Include/fg_constants.h>
#define FG_BUCKET_SPAN 0.125 // 1/8 of a degree
#define FG_HALF_BUCKET_SPAN 0.0625 // 1/2 of 1/8 of a degree = 1/16 = 0.0625
class FGBucket;
ostream& operator<< ( ostream&, const FGBucket& );
bool operator== ( const FGBucket&, const FGBucket& );
class FGBucket {
private:
double cx, cy; // centerpoint (lon, lat) in degrees of bucket
int lon; // longitude index (-180 to 179)
int lat; // latitude index (-90 to 89)
int x; // x subdivision (0 to 7)
int y; // y subdivision (0 to 7)
public:
// default constructor
FGBucket();
// create a bucket which would contain the specified lon/lat
FGBucket(const double lon, const double lat);
// create a bucket based on "long int" index
FGBucket(const long int bindex);
// create an impossible bucket if false
FGBucket(const bool is_good);
~FGBucket();
// Set the bucket params for the specified lat and lon
void set_bucket( double dlon, double dlat );
void make_bad ( void );
// Generate the unique scenery tile index for this bucket
long int gen_index();
string gen_index_str() const;
// Build the path name for this bucket
string gen_base_path() const;
// return the center lon of a tile
double get_center_lon() const;
// return width of the tile
double get_width() const;
// return the center lat of a tile
double get_center_lat() const;
// return height of the tile
double get_height() const;
// Informational methods
inline int get_lon() const { return lon; }
inline int get_lat() const { return lat; }
inline int get_x() const { return x; }
inline int get_y() const { return y; }
// friends
friend ostream& operator<< ( ostream&, const FGBucket& );
friend bool operator== ( const FGBucket&, const FGBucket& );
};
// return the horizontal tile span factor based on latitude
inline double bucket_span( double l ) {
if ( l >= 89.0 ) {
return 360.0;
} else if ( l >= 88.0 ) {
return 8.0;
} else if ( l >= 86.0 ) {
return 4.0;
} else if ( l >= 83.0 ) {
return 2.0;
} else if ( l >= 76.0 ) {
return 1.0;
} else if ( l >= 62.0 ) {
return 0.5;
} else if ( l >= 22.0 ) {
return 0.25;
} else if ( l >= -22.0 ) {
return 0.125;
} else if ( l >= -62.0 ) {
return 0.25;
} else if ( l >= -76.0 ) {
return 0.5;
} else if ( l >= -83.0 ) {
return 1.0;
} else if ( l >= -86.0 ) {
return 2.0;
} else if ( l >= -88.0 ) {
return 4.0;
} else if ( l >= -89.0 ) {
return 8.0;
} else {
return 360.0;
}
}
// Set the bucket params for the specified lat and lon
inline void FGBucket::set_bucket( double dlon, double dlat ) {
//
// latitude first
//
double span = bucket_span( dlat );
double diff = dlon - (double)(int)dlon;
// cout << "diff = " << diff << " span = " << span << endl;
if ( (dlon >= 0) || (fabs(diff) < FG_EPSILON) ) {
lon = (int)dlon;
} else {
lon = (int)dlon - 1;
}
// find subdivision or super lon if needed
if ( span < FG_EPSILON ) {
// polar cap
lon = 0;
x = 0;
} else if ( span <= 1.0 ) {
x = (int)((dlon - lon) / span);
} else {
if ( (dlon >= 0) || (fabs(diff) < FG_EPSILON) ) {
lon = (int)( (int)(lon / span) * span);
} else {
// cout << " lon = " << lon
// << " tmp = " << (int)((lon-1) / span) << endl;
lon = (int)( (int)((lon + 1) / span) * span - span);
if ( lon < -180 ) {
lon = -180;
}
}
x = 0;
}
//
// then latitude
//
diff = dlat - (double)(int)dlat;
if ( (dlat >= 0) || (fabs(diff) < FG_EPSILON) ) {
lat = (int)dlat;
} else {
lat = (int)dlat - 1;
}
y = (int)((dlat - lat) * 8);
}
// default constructor
inline FGBucket::FGBucket() {}
// constructor for specified location
inline FGBucket::FGBucket(const double dlon, const double dlat) {
set_bucket(dlon, dlat);
}
// create an impossible bucket if false
inline FGBucket::FGBucket(const bool is_good) {
set_bucket(0.0, 0.0);
if ( !is_good ) {
lon = -1000;
}
}
// Parse a unique scenery tile index and find the lon, lat, x, and y
inline FGBucket::FGBucket(const long int bindex) {
long int index = bindex;
lon = index >> 14;
index -= lon << 14;
lon -= 180;
lat = index >> 6;
index -= lat << 6;
lat -= 90;
y = index >> 3;
index -= y << 3;
x = index;
}
// default destructor
inline FGBucket::~FGBucket() {}
// Generate the unique scenery tile index for this bucket
//
// The index is constructed as follows:
//
// 9 bits - to represent 360 degrees of longitude (-180 to 179)
// 8 bits - to represent 180 degrees of latitude (-90 to 89)
//
// Each 1 degree by 1 degree tile is further broken down into an 8x8
// grid. So we also need:
//
// 3 bits - to represent x (0 to 7)
// 3 bits - to represent y (0 to 7)
inline long int FGBucket::gen_index() {
return ((lon + 180) << 14) + ((lat + 90) << 6) + (y << 3) + x;
}
inline string FGBucket::gen_index_str() const {
char tmp[20];
sprintf(tmp, "%ld",
(((long)lon + 180) << 14) + ((lat + 90) << 6) + (y << 3) + x);
return (string)tmp;
}
// return the center lon of a tile
inline double FGBucket::get_center_lon() const {
double span = bucket_span( lat + y / 8.0 + FG_HALF_BUCKET_SPAN );
if ( span >= 1.0 ) {
return lon + span / 2.0;
} else {
return lon + x * span + span / 2.0;
}
}
// return the center lat of a tile
inline double FGBucket::get_center_lat() const {
return lat + y / 8.0 + FG_HALF_BUCKET_SPAN;
}
// return width of the tile
inline double FGBucket::get_width() const {
return bucket_span( get_center_lat() );
}
// return height of the tile
inline double FGBucket::get_height() const {
return FG_BUCKET_SPAN;
}
// create an impossible bucket
inline void FGBucket::make_bad( void ) {
set_bucket(0.0, 0.0);
lon = -1000;
}
// offset a bucket struct by the specified tile units in the X & Y
// direction
FGBucket fgBucketOffset( double dlon, double dlat, int x, int y );
// calculate the offset between two buckets
void fgBucketDiff( const FGBucket& b1, const FGBucket& b2, int *dx, int *dy );
/*
// Given a lat/lon, fill in the local tile index array
void fgBucketGenIdxArray(fgBUCKET *p1, fgBUCKET *tiles, int width, int height);
*/
inline ostream&
operator<< ( ostream& out, const FGBucket& b )
{
return out << b.lon << ":" << b.x << ", " << b.lat << ":" << b.y;
}
inline bool
operator== ( const FGBucket& b1, const FGBucket& b2 )
{
return ( b1.lon == b2.lon &&
b1.lat == b2.lat &&
b1.x == b2.x &&
b1.y == b2.y );
}
#endif // _NEWBUCKET_HXX

View file

@ -1,32 +0,0 @@
// test new bucket routines
#include "newbucket.cxx"
main() {
double lat = 21.9625;
double lon = -110.0 + 0.0625;
/*
while ( lon < 180 ) {
FGBucket b1( lon, lat );
long int index = b1.gen_index();
FGBucket b2( index );
cout << lon << "," << lat << " ";
cout << b2 << " " << b2.get_center_lon() << ","
<< b2.get_center_lat() << endl;
lon += 0.125;
}
*/
FGBucket b1;
for ( int j = 2; j >= -2; j-- ) {
for ( int i = -2; i < 3; i++ ) {
b1 = fgBucketOffset(lon, lat, i, j);
cout << "(" << i << "," << j << ")" << b1 << "\t";
}
cout << endl;
}
}

View file

@ -1,11 +0,0 @@
EXTRA_DIST = logtest.cxx
noinst_LIBRARIES = libDebug.a
libDebug_a_SOURCES = \
debug_types.h \
logstream.cxx logstream.hxx
# fg_debug.c fg_debug.h \
INCLUDES += -I$(top_builddir)

View file

@ -1,37 +0,0 @@
// NB: To add a dbg_class, add it here, and add it to the structure in
// fg_debug.c
typedef enum {
FG_NONE = 0x00000000,
FG_TERRAIN = 0x00000001,
FG_ASTRO = 0x00000002,
FG_FLIGHT = 0x00000004,
FG_INPUT = 0x00000008,
FG_GL = 0x00000010,
FG_VIEW = 0x00000020,
FG_COCKPIT = 0x00000040,
FG_GENERAL = 0x00000080,
FG_MATH = 0x00000100,
FG_EVENT = 0x00000200,
FG_AIRCRAFT = 0x00000400,
FG_AUTOPILOT = 0x00000800,
FG_SERIAL = 0x00001000,
FG_CLIPPER = 0x00002000,
FG_UNDEFD = 0x00004000, // For range checking
FG_ALL = 0xFFFFFFFF
} fgDebugClass;
// NB: To add a priority, add it here.
typedef enum {
FG_BULK, // For frequent messages
FG_DEBUG, // Less frequent debug type messages
FG_INFO, // Informatory messages
FG_WARN, // Possible impending problem
FG_ALERT // Very possible impending problem
// FG_EXIT, // Problem (no core)
// FG_ABORT // Abandon ship (core)
} fgDebugPriority;

View file

@ -1,282 +0,0 @@
/* -*- Mode: C++ -*-
*
* fg_debug.c -- Flight Gear debug utility functions
*
* Written by Paul Bleisch, started January 1998.
*
* Copyright (C) 1998 Paul Bleisch, pbleisch@acm.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$
**************************************************************************/
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <Include/cmdargs.h> // Line to command line arguments
#include "fg_debug.h"
static int fg_DebugSem = 1;
fgDebugClass fg_DebugClass = FG_NONE; // Need visibility for
fgDebugPriority fg_DebugPriority = FG_INFO; // command line processing.
static fgDebugCallback fg_DebugCallback = NULL;
FILE *fg_DebugOutput = NULL; // Visibility needed for command line processor.
// This can be set to a FILE from the command
// line. If not, it will be set to stderr.
/* TODO: Actually make this thing thread safe */
#ifdef USETHREADS
#define FG_GRABDEBUGSEM while( --fg_DebugSem < 0 ) { fg_DebugSem++; }
#define FG_RELEASEDEBUGSEM fg_DebugSem++;
#else
#define FG_GRABDEBUGSEM
#define FG_RELEASEDEBUGSEM
#endif
/* Used for convienence initialization from env variables.
*/
static struct {
char *str;
fgDebugClass dbg_class;
} fg_DebugClasses[] = {
{ "FG_NONE", 0x00000000 },
{ "FG_TERRAIN", 0x00000001 },
{ "FG_ASTRO", 0x00000002 },
{ "FG_FLIGHT", 0x00000004 },
{ "FG_INPUT", 0x00000008 },
{ "FG_GL", 0x00000010 },
{ "FG_VIEW", 0x00000020 },
{ "FG_COCKPIT", 0x00000040 },
{ "FG_GENERAL", 0x00000080 },
{ "FG_MATH", 0x00000100 },
{ "FG_EVENT", 0x00000200 },
{ "FG_AIRCRAFT", 0x00000400 },
{ "FG_AUTOPILOT", 0x00000800 },
/* Do not edit below here, last entry should be null */
{ "FG_ALL", 0xFFFFFFFF },
{ NULL, 0 }
};
static fgDebugClass fgDebugStrToClass( char *str );
/* fgInitDebug =============================================================*/
void fgInitDebug( void ) {
char *pszClass, *pszPrio, *pszFile;
// Support for log file/alt debug output via command line, environment or
// reasonable default.
/*
if( strlen( logArgbuf ) > 3) { // First check for command line option
// Assumed that we will append.
fg_DebugOutput = fopen(logArgbuf, "a+" );
}
*/
if( !fg_DebugOutput ) { // If not set on command line, environment?
pszFile = getenv( "FG_DEBUGFILE" );
if( pszFile ) { // There is such an environmental variable.
fg_DebugOutput = fopen( pszFile, "a+" );
}
}
if( !fg_DebugOutput ) { // If neither command line nor environment
fg_DebugOutput = stderr; // then we use the fallback position
}
FG_GRABDEBUGSEM;
fg_DebugSem = fg_DebugSem; /* shut up GCC */
// Test command line option overridge of debug priority. If the value
// is in range (properly optioned) the we will override both defaults
// and the environmental value.
/*
if ((priorityArgValue >= FG_BULK) && (priorityArgValue <= FG_ABORT)) {
fg_DebugPriority = priorityArgValue;
} else { // Either not set or out of range. We will not warn the user.
*/
pszPrio = getenv( "FG_DEBUGPRIORITY" );
if( pszPrio ) {
fg_DebugPriority = atoi( pszPrio );
fprintf( stderr,
"fg_debug.c: Environment overrides default debug priority (%d)\n",
fg_DebugPriority );
}
/* } */
/*
if ((debugArgValue >= FG_ALL) && (debugArgValue < FG_UNDEFD)) {
fg_DebugPriority = priorityArgValue;
} else { // Either not set or out of range. We will not warn the user.
*/
pszClass = getenv( "FG_DEBUGCLASS" );
if( pszClass ) {
fg_DebugClass = fgDebugStrToClass( pszClass );
fprintf( stderr,
"fg_debug.c: Environment overrides default debug class (0x%08X)\n",
fg_DebugClass );
}
/* } */
FG_RELEASEDEBUGSEM;
}
/* fgDebugStrToClass ======================================================*/
fgDebugClass fgDebugStrToClass( char *str ) {
char *hex = "0123456789ABCDEF";
char *hexl = "0123456789abcdef";
char *pt, *p, *ph, ps = 1;
unsigned int val = 0, i;
if( str == NULL ) {
return 0;
}
/* Check for 0xXXXXXX notation */
p = strstr( str, "0x");
if( p ) {
p++; p++;
while (*p) {
ph = strchr(hex,*p);
if ( ph ) {
val <<= 4;
val += ph-hex;
p++;
} else {
ph = strchr(hexl,*p);
if ( ph ) {
val <<= 4;
val += ph-hex;
p++;
} else {
// fprintf( stderr, "Error in hex string '%s'\n", str );
return FG_NONE;
}
}
}
} else {
/* Must be in string format */
p = str;
ps = 1;
while( ps ) {
while( *p && (*p==' ' || *p=='\t') ) p++; /* remove whitespace */
pt = p; /* mark token */
while( *p && (*p!='|') ) p++; /* find OR or EOS */
ps = *p; /* save value at p so we can attempt to be bounds safe */
*p++ = 0; /* terminate token */
/* determine value for token */
i=0;
while( fg_DebugClasses[i].str &&
strncmp( fg_DebugClasses[i].str, pt,
strlen(fg_DebugClasses[i].str)) ) i++;
if( fg_DebugClasses[i].str == NULL ) {
fprintf( stderr,
"fg_debug.c: Could not find message class '%s'\n",
pt );
} else {
val |= fg_DebugClasses[i].dbg_class;
}
}
}
return (fgDebugClass)val;
}
/* fgSetDebugOutput =======================================================*/
void fgSetDebugOutput( FILE *out ) {
FG_GRABDEBUGSEM;
fflush( fg_DebugOutput );
fg_DebugOutput = out;
FG_RELEASEDEBUGSEM;
}
/* fgSetDebugLevels =======================================================*/
void fgSetDebugLevels( fgDebugClass dbg_class, fgDebugPriority prio ) {
FG_GRABDEBUGSEM;
fg_DebugClass = dbg_class;
fg_DebugPriority = prio;
FG_RELEASEDEBUGSEM;
}
/* fgRegisterDebugCallback ================================================*/
fgDebugCallback fgRegisterDebugCallback( fgDebugCallback callback ) {
fgDebugCallback old;
FG_GRABDEBUGSEM;
old = fg_DebugCallback;
fg_DebugCallback = callback;
FG_RELEASEDEBUGSEM;
return old;
}
/* fgPrintf ===============================================================*/
int fgPrintf( fgDebugClass dbg_class, fgDebugPriority prio, char *fmt, ... ) {
char szOut[1024+1];
va_list ap;
int ret = 0;
// If no action to take, then don't bother with the semaphore
// activity Slight speed benefit.
// printf("dbg_class = %d fg_DebugClass = %d\n", dbg_class, fg_DebugClass);
// printf("prio = %d fg_DebugPriority = %d\n", prio, fg_DebugPriority);
if( !(dbg_class & fg_DebugClass) ) {
// Failed to match a specific debug class
if ( prio < fg_DebugPriority ) {
// priority is less than requested
// "ret" is zero anyway. But we might think about changing
// it upon some error condition?
return ret;
}
}
FG_GRABDEBUGSEM;
/* ret = vsprintf( szOut, fmt, (&fmt+1)); (but it didn't work, thus ... */
va_start (ap, fmt);
ret = vsprintf( szOut, fmt, ap);
va_end (ap);
if( fg_DebugCallback!=NULL && fg_DebugCallback(dbg_class, prio, szOut) ) {
FG_RELEASEDEBUGSEM;
return ret;
} else {
fprintf( fg_DebugOutput, szOut );
FG_RELEASEDEBUGSEM;
if( prio == FG_EXIT ) {
exit(0);
} else if( prio == FG_ABORT ) {
abort();
}
}
return ret;
}

View file

@ -1,155 +0,0 @@
/* -*- Mode: C++ -*-
*
* fg_debug.h -- Flight Gear debug utility functions
*
* Written by Paul Bleisch, started January 1998.
*
* Copyright (C) 1998 Paul Bleisch, pbleisch@acm.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.
*
**************************************************************************/
#error "use logstream"
#ifndef _FG_DEBUG_H
#define _FG_DEBUG_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
/* NB: To add a dbg_class, add it here, and add it to the structure in
fg_debug.c */
typedef enum {
FG_NONE = 0x00000000,
FG_TERRAIN = 0x00000001,
FG_ASTRO = 0x00000002,
FG_FLIGHT = 0x00000004,
FG_INPUT = 0x00000008,
FG_GL = 0x00000010,
FG_VIEW = 0x00000020,
FG_COCKPIT = 0x00000040,
FG_GENERAL = 0x00000080,
FG_MATH = 0x00000100,
FG_EVENT = 0x00000200,
FG_AIRCRAFT = 0x00000400,
FG_AUTOPILOT = 0x00000800,
FG_UNDEFD = 0x00001000, // For range checking
FG_ALL = 0xFFFFFFFF
} fgDebugClass;
/* NB: To add a priority, add it here. */
typedef enum {
FG_BULK, /* For frequent messages */
FG_DEBUG, /* Less frequent debug type messages */
FG_INFO, /* Informatory messages */
FG_WARN, /* Possible impending problem */
FG_ALERT, /* Very possible impending problem */
FG_EXIT, /* Problem (no core) */
FG_ABORT /* Abandon ship (core) */
} fgDebugPriority;
/* Initialize the debuggin stuff. */
void fgInitDebug( void );
/* fgPrintf
Expects:
class fgDebugClass mask for this message.
prio fgDebugPriority of this message.
fmt printf like string format
... var args for fmt
Returns:
number of items in fmt handled.
This function works like the standard C library function printf() with
the addition of message classes and priorities (see fgDebugClasses
and fgDebugPriorities). These additions allow us to classify messages
and disable sets of messages at runtime. Only messages with a prio
greater than or equal to fg_DebugPriority and in the current debug class
(fg_DebugClass) are printed.
*/
int fgPrintf( fgDebugClass dbg_class, fgDebugPriority prio, char *fmt, ... );
/* fgSetDebugLevels()
Expects:
dbg_class Bitmask representing classes to display.
prio Minimum priority of messages to display.
*/
void fgSetDebugLevels( fgDebugClass dbg_class, fgDebugPriority prio );
/* fgSetDebugOutput()
Expects:
file A FILE* to a stream to send messages to.
It is assumed the file stream is open and writable. The system
defaults to stderr. The current stream is flushed but not
closed.
*/
void fgSetDebugOutput( FILE *out );
/* fgRegisterDebugCallback
Expects:
callback A function that takes parameters as defined by the
fgDebugCallback type.
Returns:
a pointer to the previously registered callback (if any)
Install a user defined debug log callback. This callback is called w
whenever fgPrintf is called. The parameters passed to the callback are
defined above by fgDebugCallback. outstr is the string that is to be
printed. If callback returns nonzero, it is assumed that the message
was handled fully by the callback and **fgPrintf need do no further
processing of the message.** Only one callback may be installed at a
time.
*/
//typedef int (*fgDebugCallback)(fgDebugClass, fgDebugPriority, char *outstr);
//fgDebugCallback fgRegisterDebugCallback( fgDebugCallback callback );
typedef int (*fgDebugCallback)( int DebugClass, int DebugPriority, char *outstr);
fgDebugCallback fgRegisterDebugCallback( fgDebugCallback callback );
// Leave these alone. Access intended for fg_debug and command line processing.
//
extern fgDebugClass fg_DebugClass;
extern fgDebugPriority fg_DebugPriority;
extern FILE * fg_DebugOutput;
#ifdef __cplusplus
}
#endif
#endif /* _FG_DEBUG_H */

View file

@ -1,63 +0,0 @@
// Stream based logging mechanism.
//
// Written by Bernie Bright, 1998
//
// Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au
//
// 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$
#include "logstream.hxx"
bool logbuf::logging_enabled = true;
fgDebugClass logbuf::logClass = FG_NONE;
fgDebugPriority logbuf::logPriority = FG_INFO;
streambuf* logbuf::sbuf = NULL;
logbuf::logbuf()
{
// if ( sbuf == NULL )
// sbuf = cerr.rdbuf();
}
logbuf::~logbuf()
{
if ( sbuf )
sync();
}
void
logbuf::set_sb( streambuf* sb )
{
if ( sbuf )
sync();
sbuf = sb;
}
void
logbuf::set_log_level( fgDebugClass c, fgDebugPriority p )
{
logClass = c;
logPriority = p;
}
void
logstream::setLogLevels( fgDebugClass c, fgDebugPriority p )
{
logbuf::set_log_level( c, p );
}

View file

@ -1,220 +0,0 @@
// Stream based logging mechanism.
//
// Written by Bernie Bright, 1998
//
// Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au
//
// 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 _LOGSTREAM_H
#define _LOGSTREAM_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <Include/compiler.h>
#ifdef FG_HAVE_STD_INCLUDES
# include <streambuf>
# include <iostream>
#else
# include <iostream.h>
# include "Include/fg_traits.hxx"
#endif
#include "debug_types.h"
#ifndef FG_HAVE_NATIVE_SGI_COMPILERS
FG_USING_STD(streambuf);
FG_USING_STD(ostream);
FG_USING_STD(cerr);
FG_USING_STD(endl);
#endif
#ifdef __MWERKS__
# define cerr std::cerr
# define endl std::endl
FG_USING_STD(iostream);
#endif
//
// TODO:
//
// 1. Change output destination. Done.
// 2. Make logbuf thread safe.
// 3. Read environment for default debugClass and debugPriority.
//
//-----------------------------------------------------------------------------
//
// logbuf is an output-only streambuf with the ability to disable sets of
// messages at runtime. Only messages with priority >= logbuf::logPriority
// and debugClass == logbuf::logClass are output.
//
class logbuf : public streambuf
{
public:
#ifndef FG_HAVE_STD_INCLUDES
typedef char_traits<char> traits_type;
typedef char_traits<char>::int_type int_type;
typedef char_traits<char>::pos_type pos_type;
typedef char_traits<char>::off_type off_type;
#endif
// logbuf( streambuf* sb ) : sbuf(sb) {}
logbuf();
~logbuf();
// Is logging enabled?
bool enabled() { return logging_enabled; }
// Set the logging level of subsequent messages.
void set_log_state( fgDebugClass c, fgDebugPriority p );
// Set the global logging level.
static void set_log_level( fgDebugClass c, fgDebugPriority p );
//
void set_sb( streambuf* sb );
protected:
inline virtual int sync();
int_type overflow( int ch );
// int xsputn( const char* s, istreamsize n );
private:
// The streambuf used for actual output. Defaults to cerr.rdbuf().
static streambuf* sbuf;
static bool logging_enabled;
static fgDebugClass logClass;
static fgDebugPriority logPriority;
private:
// Not defined.
logbuf( const logbuf& );
void operator= ( const logbuf& );
};
inline int
logbuf::sync()
{
#ifdef FG_HAVE_STD_INCLUDES
return sbuf->pubsync();
#else
return sbuf->sync();
#endif
}
inline void
logbuf::set_log_state( fgDebugClass c, fgDebugPriority p )
{
logging_enabled = ((c & logClass) != 0 && p >= logPriority);
}
inline logbuf::int_type
logbuf::overflow( int c )
{
return logging_enabled ? sbuf->sputc(c) : (EOF == 0 ? 1: 0);
}
//-----------------------------------------------------------------------------
//
// logstream manipulator for setting the log level of a message.
//
struct loglevel
{
loglevel( fgDebugClass c, fgDebugPriority p )
: logClass(c), logPriority(p) {}
fgDebugClass logClass;
fgDebugPriority logPriority;
};
//-----------------------------------------------------------------------------
//
// A helper class that ensures a streambuf and ostream are constructed and
// destroyed in the correct order. The streambuf must be created before the
// ostream but bases are constructed before members. Thus, making this class
// a private base of logstream, declared to the left of ostream, we ensure the
// correct order of construction and destruction.
//
struct logstream_base
{
// logstream_base( streambuf* sb ) : lbuf(sb) {}
logstream_base() {}
logbuf lbuf;
};
//-----------------------------------------------------------------------------
//
//
//
class logstream : private logstream_base, public ostream
{
public:
// The default is to send messages to cerr.
logstream( ostream& out )
// : logstream_base(out.rdbuf()),
: logstream_base(),
ostream(&lbuf) { lbuf.set_sb(out.rdbuf());}
void set_output( ostream& out ) { lbuf.set_sb( out.rdbuf() ); }
// Set the global log class and priority level.
void setLogLevels( fgDebugClass c, fgDebugPriority p );
// Output operator to capture the debug level and priority of a message.
inline ostream& operator<< ( const loglevel& l );
};
inline ostream&
logstream::operator<< ( const loglevel& l )
{
lbuf.set_log_state( l.logClass, l.logPriority );
return *this;
}
//-----------------------------------------------------------------------------
//
// Return the one and only logstream instance.
// We use a function instead of a global object so we are assured that cerr
// has been initialised.
//
inline logstream&
fglog()
{
static logstream logstrm( cerr );
return logstrm;
}
#ifdef FG_NDEBUG
# define FG_LOG(C,P,M)
#elif defined( __MWERKS__ )
# define FG_LOG(C,P,M) ::fglog() << ::loglevel(C,P) << M << std::endl
#else
# define FG_LOG(C,P,M) fglog() << loglevel(C,P) << M << endl
#endif
#endif // _LOGSTREAM_H

View file

@ -1,34 +0,0 @@
#include <string>
#include "Debug/logstream.hxx"
int
main( int argc, char* argv[] )
{
fglog().setLogLevels( FG_ALL, FG_INFO );
FG_LOG( FG_TERRAIN, FG_BULK, "terrain::bulk" ); // shouldnt appear
FG_LOG( FG_TERRAIN, FG_DEBUG, "terrain::debug" ); // shouldnt appear
FG_LOG( FG_TERRAIN, FG_INFO, "terrain::info" );
FG_LOG( FG_TERRAIN, FG_WARN, "terrain::warn" );
FG_LOG( FG_TERRAIN, FG_ALERT, "terrain::alert" );
int i = 12345;
long l = 54321L;
double d = 3.14159;
string s = "Hello world!";
FG_LOG( FG_EVENT, FG_INFO, "event::info "
<< "i=" << i
<< ", l=" << l
<< ", d=" << d
<< ", d*l=" << d*l
<< ", s=\"" << s << "\"" );
// This shouldn't appear in log output:
FG_LOG( FG_EVENT, FG_DEBUG, "event::debug "
<< "- this should be seen - "
<< "d=" << d
<< ", s=\"" << s << "\"" );
return 0;
}

View file

@ -1,14 +0,0 @@
if ENABLE_UNIX_SERIAL
SERIAL_DIRS = Serial
else
SERIAL_DIRS =
endif
SUBDIRS = \
Bucket \
Debug \
Math \
Misc \
$(SERIAL_DIRS) \
XGL\
zlib

View file

@ -1,168 +0,0 @@
/* #include "HEADERS.h" */
/* Copyright 1988, Brown Computer Graphics Group. All Rights Reserved. */
/* --------------------------------------------------------------------------
* This file contains routines that perform geometry-related operations
* on matrices.
* -------------------------------------------------------------------------*/
#include <Math/mat3defs.h>
/* -------------------------- Static Routines ---------------------------- */
/* ------------------------- Internal Routines --------------------------- */
/* -------------------------- Public Routines ---------------------------- */
/*
* This takes a matrix used to transform points, and returns a corresponding
* matrix that can be used to transform direction vectors (between points).
*/
void
MAT3direction_matrix(register double (*result_mat)[4], register double (*mat)[4])
{
register int i;
MAT3copy(result_mat, mat);
for (i = 0; i < 4; i++) result_mat[i][3] = result_mat[3][i] = 0.0;
result_mat[3][3] = 1.0;
}
/*
* This takes a matrix used to transform points, and returns a corresponding
* matrix that can be used to transform vectors that must remain perpendicular
* to planes defined by the points. It is useful when you are transforming
* some object that has both points and normals in its definition, and you
* only have the transformation matrix for the points. This routine returns
* FALSE if the normal matrix is uncomputable. Otherwise, it returns TRUE.
*
* Spike sez: "This is the adjoint for the non-homogeneous part of the
* transformation."
*/
int
MAT3normal_matrix(register double (*result_mat)[4], register double (*mat)[4])
{
register int ret;
MAT3mat tmp_mat;
MAT3direction_matrix(result_mat, mat);
if ( (ret = MAT3invert(tmp_mat, tmp_mat)) ) {
MAT3transpose(result_mat, tmp_mat);
}
return(ret);
}
/*
* Sets the given matrix to be a scale matrix for the given vector of
* scale values.
*/
void
MAT3scale(double (*result_mat)[4], double *scale)
{
MAT3identity(result_mat);
result_mat[0][0] = scale[0];
result_mat[1][1] = scale[1];
result_mat[2][2] = scale[2];
}
/*
* Sets up a matrix for a rotation about an axis given by the line from
* (0,0,0) to axis, through an angle (in radians).
* Looking along the axis toward the origin, the rotation is counter-clockwise.
*/
#define SELECT .7071 /* selection constant (roughly .5*sqrt(2) */
void
MAT3rotate(double (*result_mat)[4], double *axis, double angle_in_radians)
{
MAT3vec naxis, /* Axis of rotation, normalized */
base2, /* 2nd unit basis vec, perp to axis */
base3; /* 3rd unit basis vec, perp to axis & base2 */
double dot;
MAT3mat base_mat, /* Change-of-basis matrix */
base_mat_trans; /* Inverse of c-o-b matrix */
register int i;
/* Step 1: extend { axis } to a basis for 3-space: { axis, base2, base3 }
* which is orthonormal (all three have unit length, and all three are
* mutually orthogonal). Also should be oriented, i.e. axis cross base2 =
* base3, rather than -base3.
*
* Method: Find a vector linearly independent from axis. For this we
* either use the y-axis, or, if that is too close to axis, the
* z-axis. 'Too close' means that the dot product is too near to 1.
*/
MAT3_COPY_VEC(naxis, axis);
MAT3_NORMALIZE_VEC(naxis, dot);
if (dot == 0.0) {
/* ERR_ERROR(MAT3_errid, ERR_SEVERE,
(ERR_S, "Zero-length axis vector given to MAT3rotate")); */
return;
}
MAT3perp_vec(base2, naxis, TRUE);
MAT3cross_product(base3, naxis, base2);
/* Set up the change-of-basis matrix, and its inverse */
MAT3identity(base_mat);
MAT3identity(base_mat_trans);
MAT3identity(result_mat);
for (i = 0; i < 3; i++){
base_mat_trans[i][0] = base_mat[0][i] = naxis[i];
base_mat_trans[i][1] = base_mat[1][i] = base2[i];
base_mat_trans[i][2] = base_mat[2][i] = base3[i];
}
/* If T(u) = uR, where R is base_mat, then T(x-axis) = naxis,
* T(y-axis) = base2, and T(z-axis) = base3. The inverse of base_mat is
* its transpose. OK?
*/
result_mat[1][1] = result_mat[2][2] = cos(angle_in_radians);
result_mat[2][1] = -(result_mat[1][2] = sin(angle_in_radians));
MAT3mult(result_mat, base_mat_trans, result_mat);
MAT3mult(result_mat, result_mat, base_mat);
}
/*
* Sets the given matrix to be a translation matrix for the given vector of
* translation values.
*/
void
MAT3translate(double (*result_mat)[4], double *trans)
{
MAT3identity(result_mat);
result_mat[3][0] = trans[0];
result_mat[3][1] = trans[1];
result_mat[3][2] = trans[2];
}
/*
* Sets the given matrix to be a shear matrix for the given x and y shear
* values.
*/
void
MAT3shear(double (*result_mat)[4], double xshear, double yshear)
{
MAT3identity(result_mat);
result_mat[2][0] = xshear;
result_mat[2][1] = yshear;
}

View file

@ -1,311 +0,0 @@
/* Copyright 1988, Brown Computer Graphics Group. All Rights Reserved. */
/* --------------------------------------------------------------------------
* This file contains routines that operate solely on matrices.
* -------------------------------------------------------------------------*/
#include <Math/mat3defs.h>
/* -------------------------- Static Routines ---------------------------- */
#define SMALL 1e-20 /* Small enough to be considered zero */
/*
* Shuffles rows in inverse of 3x3. See comment in MAT3_inv3_second_col().
*/
static void
MAT3_inv3_swap( register double inv[3][3], int row0, int row1, int row2)
{
register int i, tempi;
double temp;
#define SWAP_ROWS(a, b) \
for (i = 0; i < 3; i++) SWAP(inv[a][i], inv[b][i], temp); \
SWAP(a, b, tempi)
if (row0 != 0){
if (row1 == 0) {
SWAP_ROWS(row0, row1);
}
else {
SWAP_ROWS(row0, row2);
}
}
if (row1 != 1) {
SWAP_ROWS(row1, row2);
}
}
/*
* Does Gaussian elimination on second column.
*/
static int
MAT3_inv3_second_col (register double source[3][3], register double inv[3][3], int row0)
{
register int row1, row2, i1, i2, i;
double temp;
double a, b;
/* Find which row to use */
if (row0 == 0) i1 = 1, i2 = 2;
else if (row0 == 1) i1 = 0, i2 = 2;
else i1 = 0, i2 = 1;
/* Find which is larger in abs. val.:the entry in [i1][1] or [i2][1] */
/* and use that value for pivoting. */
a = source[i1][1]; if (a < 0) a = -a;
b = source[i2][1]; if (b < 0) b = -b;
if (a > b) row1 = i1;
else row1 = i2;
row2 = (row1 == i1 ? i2 : i1);
/* Scale row1 in source */
if ((source[row1][1] < SMALL) && (source[row1][1] > -SMALL)) return(FALSE);
temp = 1.0 / source[row1][1];
source[row1][1] = 1.0;
source[row1][2] *= temp; /* source[row1][0] is zero already */
/* Scale row1 in inv */
inv[row1][row1] = temp; /* it used to be a 1.0 */
inv[row1][row0] *= temp;
/* Clear column one, source, and make corresponding changes in inv */
for (i = 0; i < 3; i++) if (i != row1) { /* for i = all rows but row1 */
temp = -source[i][1];
source[i][1] = 0.0;
source[i][2] += temp * source[row1][2];
inv[i][row1] = temp * inv[row1][row1];
inv[i][row0] += temp * inv[row1][row0];
}
/* Scale row2 in source */
if ((source[row2][2] < SMALL) && (source[row2][2] > -SMALL)) return(FALSE);
temp = 1.0 / source[row2][2];
source[row2][2] = 1.0; /* source[row2][*] is zero already */
/* Scale row2 in inv */
inv[row2][row2] = temp; /* it used to be a 1.0 */
inv[row2][row0] *= temp;
inv[row2][row1] *= temp;
/* Clear column one, source, and make corresponding changes in inv */
for (i = 0; i < 3; i++) if (i != row2) { /* for i = all rows but row2 */
temp = -source[i][2];
source[i][2] = 0.0;
inv[i][row0] += temp * inv[row2][row0];
inv[i][row1] += temp * inv[row2][row1];
inv[i][row2] += temp * inv[row2][row2];
}
/*
* Now all is done except that the inverse needs to have its rows shuffled.
* row0 needs to be moved to inv[0][*], row1 to inv[1][*], etc.
*
* We *didn't* do the swapping before the elimination so that we could more
* easily keep track of what ops are needed to be done in the inverse.
*/
MAT3_inv3_swap(inv, row0, row1, row2);
return(TRUE);
}
/*
* Fast inversion routine for 3 x 3 matrices. - Written by jfh.
*
* This takes 30 multiplies/divides, as opposed to 39 for Cramer's Rule.
* The algorithm consists of performing fast gaussian elimination, by never
* doing any operations where the result is guaranteed to be zero, or where
* one operand is guaranteed to be zero. This is done at the cost of clarity,
* alas.
*
* Returns 1 if the inverse was successful, 0 if it failed.
*/
static int
MAT3_invert3 (register double source[3][3], register double inv[3][3])
{
register int i, row0;
double temp;
double a, b, c;
inv[0][0] = inv[1][1] = inv[2][2] = 1.0;
inv[0][1] = inv[0][2] = inv[1][0] = inv[1][2] = inv[2][0] = inv[2][1] = 0.0;
/* attempt to find the largest entry in first column to use as pivot */
a = source[0][0]; if (a < 0) a = -a;
b = source[1][0]; if (b < 0) b = -b;
c = source[2][0]; if (c < 0) c = -c;
if (a > b) {
if (a > c) row0 = 0;
else row0 = 2;
}
else {
if (b > c) row0 = 1;
else row0 = 2;
}
/* Scale row0 of source */
if ((source[row0][0] < SMALL) && (source[row0][0] > -SMALL)) return(FALSE);
temp = 1.0 / source[row0][0];
source[row0][0] = 1.0;
source[row0][1] *= temp;
source[row0][2] *= temp;
/* Scale row0 of inverse */
inv[row0][row0] = temp; /* other entries are zero -- no effort */
/* Clear column zero of source, and make corresponding changes in inverse */
for (i = 0; i < 3; i++) if (i != row0) { /* for i = all rows but row0 */
temp = -source[i][0];
source[i][0] = 0.0;
source[i][1] += temp * source[row0][1];
source[i][2] += temp * source[row0][2];
inv[i][row0] = temp * inv[row0][row0];
}
/*
* We've now done gaussian elimination so that the source and
* inverse look like this:
*
* 1 * * * 0 0
* 0 * * * 1 0
* 0 * * * 0 1
*
* We now proceed to do elimination on the second column.
*/
if (! MAT3_inv3_second_col(source, inv, row0)) return(FALSE);
return(TRUE);
}
/*
* Finds a new pivot for a non-simple 4x4. See comments in MAT3invert().
*/
static int
MAT3_inv4_pivot (register MAT3mat src, MAT3vec r, double *s, int *swap)
{
register int i, j;
double temp, max;
*swap = -1;
if (MAT3_IS_ZERO(src[3][3])) {
/* Look for a different pivot element: one with largest abs value */
max = 0.0;
for (i = 0; i < 4; i++) {
if (src[i][3] > max) max = src[*swap = i][3];
else if (src[i][3] < -max) max = -src[*swap = i][3];
}
/* No pivot element available ! */
if (*swap < 0) return(FALSE);
else for (j = 0; j < 4; j++) SWAP(src[*swap][j], src[3][j], temp);
}
MAT3_SET_VEC (r, -src[0][3], -src[1][3], -src[2][3]);
*s = 1.0 / src[3][3];
src[0][3] = src[1][3] = src[2][3] = 0.0;
src[3][3] = 1.0;
MAT3_SCALE_VEC(src[3], src[3], *s);
for (i = 0; i < 3; i++) {
src[0][i] += r[0] * src[3][i];
src[1][i] += r[1] * src[3][i];
src[2][i] += r[2] * src[3][i];
}
return(TRUE);
}
/* ------------------------- Internal Routines --------------------------- */
/* -------------------------- Public Routines ---------------------------- */
/*
* This returns the inverse of the given matrix. The result matrix
* may be the same as the one to invert.
*
* Fast inversion routine for 4 x 4 matrices, written by jfh.
*
* Returns 1 if the inverse was successful, 0 if it failed.
*
* This routine has been specially tweaked to notice the following:
* If the matrix has the form
* * * * 0
* * * * 0
* * * * 0
* * * * 1
*
* (as do many matrices in graphics), then we compute the inverse of
* the upper left 3x3 matrix and use this to find the general inverse.
*
* In the event that the right column is not 0-0-0-1, we do gaussian
* elimination to make it so, then use the 3x3 inverse, and then do
* our gaussian elimination.
*/
int
MAT3invert(double (*result_mat)[4], double (*mat)[4])
{
MAT3mat src, inv;
register int i, j, simple;
double m[3][3], inv3[3][3], s, temp;
MAT3vec r, t;
int swap;
MAT3copy(src, mat);
MAT3identity(inv);
/* If last column is not (0,0,0,1), use special code */
simple = (mat[0][3] == 0.0 && mat[1][3] == 0.0 &&
mat[2][3] == 0.0 && mat[3][3] == 1.0);
if (! simple && ! MAT3_inv4_pivot(src, r, &s, &swap)) return(FALSE);
MAT3_COPY_VEC(t, src[3]); /* Translation vector */
/* Copy upper-left 3x3 matrix */
for (i = 0; i < 3; i++) for (j = 0; j < 3; j++) m[i][j] = src[i][j];
if (! MAT3_invert3(m, inv3)) return(FALSE);
for (i = 0; i < 3; i++) for (j = 0; j < 3; j++) inv[i][j] = inv3[i][j];
for (i = 0; i < 3; i++) for (j = 0; j < 3; j++)
inv[3][i] -= t[j] * inv3[j][i];
if (! simple) {
/* We still have to undo our gaussian elimination from earlier on */
/* add r0 * first col to last col */
/* add r1 * 2nd col to last col */
/* add r2 * 3rd col to last col */
for (i = 0; i < 4; i++) {
inv[i][3] += r[0] * inv[i][0] + r[1] * inv[i][1] + r[2] * inv[i][2];
inv[i][3] *= s;
}
if (swap >= 0)
for (i = 0; i < 4; i++) SWAP(inv[i][swap], inv[i][3], temp);
}
MAT3copy(result_mat, inv);
return(TRUE);
}

View file

@ -1,120 +0,0 @@
/* #include "HEADERS.h" */
/* Copyright 1988, Brown Computer Graphics Group. All Rights Reserved. */
/* --------------------------------------------------------------------------
* This file contains routines that operate solely on matrices.
* -------------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef WIN32
# ifndef HAVE_STL_SGI_PORT
# ifdef __BORLANDC__
# include <mem.h>
# else
# include <memory.h> /* required for memset() and memcpy() */
# endif
# endif
#endif
#include <string.h>
#include <Math/mat3defs.h>
MAT3mat identityMatrix = {
{ 1.0, 0.0, 0.0, 0.0 },
{ 0.0, 1.0, 0.0, 0.0 },
{ 0.0, 0.0, 1.0, 0.0 },
{ 0.0, 0.0, 0.0, 1.0 }
};
/* #include "macros.h" */
/* -------------------------- Static Routines ---------------------------- */
/* ------------------------- Internal Routines --------------------------- */
/* -------------------------- Public Routines ---------------------------- */
#if !defined( USE_XTRA_MAT3_INLINES )
/*
* This multiplies two matrices, producing a third, which may the same as
* either of the first two.
*/
void
MAT3mult (double (*result_mat)[4], register double (*mat1)[4], register double (*mat2)[4])
{
register int i, j;
MAT3mat tmp_mat;
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
tmp_mat[i][j] = (mat1[i][0] * mat2[0][j] +
mat1[i][1] * mat2[1][j] +
mat1[i][2] * mat2[2][j] +
mat1[i][3] * mat2[3][j]);
MAT3copy (result_mat, tmp_mat);
}
#endif // !defined( USE_XTRA_MAT3_INLINES )
/*
* This returns the transpose of a matrix. The result matrix may be
* the same as the one to transpose.
*/
void
MAT3transpose (double (*result_mat)[4], register double (*mat)[4])
{
register int i, j;
MAT3mat tmp_mat;
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
tmp_mat[i][j] = mat[j][i];
MAT3copy (result_mat, tmp_mat);
}
/*
* This prints the given matrix to the given file pointer.
*/
void
MAT3print(double (*mat)[4], FILE *fp)
{
MAT3print_formatted(mat, fp, CNULL, CNULL, CNULL, CNULL);
}
/*
* This prints the given matrix to the given file pointer.
* use the format string to pass to fprintf. head and tail
* are printed at the beginning and end of each line.
*/
void
MAT3print_formatted(double (*mat)[4], FILE *fp, char *title, char *head, char *format, char *tail)
{
register int i, j;
/* This is to allow this to be called easily from a debugger */
if (fp == NULL) fp = stderr;
if (title == NULL) title = "MAT3 matrix:\n";
if (head == NULL) head = " ";
if (format == NULL) format = "%#8.4lf ";
if (tail == NULL) tail = "\n";
(void) fprintf(fp, title);
for (i = 0; i < 4; i++) {
(void) fprintf(fp, head);
for (j = 0; j < 4; j++) (void) fprintf(fp, format, mat[i][j]);
(void) fprintf(fp, tail);
}
}

View file

@ -1,154 +0,0 @@
/* Copyright 1988, Brown Computer Graphics Group. All Rights Reserved. */
/* --------------------------------------------------------------------------
* This file contains routines that operate on matrices and vectors, or
* vectors and vectors.
* -------------------------------------------------------------------------*/
/* #include "sphigslocal.h" */
/* -------------------------- Static Routines ---------------------------- */
/* ------------------------- Internal Routines --------------------------- */
/* -------------------------- Public Routines ---------------------------- */
/*
* Multiplies a vector by a matrix, setting the result vector.
* It assumes all homogeneous coordinates are 1.
* The two vectors involved may be the same.
*/
#include <Math/mat3.h>
#ifndef TRUE
# define TRUE 1
#endif
#ifndef FALSE
# define FALSE 0
#endif
#if !defined( USE_XTRA_MAT3_INLINES )
void
MAT3mult_vec(double *result_vec, register double *vec, register double (*mat)[4])
{
MAT3vec tempvec;
register double *temp = tempvec;
temp[0] = vec[0] * mat[0][0] + vec[1] * mat[1][0] +
vec[2] * mat[2][0] + mat[3][0];
temp[1] = vec[0] * mat[0][1] + vec[1] * mat[1][1] +
vec[2] * mat[2][1] + mat[3][1];
temp[2] = vec[0] * mat[0][2] + vec[1] * mat[1][2] +
vec[2] * mat[2][2] + mat[3][2];
MAT3_COPY_VEC(result_vec, temp);
}
#endif // !defined( USE_XTRA_MAT3_INLINES )
/*
* Multiplies a vector of size 4 by a matrix, setting the result vector.
* The fourth element of the vector is the homogeneous coordinate, which
* may or may not be 1. If the "normalize" parameter is TRUE, then the
* result vector will be normalized so that the homogeneous coordinate is 1.
* The two vectors involved may be the same.
* This returns zero if the vector was to be normalized, but couldn't be.
*/
int
MAT3mult_hvec(double *result_vec, register double *vec, register double (*mat)[4], int normalize)
{
MAT3hvec tempvec;
double norm_fac;
register double *temp = tempvec;
register int ret = TRUE;
temp[0] = vec[0] * mat[0][0] + vec[1] * mat[1][0] +
vec[2] * mat[2][0] + vec[3] * mat[3][0];
temp[1] = vec[0] * mat[0][1] + vec[1] * mat[1][1] +
vec[2] * mat[2][1] + vec[3] * mat[3][1];
temp[2] = vec[0] * mat[0][2] + vec[1] * mat[1][2] +
vec[2] * mat[2][2] + vec[3] * mat[3][2];
temp[3] = vec[0] * mat[0][3] + vec[1] * mat[1][3] +
vec[2] * mat[2][3] + vec[3] * mat[3][3];
/* Normalize if asked for, possible, and necessary */
if (normalize) {
if (MAT3_IS_ZERO(temp[3])) {
#ifndef THINK_C
fprintf (stderr,
"Can't normalize vector: homogeneous coordinate is 0");
#endif
ret = FALSE;
}
else {
norm_fac = 1.0 / temp[3];
MAT3_SCALE_VEC(result_vec, temp, norm_fac);
result_vec[3] = 1.0;
}
}
else MAT3_COPY_HVEC(result_vec, temp);
return(ret);
}
#if !defined( USE_XTRA_MAT3_INLINES )
/*
* Sets the first vector to be the cross-product of the last two vectors.
*/
void
MAT3cross_product(double *result_vec, register double *vec1, register double *vec2)
{
MAT3vec tempvec;
register double *temp = tempvec;
temp[0] = vec1[1] * vec2[2] - vec1[2] * vec2[1];
temp[1] = vec1[2] * vec2[0] - vec1[0] * vec2[2];
temp[2] = vec1[0] * vec2[1] - vec1[1] * vec2[0];
MAT3_COPY_VEC(result_vec, temp);
}
#endif // !defined( USE_XTRA_MAT3_INLINES )
/*
* Finds a vector perpendicular to vec and stores it in result_vec.
* Method: take any vector (we use <0,1,0>) and subtract the
* portion of it pointing in the vec direction. This doesn't
* work if vec IS <0,1,0> or is very near it. So if this is
* the case, use <0,0,1> instead.
* If "is_unit" is TRUE, the given vector is assumed to be unit length.
*/
#define SELECT .7071 /* selection constant (roughly .5*sqrt(2) */
void
MAT3perp_vec(double *result_vec, double *vec, int is_unit)
{
MAT3vec norm;
double dot;
MAT3_SET_VEC(result_vec, 0.0, 1.0, 0.0);
MAT3_COPY_VEC(norm, vec);
if (! is_unit) MAT3_NORMALIZE_VEC(norm, dot);
/* See if vector is too close to <0,1,0>. If so, use <0,0,1> */
if ((dot = MAT3_DOT_PRODUCT(norm, result_vec)) > SELECT || dot < -SELECT) {
result_vec[1] = 0.0;
result_vec[2] = 1.0;
dot = MAT3_DOT_PRODUCT(norm, result_vec);
}
/* Subtract off non-perpendicular part */
result_vec[0] -= dot * norm[0];
result_vec[1] -= dot * norm[1];
result_vec[2] -= dot * norm[2];
/* Make result unit length */
MAT3_NORMALIZE_VEC(result_vec, dot);
}

View file

@ -1,17 +0,0 @@
noinst_LIBRARIES = libMath.a
libMath_a_SOURCES = \
MAT3geom.c \
MAT3inv.c \
MAT3mat.c \
MAT3vec.c \
fg_geodesy.cxx fg_geodesy.hxx \
fg_random.c fg_random.h \
interpolater.cxx interpolater.hxx \
leastsqs.cxx leastsqs.hxx \
mat3.h mat3defs.h mat3err.h \
point3d.hxx \
polar3d.cxx polar3d.hxx \
vector.cxx vector.hxx
INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib -I$(top_builddir)/Simulator

View file

@ -1,211 +0,0 @@
// fg_geodesy.cxx -- routines to convert between geodetic and geocentric
// coordinate systems.
//
// Copied and adapted directly from LaRCsim/ls_geodesy.c
//
// See below for the complete original LaRCsim comments.
//
// $Id$
#include "Include/compiler.h"
#ifdef FG_HAVE_STD_INCLUDES
# include <cmath>
# include <cerrno>
#else
# include <math.h>
# include <errno.h>
#endif
#include <Debug/logstream.hxx>
#include <Include/fg_constants.h>
#include <Math/fg_geodesy.hxx>
#include <Math/point3d.hxx>
#ifndef FG_HAVE_NATIVE_SGI_COMPILERS
FG_USING_STD(cout);
#endif
// ONE_SECOND is pi/180/60/60, or about 100 feet at earths' equator
#define ONE_SECOND 4.848136811E-6
// fgGeocToGeod(lat_geoc, radius, *lat_geod, *alt, *sea_level_r)
// INPUTS:
// lat_geoc Geocentric latitude, radians, + = North
// radius C.G. radius to earth center (meters)
//
// OUTPUTS:
// lat_geod Geodetic latitude, radians, + = North
// alt C.G. altitude above mean sea level (meters)
// sea_level_r radius from earth center to sea level at
// local vertical (surface normal) of C.G. (meters)
void fgGeocToGeod( double lat_geoc, double radius, double
*lat_geod, double *alt, double *sea_level_r )
{
double t_lat, x_alpha, mu_alpha, delt_mu, r_alpha, l_point, rho_alpha;
double sin_mu_a, denom,delt_lambda, lambda_sl, sin_lambda_sl;
if( ( (FG_PI_2 - lat_geoc) < ONE_SECOND ) // near North pole
|| ( (FG_PI_2 + lat_geoc) < ONE_SECOND ) ) // near South pole
{
*lat_geod = lat_geoc;
*sea_level_r = EQUATORIAL_RADIUS_M*E;
*alt = radius - *sea_level_r;
} else {
t_lat = tan(lat_geoc);
x_alpha = E*EQUATORIAL_RADIUS_M/sqrt(t_lat*t_lat + E*E);
double tmp = RESQ_M - x_alpha * x_alpha;
if ( tmp < 0.0 ) { tmp = 0.0; }
mu_alpha = atan2(sqrt(tmp),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);
// check for domain error
if ( errno == EDOM ) {
FG_LOG( FG_GENERAL, FG_ALERT, "Domain ERROR in fgGeocToGeod!!!!" );
*alt = 0.0;
}
denom = sqrt(1-EPS*EPS*sin_mu_a*sin_mu_a);
rho_alpha = EQUATORIAL_RADIUS_M*(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_M / (1 + ((1/(E*E))-1)*sin_lambda_sl*sin_lambda_sl));
// check for domain error
if ( errno == EDOM ) {
FG_LOG( FG_GENERAL, FG_ALERT, "Domain ERROR in fgGeocToGeod!!!!" );
*sea_level_r = 0.0;
}
}
}
// fgGeodToGeoc( lat_geod, alt, *sl_radius, *lat_geoc )
// INPUTS:
// lat_geod Geodetic latitude, radians, + = North
// alt C.G. altitude above mean sea level (meters)
//
// OUTPUTS:
// sl_radius SEA LEVEL radius to earth center (meters)
// (add Altitude to get true distance from earth center.
// lat_geoc Geocentric latitude, radians, + = North
//
void fgGeodToGeoc( double lat_geod, double alt, double *sl_radius,
double *lat_geoc )
{
double 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_M / (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 );
}
/***************************************************************************
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$
* 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.
--------------------------------------------------------------------------*/

View file

@ -1,162 +0,0 @@
// fg_geodesy.hxx -- routines to convert between geodetic and geocentric
// coordinate systems.
//
// Copied and adapted directly from LaRCsim/ls_geodesy.c
//
// See below for the complete original LaRCsim comments.
//
// $Id$
#ifndef _FG_GEODESY_HXX
#define _FG_GEODESY_HXX
#ifndef __cplusplus
# error This library requires C++
#endif
#include <Math/point3d.hxx>
#include <Math/polar3d.hxx>
// fgGeocToGeod(lat_geoc, radius, *lat_geod, *alt, *sea_level_r)
// INPUTS:
// lat_geoc Geocentric latitude, radians, + = North
// radius C.G. radius to earth center (meters)
//
// OUTPUTS:
// lat_geod Geodetic latitude, radians, + = North
// alt C.G. altitude above mean sea level (meters)
// sea_level_r radius from earth center to sea level at
// local vertical (surface normal) of C.G. (meters)
void fgGeocToGeod( double lat_geoc, double radius, double
*lat_geod, double *alt, double *sea_level_r );
// fgGeodToGeoc( lat_geod, alt, *sl_radius, *lat_geoc )
// INPUTS:
// lat_geod Geodetic latitude, radians, + = North
// alt C.G. altitude above mean sea level (meters)
//
// OUTPUTS:
// sl_radius SEA LEVEL radius to earth center (meters)
// (add Altitude to get true distance from earth center.
// lat_geoc Geocentric latitude, radians, + = North
//
void fgGeodToGeoc( double lat_geod, double alt, double *sl_radius,
double *lat_geoc );
// convert a geodetic point lon(radians), lat(radians), elev(meter) to
// a cartesian point
inline Point3D fgGeodToCart(const Point3D& geod) {
double gc_lon, gc_lat, sl_radius;
// printf("A geodetic point is (%.2f, %.2f, %.2f)\n",
// geod[0], geod[1], geod[2]);
gc_lon = geod.lon();
fgGeodToGeoc(geod.lat(), geod.radius(), &sl_radius, &gc_lat);
// printf("A geocentric point is (%.2f, %.2f, %.2f)\n", gc_lon,
// gc_lat, sl_radius+geod[2]);
Point3D pp = Point3D( gc_lon, gc_lat, sl_radius + geod.radius());
return fgPolarToCart3d(pp);
}
/***************************************************************************
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$
* 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.
--------------------------------------------------------------------------*/
#endif // _FG_GEODESY_HXX

View file

@ -1,71 +0,0 @@
// fg_random.c -- routines to handle random number generation
//
// Written by Curtis Olson, started July 1997.
//
// Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h> // for random(), srandom()
#include <time.h> // for time() to seed srandom()
#include "fg_random.h"
#ifndef HAVE_RAND
# ifdef sgi
# undef RAND_MAX
# define RAND_MAX 2147483647
# endif
#endif
#ifdef __SUNPRO_CC
extern "C" {
long int random(void);
void srandom(unsigned int seed);
}
#endif
// Seed the random number generater with time() so we don't see the
// same sequence every time
void fg_srandom(void) {
// fgPrintf( FG_MATH, FG_INFO, "Seeding random number generater\n");
#ifdef HAVE_RAND
srand(time(NULL));
#else
srandom(time(NULL));
#endif
}
// return a random number between [0.0, 1.0)
double fg_random(void) {
#ifdef HAVE_RAND
return(rand() / (double)RAND_MAX);
#else
return(random() / (double)RAND_MAX);
#endif
}

View file

@ -1,48 +0,0 @@
// fg_random.h -- routines to handle random number generation
//
// Written by Curtis Olson, started July 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$
#ifndef _FG_RANDOM_H
#define _FG_RANDOM_H
#ifdef __cplusplus
extern "C" {
#endif
// Seed the random number generater with time() so we don't see the
// same sequence every time
void fg_srandom(void);
// return a random number between [0.0, 1.0)
double fg_random(void);
#ifdef __cplusplus
}
#endif
#endif // _FG_RANDOM_H

View file

@ -1,30 +0,0 @@
#include <Include/fg_constants.h>
#include <Math/fg_geodesy.h>
#include <stdio.h>
void
main( void )
{
double Lon, Alt, sl_radius;
double geodetic_Lat;
double geocentric_Lat;
Lon = -87.75 * DEG_TO_RAD;
geodetic_Lat = 41.83 * DEG_TO_RAD;
Alt = 1.5; /* km */
printf("Geodetic position = (%.8f, %.8f, %.8f)\n", Lon, geodetic_Lat, Alt);
fgGeodToGeoc( geodetic_Lat, Alt, &sl_radius, &geocentric_Lat );
printf("Geocentric position = (%.8f, %.8f, %.8f)\n", Lon, geocentric_Lat,
sl_radius + Alt);
printf("new sl_radius = %.8f\n", sl_radius);
fgGeocToGeod( geocentric_Lat, sl_radius + Alt, &geodetic_Lat,
&Alt, &sl_radius );
printf("Geodetic position = (%.8f, %.8f, %.8f)\n", Lon, geodetic_Lat, Alt);
printf("new sl_radius = %.8f\n", sl_radius);
}

View file

@ -1,107 +0,0 @@
//
// interpolater.cxx -- routines to handle linear interpolation from a table of
// x,y The table must be sorted by "x" in ascending order
//
// 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$
#include <Include/compiler.h>
#ifdef __MWERKS__
#include <stdlib.h> // for exit()
#endif
#include STL_STRING
#include <Debug/logstream.hxx>
#include <Include/fg_zlib.h>
#include <Misc/fgstream.hxx>
#include "interpolater.hxx"
// Constructor -- loads the interpolation table from the specified
// file
fgINTERPTABLE::fgINTERPTABLE( const string& file ) {
FG_LOG( FG_MATH, FG_INFO, "Initializing Interpolator for " << file );
fg_gzifstream in( file );
if ( !in ) {
FG_LOG( FG_GENERAL, FG_ALERT, "Cannot open file: " << file );
exit(-1);
}
size = 0;
in >> skipcomment;
while ( in ) {
if ( size < MAX_TABLE_SIZE ) {
in >> table[size][0] >> table[size][1];
size++;
} else {
FG_LOG( FG_MATH, FG_ALERT,
"fgInterpolateInit(): Exceed max table size = "
<< MAX_TABLE_SIZE );
exit(-1);
}
}
}
// Given an x value, linearly interpolate the y value from the table
double fgINTERPTABLE::interpolate(double x) {
int i;
double y;
i = 0;
while ( (x > table[i][0]) && (i < size) ) {
i++;
}
// printf ("i = %d ", i);
if ( (i == 0) && (x < table[0][0]) ) {
FG_LOG( FG_MATH, FG_ALERT,
"fgInterpolateInit(): lookup error, x to small = " << x );
return(0.0);
}
if ( x > table[i][0] ) {
FG_LOG( FG_MATH, FG_ALERT,
"fgInterpolateInit(): lookup error, x to big = " << x );
return(0.0);
}
// y = y1 + (y0 - y1)(x - x1) / (x0 - x1)
y = table[i][1] +
( (table[i-1][1] - table[i][1]) *
(x - table[i][0]) ) /
(table[i-1][0] - table[i][0]);
return(y);
}
// Destructor
fgINTERPTABLE::~fgINTERPTABLE( void ) {
}

Some files were not shown because too many files have changed in this diff Show more