1999-02-15 00:38:46 +00:00
|
|
|
%
|
|
|
|
% `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}
|
|
|
|
|
1999-03-13 21:42:37 +00:00
|
|
|
This library has routines to parse the 3 arcsec DEM file format, and
|
|
|
|
output a square section corresponding to a specified tile.
|
1999-02-15 00:38:46 +00:00
|
|
|
|
1999-03-13 21:42:37 +00:00
|
|
|
\subsubsection{Polygon}
|
1999-02-15 00:38:46 +00:00
|
|
|
|
1999-03-13 21:42:37 +00:00
|
|
|
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.
|
1999-02-15 00:38:46 +00:00
|
|
|
|
1999-03-13 21:42:37 +00:00
|
|
|
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.
|
1999-02-15 00:38:46 +00:00
|
|
|
|
|
|
|
\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.
|
|
|
|
|
1999-03-08 21:59:52 +00:00
|
|
|
\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.
|
|
|
|
|
1999-02-15 00:38:46 +00:00
|
|
|
\subsection{Preprocessing tools}
|
|
|
|
|
1999-03-08 21:59:52 +00:00
|
|
|
The preprocessing tools are responsible for inputing raw world data,
|
1999-03-13 21:42:37 +00:00
|
|
|
clipping it to the appropriate scenery tiles, and outputing it into
|
|
|
|
the workspace directory tree.
|
1999-03-08 21:59:52 +00:00
|
|
|
|
|
|
|
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.
|
|
|
|
|
1999-03-13 21:42:37 +00:00
|
|
|
\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.)
|
|
|
|
|
1999-02-15 00:38:46 +00:00
|
|
|
\subsubsection{GenAirports}
|
|
|
|
|
|
|
|
This tools inputs an ascii specification of the airports of the world
|
|
|
|
that looks like the following:
|
|
|
|
|
|
|
|
\begin{verbatim}
|
1999-03-21 15:12:51 +00:00
|
|
|
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
|
1999-02-15 00:38:46 +00:00
|
|
|
\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.
|
|
|
|
|
1999-03-13 21:42:37 +00:00
|
|
|
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.
|
|
|
|
|
1999-02-15 00:38:46 +00:00
|
|
|
\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.
|
|
|
|
|
1999-03-08 21:59:52 +00:00
|
|
|
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.
|
1999-02-15 00:38:46 +00:00
|
|
|
|
|
|
|
\subsection{Scenery generation tools}
|
|
|
|
|
|
|
|
Issues:
|
|
|
|
|
1999-03-13 21:42:37 +00:00
|
|
|
\begin{itemize}
|
|
|
|
\item Combining height data, polygon data.
|
1999-02-15 00:38:46 +00:00
|
|
|
|
1999-03-13 21:42:37 +00:00
|
|
|
\item Triangulating / tri-stripping / tri-fanning.
|
1999-02-15 00:38:46 +00:00
|
|
|
|
1999-03-13 21:42:37 +00:00
|
|
|
\item Matching vertices and normals along edges and at corners.
|
1999-02-15 00:38:46 +00:00
|
|
|
|
1999-03-13 21:42:37 +00:00
|
|
|
\item Resolving conflicts in data:
|
1999-02-15 00:38:46 +00:00
|
|
|
overlapping polygon areas.
|
|
|
|
conflicting height data between airports and DEM data
|
1999-03-13 21:42:37 +00:00
|
|
|
\end{itemize}
|
1999-02-15 00:38:46 +00:00
|
|
|
|
|
|
|
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.)
|
|
|
|
|
1999-03-21 15:12:51 +00:00
|
|
|
For each tile create a fitted set of ``important height'' points from
|
|
|
|
the original regular grid of data.
|
|
|
|
|
1999-02-15 00:38:46 +00:00
|
|
|
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
|
1999-03-21 15:12:51 +00:00
|
|
|
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. :-)
|
1999-02-15 00:38:46 +00:00
|
|
|
|
|
|
|
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.
|
|
|
|
|
1999-03-13 21:42:37 +00:00
|
|
|
\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.
|
|
|
|
|
1999-02-15 00:38:46 +00:00
|
|
|
% \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}
|
|
|
|
|
|
|
|
|
|
|
|
%------------------------------------------------------------------------
|
|
|
|
% $Log$
|
1999-03-21 15:12:51 +00:00
|
|
|
% Revision 1.4 1999/03/21 15:12:51 curt
|
|
|
|
% Updated to reflect current scenery progress.
|
|
|
|
%
|
1999-03-13 21:42:37 +00:00
|
|
|
% Revision 1.3 1999/03/13 21:42:37 curt
|
|
|
|
% Updated to match current scenery generation tools progress.
|
|
|
|
%
|
1999-03-08 21:59:52 +00:00
|
|
|
% Revision 1.2 1999/03/08 21:59:52 curt
|
|
|
|
% Updated based on current efforts.
|
|
|
|
%
|
1999-02-15 00:38:46 +00:00
|
|
|
% Revision 1.1 1999/02/15 00:38:46 curt
|
|
|
|
% Initial revision.
|
|
|
|
%
|