Compare commits
127 Commits
RELEASE_0_
...
RELEASE_0_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0ce0684dae | ||
|
|
377eb4782a | ||
|
|
f1a79e6b9f | ||
|
|
007a1e4659 | ||
|
|
fcb873b6dd | ||
|
|
a66d1ad855 | ||
|
|
76a5950f19 | ||
|
|
b7a91bdb03 | ||
|
|
e4bbc5c50b | ||
|
|
b481ccd749 | ||
|
|
e7b9e55599 | ||
|
|
05eaa7135f | ||
|
|
d063b319e8 | ||
|
|
be4fd56660 | ||
|
|
a406a3c00b | ||
|
|
c7295da5eb | ||
|
|
505f561e1c | ||
|
|
7bd8477fa1 | ||
|
|
36ef15940e | ||
|
|
f2ba7aefa6 | ||
|
|
73b58b0e87 | ||
|
|
6ce4f096b2 | ||
|
|
3e7ece7f5f | ||
|
|
48a219473e | ||
|
|
887ffd102f | ||
|
|
b1a719dd4c | ||
|
|
b4efe8f374 | ||
|
|
03f844d4be | ||
|
|
a212589865 | ||
|
|
29dfc5bd3c | ||
|
|
a6ac06c47a | ||
|
|
4d914db1db | ||
|
|
68572f106d | ||
|
|
c5ca4db94e | ||
|
|
3980f08cc5 | ||
|
|
f93fa4b613 | ||
|
|
06f2dba92c | ||
|
|
30a14741c9 | ||
|
|
2f39b688f4 | ||
|
|
724a2ef83b | ||
|
|
f7e0e46143 | ||
|
|
83acb47295 | ||
|
|
e5282caea5 | ||
|
|
6a481eed36 | ||
|
|
e145f903de | ||
|
|
2afd1c8663 | ||
|
|
948d02055d | ||
|
|
e2b4c0787a | ||
|
|
2d21e59b54 | ||
|
|
00ccafb90d | ||
|
|
b82e02b5ed | ||
|
|
096550f163 | ||
|
|
81e5963a5d | ||
|
|
14569e4fae | ||
|
|
6cc32a56b9 | ||
|
|
ebdb86c460 | ||
|
|
400c9d6a2d | ||
|
|
e9a1b06746 | ||
|
|
4f3aaa1ede | ||
|
|
187258cc3a | ||
|
|
dfbcb1566b | ||
|
|
e3b0a70eb9 | ||
|
|
790a40ec99 | ||
|
|
a824bec9e1 | ||
|
|
10db0c3c66 | ||
|
|
12620b6152 | ||
|
|
2294283506 | ||
|
|
cebcf6a4fc | ||
|
|
a79a78b6e6 | ||
|
|
c6ad744ce2 | ||
|
|
b430b3c8df | ||
|
|
0b316a8c5e | ||
|
|
b8e93e6099 | ||
|
|
a84a88bf09 | ||
|
|
02d54dd187 | ||
|
|
fb054c7f8d | ||
|
|
77da29b4f7 | ||
|
|
828a9a8c51 | ||
|
|
c680947db5 | ||
|
|
5348f4eafe | ||
|
|
7781498181 | ||
|
|
b8ce139b8a | ||
|
|
75911b6c64 | ||
|
|
bf0d95145d | ||
|
|
4326d560e9 | ||
|
|
65fa6f2f00 | ||
|
|
124629e1d9 | ||
|
|
557fade4a7 | ||
|
|
98a65b5d1d | ||
|
|
caaa35e5a7 | ||
|
|
a7459489ff | ||
|
|
87e59ff876 | ||
|
|
9d87c913e7 | ||
|
|
0e8c010645 | ||
|
|
470d01a508 | ||
|
|
c16b9ed25b | ||
|
|
d498199e8a | ||
|
|
013687dccd | ||
|
|
baf25ca7a7 | ||
|
|
6c28bd884b | ||
|
|
510091f082 | ||
|
|
7db44c113c | ||
|
|
6cbf4306e7 | ||
|
|
777386ea67 | ||
|
|
95e5e90791 | ||
|
|
a86868526e | ||
|
|
f1ab6e2533 | ||
|
|
9f516a8ccc | ||
|
|
e07af68018 | ||
|
|
a37d9a2d8e | ||
|
|
57811b5371 | ||
|
|
7ff9ba4fe6 | ||
|
|
fad34bdbc3 | ||
|
|
22b41d892a | ||
|
|
7a97c7575d | ||
|
|
b0e175ad3d | ||
|
|
0de60aa6aa | ||
|
|
933e10d8a0 | ||
|
|
2efac3d949 | ||
|
|
c33841329d | ||
|
|
f37800560f | ||
|
|
60e61a0627 | ||
|
|
260dbeb3d2 | ||
|
|
70f495b4e1 | ||
|
|
663db8f978 | ||
|
|
c412739040 | ||
|
|
8b13d71fcf |
806
Doxyfile
Normal file
806
Doxyfile
Normal file
@@ -0,0 +1,806 @@
|
||||
# Doxyfile 1.2.6
|
||||
|
||||
# This file describes the settings to be used by doxygen for a project
|
||||
#
|
||||
# All text after a hash (#) is considered a comment and will be ignored
|
||||
# The format is:
|
||||
# TAG = value [value, ...]
|
||||
# For lists items can also be appended using:
|
||||
# TAG += value [value, ...]
|
||||
# Values that contain spaces should be placed between quotes (" ")
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# General configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
|
||||
# by quotes) that should identify the project.
|
||||
|
||||
PROJECT_NAME = SimGear
|
||||
|
||||
# The PROJECT_NUMBER tag can be used to enter a project or revision number.
|
||||
# This could be handy for archiving the generated documentation or
|
||||
# if some version control system is used.
|
||||
|
||||
PROJECT_NUMBER = 0.0.16
|
||||
|
||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
||||
# base path where the generated documentation will be put.
|
||||
# If a relative path is entered, it will be relative to the location
|
||||
# where doxygen was started. If left blank the current directory will be used.
|
||||
|
||||
OUTPUT_DIRECTORY = ../doxy
|
||||
|
||||
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
|
||||
# documentation generated by doxygen is written. Doxygen will use this
|
||||
# information to generate all constant output in the proper language.
|
||||
# The default language is English, other supported languages are:
|
||||
# Dutch, French, Italian, Czech, Swedish, German, Finnish, Japanese,
|
||||
# Korean, Hungarian, Norwegian, Spanish, Romanian, Russian, Croatian,
|
||||
# Polish, Portuguese and Slovene.
|
||||
|
||||
OUTPUT_LANGUAGE = English
|
||||
|
||||
# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
|
||||
# documentation are documented, even if no documentation was available.
|
||||
# Private class members and static file members will be hidden unless
|
||||
# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
|
||||
|
||||
EXTRACT_ALL = NO
|
||||
|
||||
# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
|
||||
# will be included in the documentation.
|
||||
|
||||
EXTRACT_PRIVATE = NO
|
||||
|
||||
# If the EXTRACT_STATIC tag is set to YES all static members of a file
|
||||
# will be included in the documentation.
|
||||
|
||||
EXTRACT_STATIC = NO
|
||||
|
||||
# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
|
||||
# undocumented members of documented classes, files or namespaces.
|
||||
# If set to NO (the default) these members will be included in the
|
||||
# various overviews, but no documentation section is generated.
|
||||
# This option has no effect if EXTRACT_ALL is enabled.
|
||||
|
||||
HIDE_UNDOC_MEMBERS = NO
|
||||
|
||||
# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
|
||||
# undocumented classes that are normally visible in the class hierarchy.
|
||||
# If set to NO (the default) these class will be included in the various
|
||||
# overviews. This option has no effect if EXTRACT_ALL is enabled.
|
||||
|
||||
HIDE_UNDOC_CLASSES = NO
|
||||
|
||||
# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
|
||||
# include brief member descriptions after the members that are listed in
|
||||
# the file and class documentation (similar to JavaDoc).
|
||||
# Set to NO to disable this.
|
||||
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
|
||||
# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
|
||||
# the brief description of a member or function before the detailed description.
|
||||
# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
|
||||
# brief descriptions will be completely suppressed.
|
||||
|
||||
REPEAT_BRIEF = YES
|
||||
|
||||
# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
|
||||
# Doxygen will generate a detailed section even if there is only a brief
|
||||
# description.
|
||||
|
||||
ALWAYS_DETAILED_SEC = NO
|
||||
|
||||
# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
|
||||
# path before files name in the file list and in the header files. If set
|
||||
# to NO the shortest path that makes the file name unique will be used.
|
||||
|
||||
FULL_PATH_NAMES = NO
|
||||
|
||||
# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
|
||||
# can be used to strip a user defined part of the path. Stripping is
|
||||
# only done if one of the specified strings matches the left-hand part of
|
||||
# the path. It is allowed to use relative paths in the argument list.
|
||||
|
||||
STRIP_FROM_PATH =
|
||||
|
||||
# The INTERNAL_DOCS tag determines if documentation
|
||||
# that is typed after a \internal command is included. If the tag is set
|
||||
# to NO (the default) then the documentation will be excluded.
|
||||
# Set it to YES to include the internal documentation.
|
||||
|
||||
INTERNAL_DOCS = NO
|
||||
|
||||
# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
|
||||
# generate a class diagram (in Html and LaTeX) for classes with base or
|
||||
# super classes. Setting the tag to NO turns the diagrams off.
|
||||
|
||||
CLASS_DIAGRAMS = YES
|
||||
|
||||
# If the SOURCE_BROWSER tag is set to YES then a list of source files will
|
||||
# be generated. Documented entities will be cross-referenced with these sources.
|
||||
|
||||
SOURCE_BROWSER = YES
|
||||
|
||||
# Setting the INLINE_SOURCES tag to YES will include the body
|
||||
# of functions and classes directly in the documentation.
|
||||
|
||||
INLINE_SOURCES = NO
|
||||
|
||||
# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
|
||||
# doxygen to hide any special comment blocks from generated source code
|
||||
# fragments. Normal C and C++ comments will always remain visible.
|
||||
|
||||
STRIP_CODE_COMMENTS = YES
|
||||
|
||||
# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
|
||||
# file names in lower case letters. If set to YES upper case letters are also
|
||||
# allowed. This is useful if you have classes or files whose names only differ
|
||||
# in case and if your file system supports case sensitive file names. Windows
|
||||
# users are adviced to set this option to NO.
|
||||
|
||||
CASE_SENSE_NAMES = YES
|
||||
|
||||
# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
|
||||
# will show members with their full class and namespace scopes in the
|
||||
# documentation. If set to YES the scope will be hidden.
|
||||
|
||||
HIDE_SCOPE_NAMES = NO
|
||||
|
||||
# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
|
||||
# will generate a verbatim copy of the header file for each class for
|
||||
# which an include is specified. Set to NO to disable this.
|
||||
|
||||
VERBATIM_HEADERS = YES
|
||||
|
||||
# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
|
||||
# will put list of the files that are included by a file in the documentation
|
||||
# of that file.
|
||||
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
|
||||
# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
|
||||
# will interpret the first line (until the first dot) of a JavaDoc-style
|
||||
# comment as the brief description. If set to NO, the JavaDoc
|
||||
# comments will behave just like the Qt-style comments (thus requiring an
|
||||
# explict @brief command for a brief description.
|
||||
|
||||
JAVADOC_AUTOBRIEF = YES
|
||||
|
||||
# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
|
||||
# member inherits the documentation from any documented member that it
|
||||
# reimplements.
|
||||
|
||||
INHERIT_DOCS = YES
|
||||
|
||||
# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
|
||||
# is inserted in the documentation for inline members.
|
||||
|
||||
INLINE_INFO = YES
|
||||
|
||||
# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
|
||||
# will sort the (detailed) documentation of file and class members
|
||||
# alphabetically by member name. If set to NO the members will appear in
|
||||
# declaration order.
|
||||
|
||||
SORT_MEMBER_DOCS = YES
|
||||
|
||||
# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
|
||||
# tag is set to YES, then doxygen will reuse the documentation of the first
|
||||
# member in the group (if any) for the other members of the group. By default
|
||||
# all members of a group must be documented explicitly.
|
||||
|
||||
DISTRIBUTE_GROUP_DOC = NO
|
||||
|
||||
# The TAB_SIZE tag can be used to set the number of spaces in a tab.
|
||||
# Doxygen uses this value to replace tabs by spaces in code fragments.
|
||||
|
||||
TAB_SIZE = 8
|
||||
|
||||
# The ENABLE_SECTIONS tag can be used to enable conditional
|
||||
# documentation sections, marked by \if sectionname ... \endif.
|
||||
|
||||
ENABLED_SECTIONS =
|
||||
|
||||
# The GENERATE_TODOLIST tag can be used to enable (YES) or
|
||||
# disable (NO) the todo list. This list is created by putting \todo
|
||||
# commands in the documentation.
|
||||
|
||||
GENERATE_TODOLIST = YES
|
||||
|
||||
# The GENERATE_TESTLIST tag can be used to enable (YES) or
|
||||
# disable (NO) the test list. This list is created by putting \test
|
||||
# commands in the documentation.
|
||||
|
||||
GENERATE_TESTLIST = YES
|
||||
|
||||
# The GENERATE_BUGLIST tag can be used to enable (YES) or
|
||||
# disable (NO) the bug list. This list is created by putting \bug
|
||||
# commands in the documentation.
|
||||
|
||||
GENERATE_BUGLIST = YES
|
||||
|
||||
# This tag can be used to specify a number of aliases that acts
|
||||
# as commands in the documentation. An alias has the form "name=value".
|
||||
# For example adding "sideeffect=\par Side Effects:\n" will allow you to
|
||||
# put the command \sideeffect (or @sideeffect) in the documentation, which
|
||||
# will result in a user defined paragraph with heading "Side Effects:".
|
||||
# You can put \n's in the value part of an alias to insert newlines.
|
||||
|
||||
ALIASES =
|
||||
|
||||
# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
|
||||
# the initial value of a variable or define consist of for it to appear in
|
||||
# the documentation. If the initializer consists of more lines than specified
|
||||
# here it will be hidden. Use a value of 0 to hide initializers completely.
|
||||
# The appearance of the initializer of individual variables and defines in the
|
||||
# documentation can be controlled using \showinitializer or \hideinitializer
|
||||
# command in the documentation regardless of this setting.
|
||||
|
||||
MAX_INITIALIZER_LINES = 30
|
||||
|
||||
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
|
||||
# only. Doxygen will then generate output that is more tailored for C.
|
||||
# For instance some of the names that are used will be different. The list
|
||||
# of all members will be omitted, etc.
|
||||
|
||||
OPTIMIZE_OUTPUT_FOR_C = NO
|
||||
|
||||
# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
|
||||
# at the bottom of the documentation of classes and structs. If set to YES the
|
||||
# list will mention the files that were used to generate the documentation.
|
||||
|
||||
SHOW_USED_FILES = YES
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to warning and progress messages
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# The QUIET tag can be used to turn on/off the messages that are generated
|
||||
# by doxygen. Possible values are YES and NO. If left blank NO is used.
|
||||
|
||||
QUIET = NO
|
||||
|
||||
# The WARNINGS tag can be used to turn on/off the warning messages that are
|
||||
# generated by doxygen. Possible values are YES and NO. If left blank
|
||||
# NO is used.
|
||||
|
||||
WARNINGS = YES
|
||||
|
||||
# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
|
||||
# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
|
||||
# automatically be disabled.
|
||||
|
||||
WARN_IF_UNDOCUMENTED = YES
|
||||
|
||||
# The WARN_FORMAT tag determines the format of the warning messages that
|
||||
# doxygen can produce. The string should contain the $file, $line, and $text
|
||||
# tags, which will be replaced by the file and line number from which the
|
||||
# warning originated and the warning text.
|
||||
|
||||
WARN_FORMAT = "$file:$line: $text"
|
||||
|
||||
# The WARN_LOGFILE tag can be used to specify a file to which warning
|
||||
# and error messages should be written. If left blank the output is written
|
||||
# to stderr.
|
||||
|
||||
WARN_LOGFILE =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the input files
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# The INPUT tag can be used to specify the files and/or directories that contain
|
||||
# documented source files. You may enter file names like "myfile.cpp" or
|
||||
# directories like "/usr/src/myproject". Separate the files or directories
|
||||
# with spaces.
|
||||
|
||||
INPUT = \
|
||||
simgear/bucket \
|
||||
simgear/compiler.h \
|
||||
simgear/constants.h \
|
||||
simgear/debug \
|
||||
simgear/ephemeris \
|
||||
simgear/io \
|
||||
simgear/magvar \
|
||||
simgear/math \
|
||||
simgear/misc \
|
||||
simgear/route \
|
||||
simgear/screen \
|
||||
simgear/serial \
|
||||
simgear/sg_inlines.h \
|
||||
simgear/sg_traits.hxx \
|
||||
simgear/sg_zlib.h \
|
||||
simgear/sky \
|
||||
simgear/threads \
|
||||
simgear/timing \
|
||||
simgear/xml
|
||||
|
||||
# If the value of the INPUT tag contains directories, you can use the
|
||||
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
|
||||
# and *.h) to filter out the source-files in the directories. If left
|
||||
# blank all files are included.
|
||||
|
||||
FILE_PATTERNS = *.h *.hxx *.c *.cxx *.cpp
|
||||
|
||||
# The RECURSIVE tag can be used to turn specify whether or not subdirectories
|
||||
# should be searched for input files as well. Possible values are YES and NO.
|
||||
# If left blank NO is used.
|
||||
|
||||
RECURSIVE = YES
|
||||
|
||||
# The EXCLUDE tag can be used to specify files and/or directories that should
|
||||
# excluded from the INPUT source files. This way you can easily exclude a
|
||||
# subdirectory from a directory tree whose root is specified with the INPUT tag.
|
||||
|
||||
EXCLUDE = simgear/metakit simgear/zlib
|
||||
|
||||
# If the value of the INPUT tag contains directories, you can use the
|
||||
# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
|
||||
# certain files from those directories.
|
||||
|
||||
EXCLUDE_PATTERNS =
|
||||
|
||||
# The EXAMPLE_PATH tag can be used to specify one or more files or
|
||||
# directories that contain example code fragments that are included (see
|
||||
# the \include command).
|
||||
|
||||
EXAMPLE_PATH =
|
||||
|
||||
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
|
||||
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
|
||||
# and *.h) to filter out the source-files in the directories. If left
|
||||
# blank all files are included.
|
||||
|
||||
EXAMPLE_PATTERNS =
|
||||
|
||||
# The IMAGE_PATH tag can be used to specify one or more files or
|
||||
# directories that contain image that are included in the documentation (see
|
||||
# the \image command).
|
||||
|
||||
IMAGE_PATH =
|
||||
|
||||
# The INPUT_FILTER tag can be used to specify a program that doxygen should
|
||||
# invoke to filter for each input file. Doxygen will invoke the filter program
|
||||
# by executing (via popen()) the command <filter> <input-file>, where <filter>
|
||||
# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
|
||||
# input file. Doxygen will then use the output that the filter program writes
|
||||
# to standard output.
|
||||
|
||||
INPUT_FILTER =
|
||||
|
||||
# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
|
||||
# INPUT_FILTER) will be used to filter the input files when producing source
|
||||
# files to browse.
|
||||
|
||||
FILTER_SOURCE_FILES = NO
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the alphabetical class index
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
|
||||
# of all compounds will be generated. Enable this if the project
|
||||
# contains a lot of classes, structs, unions or interfaces.
|
||||
|
||||
ALPHABETICAL_INDEX = NO
|
||||
|
||||
# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
|
||||
# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
|
||||
# in which this list will be split (can be a number in the range [1..20])
|
||||
|
||||
COLS_IN_ALPHA_INDEX = 5
|
||||
|
||||
# In case all classes in a project start with a common prefix, all
|
||||
# classes will be put under the same header in the alphabetical index.
|
||||
# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
|
||||
# should be ignored while generating the index headers.
|
||||
|
||||
IGNORE_PREFIX =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the HTML output
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
|
||||
# generate HTML output.
|
||||
|
||||
GENERATE_HTML = YES
|
||||
|
||||
# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
|
||||
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
|
||||
# put in front of it. If left blank `html' will be used as the default path.
|
||||
|
||||
HTML_OUTPUT = html
|
||||
|
||||
# The HTML_HEADER tag can be used to specify a personal HTML header for
|
||||
# each generated HTML page. If it is left blank doxygen will generate a
|
||||
# standard header.
|
||||
|
||||
HTML_HEADER =
|
||||
|
||||
# The HTML_FOOTER tag can be used to specify a personal HTML footer for
|
||||
# each generated HTML page. If it is left blank doxygen will generate a
|
||||
# standard footer.
|
||||
|
||||
HTML_FOOTER =
|
||||
|
||||
# The HTML_STYLESHEET tag can be used to specify a user defined cascading
|
||||
# style sheet that is used by each HTML page. It can be used to
|
||||
# fine-tune the look of the HTML output. If the tag is left blank doxygen
|
||||
# will generate a default style sheet
|
||||
|
||||
HTML_STYLESHEET =
|
||||
|
||||
# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
|
||||
# files or namespaces will be aligned in HTML using tables. If set to
|
||||
# NO a bullet list will be used.
|
||||
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
|
||||
# If the GENERATE_HTMLHELP tag is set to YES, additional index files
|
||||
# will be generated that can be used as input for tools like the
|
||||
# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
|
||||
# of the generated HTML documentation.
|
||||
|
||||
GENERATE_HTMLHELP = NO
|
||||
|
||||
# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
|
||||
# controls if a separate .chi index file is generated (YES) or that
|
||||
# it should be included in the master .chm file (NO).
|
||||
|
||||
GENERATE_CHI = NO
|
||||
|
||||
# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
|
||||
# controls whether a binary table of contents is generated (YES) or a
|
||||
# normal table of contents (NO) in the .chm file.
|
||||
|
||||
BINARY_TOC = NO
|
||||
|
||||
# The TOC_EXPAND flag can be set YES to add extra items for group members
|
||||
# to the contents of the Html help documentation and to the tree view.
|
||||
|
||||
TOC_EXPAND = NO
|
||||
|
||||
# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
|
||||
# top of each HTML page. The value NO (the default) enables the index and
|
||||
# the value YES disables it.
|
||||
|
||||
DISABLE_INDEX = NO
|
||||
|
||||
# This tag can be used to set the number of enum values (range [1..20])
|
||||
# that doxygen will group on one line in the generated HTML documentation.
|
||||
|
||||
ENUM_VALUES_PER_LINE = 4
|
||||
|
||||
# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
|
||||
# generated containing a tree-like index structure (just like the one that
|
||||
# is generated for HTML Help). For this to work a browser that supports
|
||||
# JavaScript and frames is required (for instance Netscape 4.0+
|
||||
# or Internet explorer 4.0+).
|
||||
|
||||
GENERATE_TREEVIEW = NO
|
||||
|
||||
# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
|
||||
# used to set the initial width (in pixels) of the frame in which the tree
|
||||
# is shown.
|
||||
|
||||
TREEVIEW_WIDTH = 250
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the LaTeX output
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
|
||||
# generate Latex output.
|
||||
|
||||
GENERATE_LATEX = YES
|
||||
|
||||
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
|
||||
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
|
||||
# put in front of it. If left blank `latex' will be used as the default path.
|
||||
|
||||
LATEX_OUTPUT = latex
|
||||
|
||||
# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
|
||||
# LaTeX documents. This may be useful for small projects and may help to
|
||||
# save some trees in general.
|
||||
|
||||
COMPACT_LATEX = NO
|
||||
|
||||
# The PAPER_TYPE tag can be used to set the paper type that is used
|
||||
# by the printer. Possible values are: a4, a4wide, letter, legal and
|
||||
# executive. If left blank a4wide will be used.
|
||||
|
||||
PAPER_TYPE = a4wide
|
||||
|
||||
# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
|
||||
# packages that should be included in the LaTeX output.
|
||||
|
||||
EXTRA_PACKAGES =
|
||||
|
||||
# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
|
||||
# the generated latex document. The header should contain everything until
|
||||
# the first chapter. If it is left blank doxygen will generate a
|
||||
# standard header. Notice: only use this tag if you know what you are doing!
|
||||
|
||||
LATEX_HEADER =
|
||||
|
||||
# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
|
||||
# is prepared for conversion to pdf (using ps2pdf). The pdf file will
|
||||
# contain links (just like the HTML output) instead of page references
|
||||
# This makes the output suitable for online browsing using a pdf viewer.
|
||||
|
||||
PDF_HYPERLINKS = NO
|
||||
|
||||
# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
|
||||
# plain latex in the generated Makefile. Set this option to YES to get a
|
||||
# higher quality PDF documentation.
|
||||
|
||||
USE_PDFLATEX = NO
|
||||
|
||||
# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
|
||||
# command to the generated LaTeX files. This will instruct LaTeX to keep
|
||||
# running if errors occur, instead of asking the user for help.
|
||||
# This option is also used when generating formulas in HTML.
|
||||
|
||||
LATEX_BATCHMODE = NO
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the RTF output
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
|
||||
# The RTF output is optimised for Word 97 and may not look very pretty with
|
||||
# other RTF readers or editors.
|
||||
|
||||
GENERATE_RTF = YES
|
||||
|
||||
# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
|
||||
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
|
||||
# put in front of it. If left blank `rtf' will be used as the default path.
|
||||
|
||||
RTF_OUTPUT = rtf
|
||||
|
||||
# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
|
||||
# RTF documents. This may be useful for small projects and may help to
|
||||
# save some trees in general.
|
||||
|
||||
COMPACT_RTF = NO
|
||||
|
||||
# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
|
||||
# will contain hyperlink fields. The RTF file will
|
||||
# contain links (just like the HTML output) instead of page references.
|
||||
# This makes the output suitable for online browsing using a WORD or other.
|
||||
# programs which support those fields.
|
||||
# Note: wordpad (write) and others do not support links.
|
||||
|
||||
RTF_HYPERLINKS = NO
|
||||
|
||||
# Load stylesheet definitions from file. Syntax is similar to doxygen's
|
||||
# config file, i.e. a series of assigments. You only have to provide
|
||||
# replacements, missing definitions are set to their default value.
|
||||
|
||||
RTF_STYLESHEET_FILE =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the man page output
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
|
||||
# generate man pages
|
||||
|
||||
GENERATE_MAN = YES
|
||||
|
||||
# The MAN_OUTPUT tag is used to specify where the man pages will be put.
|
||||
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
|
||||
# put in front of it. If left blank `man' will be used as the default path.
|
||||
|
||||
MAN_OUTPUT = man
|
||||
|
||||
# The MAN_EXTENSION tag determines the extension that is added to
|
||||
# the generated man pages (default is the subroutine's section .3)
|
||||
|
||||
MAN_EXTENSION = .3
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the preprocessor
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
|
||||
# evaluate all C-preprocessor directives found in the sources and include
|
||||
# files.
|
||||
|
||||
ENABLE_PREPROCESSING = YES
|
||||
|
||||
# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
|
||||
# names in the source code. If set to NO (the default) only conditional
|
||||
# compilation will be performed. Macro expansion can be done in a controlled
|
||||
# way by setting EXPAND_ONLY_PREDEF to YES.
|
||||
|
||||
MACRO_EXPANSION = NO
|
||||
|
||||
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
|
||||
# then the macro expansion is limited to the macros specified with the
|
||||
# PREDEFINED and EXPAND_AS_PREDEFINED tags.
|
||||
|
||||
EXPAND_ONLY_PREDEF = NO
|
||||
|
||||
# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
|
||||
# in the INCLUDE_PATH (see below) will be search if a #include is found.
|
||||
|
||||
SEARCH_INCLUDES = YES
|
||||
|
||||
# The INCLUDE_PATH tag can be used to specify one or more directories that
|
||||
# contain include files that are not input files but should be processed by
|
||||
# the preprocessor.
|
||||
|
||||
INCLUDE_PATH =
|
||||
|
||||
# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
|
||||
# patterns (like *.h and *.hpp) to filter out the header-files in the
|
||||
# directories. If left blank, the patterns specified with FILE_PATTERNS will
|
||||
# be used.
|
||||
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
|
||||
# The PREDEFINED tag can be used to specify one or more macro names that
|
||||
# are defined before the preprocessor is started (similar to the -D option of
|
||||
# gcc). The argument of the tag is a list of macros of the form: name
|
||||
# or name=definition (no spaces). If the definition and the = are
|
||||
# omitted =1 is assumed.
|
||||
|
||||
PREDEFINED =
|
||||
|
||||
# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then
|
||||
# this tag can be used to specify a list of macro names that should be expanded.
|
||||
# The macro definition that is found in the sources will be used.
|
||||
# Use the PREDEFINED tag if you want to use a different macro definition.
|
||||
|
||||
EXPAND_AS_DEFINED =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::addtions related to external references
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# The TAGFILES tag can be used to specify one or more tagfiles.
|
||||
|
||||
TAGFILES =
|
||||
|
||||
# When a file name is specified after GENERATE_TAGFILE, doxygen will create
|
||||
# a tag file that is based on the input files it reads.
|
||||
|
||||
GENERATE_TAGFILE =
|
||||
|
||||
# If the ALLEXTERNALS tag is set to YES all external classes will be listed
|
||||
# in the class index. If set to NO only the inherited external classes
|
||||
# will be listed.
|
||||
|
||||
ALLEXTERNALS = NO
|
||||
|
||||
# The PERL_PATH should be the absolute path and name of the perl script
|
||||
# interpreter (i.e. the result of `which perl').
|
||||
|
||||
PERL_PATH = /usr/bin/perl
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
|
||||
# available from the path. This tool is part of Graphviz, a graph visualization
|
||||
# toolkit from AT&T and Lucent Bell Labs. The other options in this section
|
||||
# have no effect if this option is set to NO (the default)
|
||||
|
||||
HAVE_DOT = NO
|
||||
|
||||
# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
|
||||
# will generate a graph for each documented class showing the direct and
|
||||
# indirect inheritance relations. Setting this tag to YES will force the
|
||||
# the CLASS_DIAGRAMS tag to NO.
|
||||
|
||||
CLASS_GRAPH = YES
|
||||
|
||||
# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
|
||||
# will generate a graph for each documented class showing the direct and
|
||||
# indirect implementation dependencies (inheritance, containment, and
|
||||
# class references variables) of the class with other documented classes.
|
||||
|
||||
COLLABORATION_GRAPH = YES
|
||||
|
||||
# If the ENABLE_PREPROCESSING, INCLUDE_GRAPH, and HAVE_DOT tags are set to
|
||||
# YES then doxygen will generate a graph for each documented file showing
|
||||
# the direct and indirect include dependencies of the file with other
|
||||
# documented files.
|
||||
|
||||
INCLUDE_GRAPH = YES
|
||||
|
||||
# If the ENABLE_PREPROCESSING, INCLUDED_BY_GRAPH, and HAVE_DOT tags are set to
|
||||
# YES then doxygen will generate a graph for each documented header file showing
|
||||
# the documented files that directly or indirectly include this file
|
||||
|
||||
INCLUDED_BY_GRAPH = YES
|
||||
|
||||
# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
|
||||
# will graphical hierarchy of all classes instead of a textual one.
|
||||
|
||||
GRAPHICAL_HIERARCHY = YES
|
||||
|
||||
# The tag DOT_PATH can be used to specify the path where the dot tool can be
|
||||
# found. If left blank, it is assumed the dot tool can be found on the path.
|
||||
|
||||
DOT_PATH =
|
||||
|
||||
# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
|
||||
# (in pixels) of the graphs generated by dot. If a graph becomes larger than
|
||||
# this value, doxygen will try to truncate the graph, so that it fits within
|
||||
# the specified constraint. Beware that most browsers cannot cope with very
|
||||
# large images.
|
||||
|
||||
MAX_DOT_GRAPH_WIDTH = 1024
|
||||
|
||||
# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
|
||||
# (in pixels) of the graphs generated by dot. If a graph becomes larger than
|
||||
# this value, doxygen will try to truncate the graph, so that it fits within
|
||||
# the specified constraint. Beware that most browsers cannot cope with very
|
||||
# large images.
|
||||
|
||||
MAX_DOT_GRAPH_HEIGHT = 1024
|
||||
|
||||
# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
|
||||
# generate a legend page explaining the meaning of the various boxes and
|
||||
# arrows in the dot generated graphs.
|
||||
|
||||
GENERATE_LEGEND = YES
|
||||
|
||||
# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
|
||||
# remove the intermedate dot files that are used to generate
|
||||
# the various graphs.
|
||||
|
||||
DOT_CLEANUP = YES
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::addtions related to the search engine
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# The SEARCHENGINE tag specifies whether or not a search engine should be
|
||||
# used. If set to NO the values of all tags below this one will be ignored.
|
||||
|
||||
SEARCHENGINE = NO
|
||||
|
||||
# The CGI_NAME tag should be the name of the CGI script that
|
||||
# starts the search engine (doxysearch) with the correct parameters.
|
||||
# A script with this name will be generated by doxygen.
|
||||
|
||||
CGI_NAME = search.cgi
|
||||
|
||||
# The CGI_URL tag should be the absolute URL to the directory where the
|
||||
# cgi binaries are located. See the documentation of your http daemon for
|
||||
# details.
|
||||
|
||||
CGI_URL =
|
||||
|
||||
# The DOC_URL tag should be the absolute URL to the directory where the
|
||||
# documentation is located. If left blank the absolute path to the
|
||||
# documentation, with file:// prepended to it, will be used.
|
||||
|
||||
DOC_URL =
|
||||
|
||||
# The DOC_ABSPATH tag should be the absolute path to the directory where the
|
||||
# documentation is located. If left blank the directory on the local machine
|
||||
# will be used.
|
||||
|
||||
DOC_ABSPATH =
|
||||
|
||||
# The BIN_ABSPATH tag must point to the directory where the doxysearch binary
|
||||
# is installed.
|
||||
|
||||
BIN_ABSPATH = /usr/local/bin/
|
||||
|
||||
# The EXT_DOC_PATHS tag can be used to specify one or more paths to
|
||||
# documentation generated for other projects. This allows doxysearch to search
|
||||
# the documentation for these projects as well.
|
||||
|
||||
EXT_DOC_PATHS =
|
||||
11
Makefile.am
11
Makefile.am
@@ -1,4 +1,4 @@
|
||||
EXTRA_DIST = mksymlinks.sh acsite.m4 acconfig.h
|
||||
EXTRA_DIST = mksymlinks.sh acsite.m4 acconfig.h SimGear.dsp SimGear.dsw
|
||||
|
||||
SUBDIRS = simgear
|
||||
|
||||
@@ -73,7 +73,11 @@ distclean:
|
||||
#
|
||||
|
||||
dist-hook:
|
||||
tar cf - simgear/metar | (cd $(distdir); tar xvf -)
|
||||
(cd $(top_srcdir); \
|
||||
$(HOME)/projects/FlightGear-0.7/admin/am2dsp.pl --lib)
|
||||
pwd
|
||||
echo "copying simgear/metar"
|
||||
echo "other stuff"
|
||||
@list='@subdirs@'; \
|
||||
target=distclean; \
|
||||
for subdir in $$list; do \
|
||||
@@ -87,7 +91,8 @@ dist-hook:
|
||||
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|
||||
|| case "$$amf" in *=*) echo "distclean error ignored...";; *k*) fail=yes;; *) echo "distclean error ignored...";; esac; \
|
||||
done
|
||||
tar cf - simgear/metakit | (cd $(distdir); tar xvf -)
|
||||
(cd $(top_srcdir); tar cf - simgear/metakit) | \
|
||||
(cd $(distdir); tar xvf -)
|
||||
|
||||
|
||||
#
|
||||
|
||||
54
NEWS
54
NEWS
@@ -1,4 +1,57 @@
|
||||
New in 0.0.16
|
||||
* July 12, 2001
|
||||
* Various changes to the property manager implimentation to better support
|
||||
dumping out the desired portions of the property tree to file.
|
||||
* Don't compile the metakit demos by default (causes problems for Irix)'
|
||||
* Other various tweaks for Irix.
|
||||
* Added a virtual destructor to XMLVisitor to fix a warning message.
|
||||
* Check for valid hostname lookup in sg_socket.cxx
|
||||
* Add a function to return modified julian date without creating an
|
||||
entire SGTime class. This avoids an extraneous warning about not
|
||||
being able to find a timezone.
|
||||
* Created a mailing list for cvs commit messages.
|
||||
* Fixed a potential array under/over run bug in interpolator.cxx
|
||||
* Removed all references to SGValue from the property manager. Added
|
||||
support for an "archive" bit in the property manager to control
|
||||
which values get written out.
|
||||
* Added SGCommandState class so that commands can compile and save
|
||||
copies of their arguments for efficiency if they are called multiple
|
||||
times.
|
||||
* Added Brian Baul's "tr" tiled rendering low level support library.
|
||||
This along with some higher level code in flightgear allows us to do
|
||||
ultra-hires tiled screen dumps suitable for large format printers.
|
||||
(Norman Vine)
|
||||
|
||||
New in 0.0.15
|
||||
* June 20, 2001
|
||||
* Various bug fixes, tweaks, and optimizations.
|
||||
* Added a command manager (analogous to the property manager)
|
||||
* Better Irix Mips support.
|
||||
* Various gcc-3.0 fixes.
|
||||
* Various MSVC fixes.
|
||||
* Added MSVC project files (automatically generated from the unix
|
||||
automake configuration files.)
|
||||
* Removed total size limitation on interpolation table module.
|
||||
* Various Cygwin fixes.
|
||||
* Added some convenience functions to point3d.
|
||||
* Various compiler warning fixes.
|
||||
* Added a thread wrapper class (currently only supports pthreads)
|
||||
* Added IO routines for a lowlevel, native simgear binary 3d file
|
||||
format optimized for TerraGear terrain.
|
||||
* Better endianness checking and support for the binary file
|
||||
read/write routines.
|
||||
* Added doxygen comments for all public interface code. Documentation
|
||||
can be accessed via the SimGear web page.
|
||||
* Many FG -> SG name space changes for better consistancy throughout
|
||||
this package.
|
||||
* Added property aliases, repeated name tags, and a general xml
|
||||
inclusion facilities. Many other property manager clean ups
|
||||
following a complete rewrite.
|
||||
* Fixed some critical null pointer bugs in property manager.
|
||||
* Magnetic variation can now be fetched for any arbitrary location.
|
||||
|
||||
New in 0.0.14
|
||||
* December 14, 2000
|
||||
* Added a module to manage waypoints and routes, calculate bearing and
|
||||
distance to next waypoint, lateral distance off route, etc.
|
||||
* Moved some of the basic time management code over from flightgear.
|
||||
@@ -13,7 +66,6 @@ New in 0.0.14
|
||||
* Fixed sky dome so that the color at the horizon will always match
|
||||
the specified fog color.
|
||||
* Did a fair amount of fg -> sg name space updating (lots left to do.)
|
||||
* December 14, 2000
|
||||
* Added support for KAI C++ on linux.
|
||||
* MSVC tweaks.
|
||||
* MacOS tweaks.
|
||||
|
||||
@@ -1,5 +1,30 @@
|
||||
With the author's permission, SimGear now bundles MetaKit. MetaKit is
|
||||
explained
|
||||
With the author's permission, SimGear now bundles MetaKit.
|
||||
|
||||
Important build note:
|
||||
|
||||
Later on when you are linking programs with -lmk4 (i.e. FlightGear or one
|
||||
of it's associated programs) if you come across an error similar to the
|
||||
following:
|
||||
|
||||
c++ -Wall -O2 -L/usr/local/lib -o gensimple gensimple.o libAirports.a
|
||||
-lsgdebug -lsgmisc -lmk4 -lz -lm
|
||||
/usr/local/lib/libmk4.a(view.o)(.text+0x1c8):view.cpp: multiple definition
|
||||
of `c4_View::~c4_View(void)'
|
||||
libAirports.a(simple.o)(.text$_$_7c4_View+0x0):simple.cxx: first defined
|
||||
here
|
||||
collect2: ld returned 1 exit status
|
||||
make[2]: *** [gensimple] Error 1
|
||||
make[2]: Leaving directory `/home/curt/FlightGear-0.7.7/src/Airports'
|
||||
make[1]: *** [all-recursive] Error 1
|
||||
make[1]: Leaving directory `/home/curt/FlightGear-0.7.7/src'
|
||||
make: *** [all-recursive] Error 1
|
||||
|
||||
Then you need to come back and rebuild Metakit with the -DNDEBUG flag.
|
||||
For unix/cygwin systems, modify the unix/Makefile file and add -DNDEBUG
|
||||
to the CFLAGS line.
|
||||
|
||||
Now we return you to the official metakit readme ... :-)
|
||||
|
||||
|
||||
The MetaKit Library 2.01 March 2000
|
||||
==============================================================================
|
||||
|
||||
1828
SimGear.dsp
Normal file
1828
SimGear.dsp
Normal file
File diff suppressed because it is too large
Load Diff
29
SimGear.dsw
Normal file
29
SimGear.dsw
Normal file
@@ -0,0 +1,29 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "SimGear"=".\SimGear.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
@@ -141,6 +141,9 @@
|
||||
/* Define if your struct stat has st_rdev. */
|
||||
#undef HAVE_ST_RDEV
|
||||
|
||||
/* Define if you have the stdint.h include. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define if you have the strftime function. */
|
||||
#undef HAVE_STRFTIME
|
||||
|
||||
|
||||
5
am2dsp.cfg
Normal file
5
am2dsp.cfg
Normal file
@@ -0,0 +1,5 @@
|
||||
exclude_dir = threads
|
||||
include_path = .
|
||||
include_path = ..
|
||||
include_path = .\SimGear
|
||||
#include_path = \usr\include
|
||||
48
configure.in
48
configure.in
@@ -6,7 +6,7 @@ dnl $Id$
|
||||
AC_INIT(simgear/bucket/newbucket.cxx)
|
||||
|
||||
dnl Initialize the automake stuff
|
||||
AM_INIT_AUTOMAKE(SimGear, 0.0.14)
|
||||
AM_INIT_AUTOMAKE(SimGear, 0.0.16)
|
||||
|
||||
dnl Specify KAI C++ compiler and flags.
|
||||
dnl Borrowed with slight modification from blitz distribution.
|
||||
@@ -28,11 +28,21 @@ echo CC = $CC
|
||||
dnl Checks for programs.
|
||||
AC_PROG_MAKE_SET
|
||||
AC_PROG_CC
|
||||
AC_PROG_CPP
|
||||
AC_PROG_CXX
|
||||
AC_PROG_RANLIB
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_LN_S
|
||||
|
||||
AR="ar"
|
||||
OS=`uname -s`
|
||||
if test "$OS" = "IRIX" -o "$OS" = "IRIX64"; then
|
||||
if test "$CXX" = "CC"; then
|
||||
AR="CC -ar"
|
||||
AC_SUBST(AR)
|
||||
fi
|
||||
fi
|
||||
|
||||
if echo $includedir | egrep "simgear$" > /dev/null; then
|
||||
echo "includedir is" $includedir "libdir is" $libdir
|
||||
else
|
||||
@@ -53,7 +63,7 @@ AC_ARG_WITH(efence, [ --with-efence Specify if we are building with "
|
||||
|
||||
if test "x$with_efence" = "xyes" ; then
|
||||
echo "Building with efence"
|
||||
LIBS= "$LIBS -lefence"
|
||||
LIBS="$LIBS -lefence"
|
||||
fi
|
||||
|
||||
dnl Check for MS Windows environment
|
||||
@@ -94,6 +104,15 @@ AC_CHECK_LIB(m, cos)
|
||||
|
||||
base_LIBS="$LIBS"
|
||||
|
||||
dnl Thread related checks
|
||||
AC_CHECK_LIB(pthread, pthread_exit)
|
||||
AC_CHECK_HEADER(pthread.h)
|
||||
if test "x$ac_cv_lib_pthread_pthread_exit" = "xyes" -a "x$ac_cv_header_pthread_h" = "xyes"; then
|
||||
CXXFLAGS="$CXXFLAGS -D_REENTRANT"
|
||||
CFLAGS="$CFLAGS -D_REENTRANT"
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_THREADS, test "x$ac_cv_lib_pthread_pthread_exit" = "xyes" -a "x$ac_cv_header_pthread_h" = "xyes")
|
||||
|
||||
AC_CHECK_LIB(socket, socket)
|
||||
AC_CHECK_LIB(X11, XCreateWindow)
|
||||
AC_CHECK_LIB(Xext, XShmCreateImage)
|
||||
@@ -245,8 +264,12 @@ AM_CONDITIONAL(HAVE_ZLIB, test "x$ac_cv_header_zlib_h" = "xyes" )
|
||||
dnl Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS( \
|
||||
fcntl.h getopt.h malloc.h memory.h stdlib.h sys/param.h sys/stat.h \
|
||||
sys/time.h sys/timeb.h unistd.h windows.h winbase.h values.h )
|
||||
fcntl.h getopt.h malloc.h memory.h stdint.h stdlib.h sys/param.h \
|
||||
sys/stat.h sys/time.h sys/timeb.h unistd.h windows.h winbase.h values.h )
|
||||
|
||||
if test "x$ac_cv_header_stdint_h" = "xyes"; then
|
||||
AC_DEFINE( HAVE_STDINT_H )
|
||||
fi
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
@@ -260,7 +283,7 @@ AC_FUNC_VPRINTF
|
||||
AC_CHECK_FUNCS( ftime gettimeofday timegm memcpy bcopy mktime strstr rand \
|
||||
random setitimer getitimer signal GetLocalTime rint getrusage )
|
||||
|
||||
AM_CONFIG_HEADER(simgear/config.h)
|
||||
AM_CONFIG_HEADER(simgear/simgear_config.h)
|
||||
|
||||
AC_OUTPUT( \
|
||||
Makefile \
|
||||
@@ -268,17 +291,18 @@ AC_OUTPUT( \
|
||||
simgear/Makefile \
|
||||
simgear/version.h \
|
||||
simgear/bucket/Makefile \
|
||||
simgear/camera/Makefile \
|
||||
simgear/debug/Makefile \
|
||||
simgear/ephemeris/Makefile \
|
||||
simgear/io/Makefile \
|
||||
simgear/magvar/Makefile \
|
||||
simgear/math/Makefile \
|
||||
simgear/metar/Makefile \
|
||||
simgear/misc/Makefile \
|
||||
simgear/route/Makefile \
|
||||
simgear/screen/Makefile \
|
||||
simgear/serial/Makefile \
|
||||
simgear/sky/Makefile \
|
||||
simgear/threads/Makefile \
|
||||
simgear/timing/Makefile \
|
||||
simgear/xgl/Makefile \
|
||||
simgear/xml/Makefile \
|
||||
@@ -320,3 +344,15 @@ fi
|
||||
if test "x$ac_cv_header_zlib_h" != "xyes"; then
|
||||
echo "Building zlib"
|
||||
fi
|
||||
|
||||
if test "x$ac_cv_lib_pthread_pthread_exit" = "xyes" -a "x$ac_cv_header_pthread_h" = "xyes"; then
|
||||
echo "Threads: pthread lib found."
|
||||
else
|
||||
echo "Threads: no threads (pthread lib not found.)"
|
||||
fi
|
||||
|
||||
if test "$OS" = "IRIX" -o "$OS" = "IRIX64"; then
|
||||
if test "$CXX" = "CC"; then
|
||||
echo "\nRemember to run: sh ../FlightGear/irix-hack.sh!\07\n"
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -16,29 +16,36 @@ else
|
||||
ZLIB_DIRS = zlib
|
||||
endif
|
||||
|
||||
METAR_DIRS =
|
||||
# METAR_DIRS = metar
|
||||
if HAVE_THREADS
|
||||
SGTHREAD_DIR = threads
|
||||
else
|
||||
SGTHREAD_DIR =
|
||||
endif
|
||||
|
||||
# METAR_DIRS =
|
||||
METAR_DIRS = metar
|
||||
|
||||
EXTRA_DIST = version.h.in
|
||||
|
||||
include_HEADERS = \
|
||||
compiler.h constants.h fg_traits.hxx fg_zlib.h inlines.h version.h
|
||||
compiler.h constants.h sg_inlines.h sg_traits.hxx sg_zlib.h version.h
|
||||
|
||||
SUBDIRS = \
|
||||
bucket \
|
||||
$(ZLIB_DIRS) \
|
||||
xml \
|
||||
debug \
|
||||
misc \
|
||||
bucket \
|
||||
ephemeris \
|
||||
io \
|
||||
magvar \
|
||||
math \
|
||||
$(METAR_DIRS) \
|
||||
misc \
|
||||
route \
|
||||
screen \
|
||||
$(SERIAL_DIRS) \
|
||||
sky \
|
||||
$(SGTHREAD_DIR) \
|
||||
timing \
|
||||
xgl \
|
||||
xml \
|
||||
$(ZLIB_DIRS)
|
||||
xgl
|
||||
|
||||
|
||||
@@ -24,14 +24,9 @@
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <simgear/misc/fgpath.hxx>
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
|
||||
#include "newbucket.hxx"
|
||||
|
||||
@@ -96,21 +91,21 @@ void SGBucket::set_bucket( double dlon, double dlat ) {
|
||||
|
||||
// cout << "diff = " << diff << " span = " << span << endl;
|
||||
|
||||
if ( (dlon >= 0) || (fabs(diff) < FG_EPSILON) ) {
|
||||
if ( (dlon >= 0) || (fabs(diff) < SG_EPSILON) ) {
|
||||
lon = (int)dlon;
|
||||
} else {
|
||||
lon = (int)dlon - 1;
|
||||
}
|
||||
|
||||
// find subdivision or super lon if needed
|
||||
if ( span < FG_EPSILON ) {
|
||||
if ( span < SG_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) ) {
|
||||
if ( (dlon >= 0) || (fabs(diff) < SG_EPSILON) ) {
|
||||
lon = (int)( (int)(lon / span) * span);
|
||||
} else {
|
||||
// cout << " lon = " << lon
|
||||
@@ -128,7 +123,7 @@ void SGBucket::set_bucket( double dlon, double dlat ) {
|
||||
//
|
||||
diff = dlat - (double)(int)dlat;
|
||||
|
||||
if ( (dlat >= 0) || (fabs(diff) < FG_EPSILON) ) {
|
||||
if ( (dlat >= 0) || (fabs(diff) < SG_EPSILON) ) {
|
||||
lat = (int)dlat;
|
||||
} else {
|
||||
lat = (int)dlat - 1;
|
||||
@@ -180,7 +175,7 @@ string SGBucket::gen_base_path() const {
|
||||
hem, top_lon, pole, top_lat,
|
||||
hem, main_lon, pole, main_lat);
|
||||
|
||||
FGPath path( raw_path );
|
||||
SGPath path( raw_path );
|
||||
|
||||
return path.str();
|
||||
}
|
||||
@@ -206,10 +201,10 @@ double SGBucket::get_width_m() const {
|
||||
} else {
|
||||
clat = (int)clat - 0.5;
|
||||
}
|
||||
double clat_rad = clat * DEG_TO_RAD;
|
||||
double clat_rad = clat * SGD_DEGREES_TO_RADIANS;
|
||||
double cos_lat = cos( clat_rad );
|
||||
double local_radius = cos_lat * EQUATORIAL_RADIUS_M;
|
||||
double local_perimeter = 2.0 * local_radius * FG_PI;
|
||||
double local_radius = cos_lat * SG_EQUATORIAL_RADIUS_M;
|
||||
double local_perimeter = 2.0 * local_radius * SGD_PI;
|
||||
double degree_width = local_perimeter / 360.0;
|
||||
|
||||
return sg_bucket_span( get_center_lat() ) * degree_width;
|
||||
@@ -218,7 +213,7 @@ double SGBucket::get_width_m() const {
|
||||
|
||||
// return height of the tile in meters
|
||||
double SGBucket::get_height_m() const {
|
||||
double perimeter = 2.0 * EQUATORIAL_RADIUS_M * FG_PI;
|
||||
double perimeter = 2.0 * SG_EQUATORIAL_RADIUS_M * SGD_PI;
|
||||
double degree_height = perimeter / 360.0;
|
||||
|
||||
return SG_BUCKET_SPAN * degree_height;
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
* $Id$
|
||||
**************************************************************************/
|
||||
|
||||
/** \file newbucket.hxx
|
||||
* A class and associated utiltity functions to manage world scenery tiling.
|
||||
*/
|
||||
|
||||
#ifndef _NEWBUCKET_HXX
|
||||
#define _NEWBUCKET_HXX
|
||||
@@ -30,44 +33,46 @@
|
||||
#include <simgear/compiler.h>
|
||||
#include <simgear/constants.h>
|
||||
|
||||
#ifdef FG_HAVE_STD_INCLUDES
|
||||
#ifdef SG_HAVE_STD_INCLUDES
|
||||
# include <cmath>
|
||||
# include <cstdio> // sprintf()
|
||||
# include <iostream>
|
||||
#else
|
||||
# include <math.h>
|
||||
# include <stdio.h> // sprintf()
|
||||
# include <iostream.h>
|
||||
#endif
|
||||
|
||||
#include STL_IOSTREAM
|
||||
|
||||
// I don't understand ... <math.h> or <cmath> should be included
|
||||
// already depending on how you defined FG_HAVE_STD_INCLUDES, but I
|
||||
// already depending on how you defined SG_HAVE_STD_INCLUDES, but I
|
||||
// can go ahead and add this -- CLO
|
||||
#ifdef __MWERKS__
|
||||
FG_USING_STD(sprintf);
|
||||
FG_USING_STD(fabs);
|
||||
SG_USING_STD(sprintf);
|
||||
SG_USING_STD(fabs);
|
||||
#endif
|
||||
|
||||
#include STL_STRING
|
||||
|
||||
FG_USING_STD(string);
|
||||
SG_USING_STD(string);
|
||||
|
||||
#if ! defined( FG_HAVE_NATIVE_SGI_COMPILERS )
|
||||
FG_USING_STD(ostream);
|
||||
#if ! defined( SG_HAVE_NATIVE_SGI_COMPILERS )
|
||||
SG_USING_STD(ostream);
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* standard size of a bucket in degrees (1/8 of a degree)
|
||||
*/
|
||||
#define SG_BUCKET_SPAN 0.125
|
||||
|
||||
#define SG_BUCKET_SPAN 0.125 // 1/8 of a degree
|
||||
#define SG_HALF_BUCKET_SPAN 0.0625 // 1/2 of 1/8 of a degree = 1/16 = 0.0625
|
||||
|
||||
class SGBucket;
|
||||
ostream& operator<< ( ostream&, const SGBucket& );
|
||||
bool operator== ( const SGBucket&, const SGBucket& );
|
||||
/**
|
||||
* half of a standard SG_BUCKET_SPAN
|
||||
*/
|
||||
#define SG_HALF_BUCKET_SPAN ( 0.5 * SG_BUCKET_SPAN )
|
||||
|
||||
|
||||
// return the horizontal tile span factor based on latitude
|
||||
inline double sg_bucket_span( double l ) {
|
||||
static double sg_bucket_span( double l ) {
|
||||
if ( l >= 89.0 ) {
|
||||
return 360.0;
|
||||
} else if ( l >= 88.0 ) {
|
||||
@@ -102,6 +107,13 @@ inline double sg_bucket_span( double l ) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A class to manage world scenery tiling.
|
||||
* This class encapsulates the world tiling scheme. It provides ways
|
||||
* to calculate a unique tile index from a lat/lon, and it can provide
|
||||
* information such as the dimensions of a given tile.
|
||||
*/
|
||||
|
||||
class SGBucket {
|
||||
|
||||
private:
|
||||
@@ -113,59 +125,101 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
// default constructor
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
SGBucket();
|
||||
|
||||
// constructor for specified location
|
||||
/**
|
||||
* Construct a bucket given a specific location.
|
||||
* @param dlon longitude specified in degrees
|
||||
* @param dlat latitude specified in degrees
|
||||
*/
|
||||
SGBucket(const double dlon, const double dlat);
|
||||
|
||||
// create an impossible bucket if false
|
||||
/** Construct a bucket.
|
||||
* @param is_good if false, create an invalid bucket. This is
|
||||
* useful * if you are comparing cur_bucket to last_bucket and
|
||||
* you want to * make sure last_bucket starts out as something
|
||||
* impossible.
|
||||
*/
|
||||
SGBucket(const bool is_good);
|
||||
|
||||
// Parse a unique scenery tile index and find the lon, lat, x, and y
|
||||
/** Construct a bucket given a unique bucket index number.
|
||||
* @param bindex unique bucket index
|
||||
*/
|
||||
SGBucket(const long int bindex);
|
||||
|
||||
// default destructor
|
||||
/**
|
||||
* Default destructor.
|
||||
*/
|
||||
~SGBucket();
|
||||
|
||||
// Set the bucket params for the specified lat and lon
|
||||
/**
|
||||
* Reset a bucket to represent a new lat and lon
|
||||
* @param dlon longitude specified in degrees
|
||||
* @param dlat latitude specified in degrees
|
||||
*/
|
||||
void set_bucket( double dlon, double dlat );
|
||||
|
||||
/**
|
||||
* Reset a bucket to represent a new lat and lon
|
||||
* @param lonlat an array of double[2] holding lon and lat
|
||||
* (specified) in degrees
|
||||
*/
|
||||
void set_bucket( double *lonlat );
|
||||
|
||||
// create an impossible bucket
|
||||
inline void make_bad( void ) {
|
||||
/**
|
||||
* Create an impossible bucket.
|
||||
* This is useful if you are comparing cur_bucket to last_bucket
|
||||
* and you want to make sure last_bucket starts out as something
|
||||
* impossible.
|
||||
*/
|
||||
inline void make_bad() {
|
||||
set_bucket(0.0, 0.0);
|
||||
lon = -1000;
|
||||
}
|
||||
|
||||
// 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)
|
||||
|
||||
/**
|
||||
* 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)
|
||||
* @return tile index
|
||||
*/
|
||||
inline long int gen_index() const {
|
||||
return ((lon + 180) << 14) + ((lat + 90) << 6) + (y << 3) + x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the unique scenery tile index for this bucket in ascii
|
||||
* string form.
|
||||
* @return tile index in string form
|
||||
*/
|
||||
inline string gen_index_str() const {
|
||||
char tmp[20];
|
||||
sprintf(tmp, "%ld",
|
||||
(((long)lon + 180) << 14) + ((lat + 90) << 6) + (y << 3) + x);
|
||||
(((long)lon + 180) << 14) + ((lat + 90) << 6) + (y << 3) + x);
|
||||
return (string)tmp;
|
||||
}
|
||||
|
||||
// Build the path name for this bucket
|
||||
/**
|
||||
* Build the base path name for this bucket.
|
||||
* @return base path in string form
|
||||
*/
|
||||
string gen_base_path() const;
|
||||
|
||||
// return the center lon of a tile
|
||||
/**
|
||||
* @return the center lon of a tile.
|
||||
*/
|
||||
inline double get_center_lon() const {
|
||||
double span = sg_bucket_span( lat + y / 8.0 + SG_HALF_BUCKET_SPAN );
|
||||
|
||||
@@ -176,42 +230,91 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// return the center lat of a tile
|
||||
/**
|
||||
* @return the center lat of a tile.
|
||||
*/
|
||||
inline double get_center_lat() const {
|
||||
return lat + y / 8.0 + SG_HALF_BUCKET_SPAN;
|
||||
}
|
||||
|
||||
// return width of the tile in degrees
|
||||
/**
|
||||
* @return the width of the tile in degrees.
|
||||
*/
|
||||
double get_width() const;
|
||||
// return height of the tile in degrees
|
||||
|
||||
/**
|
||||
* @return the height of the tile in degrees.
|
||||
*/
|
||||
double get_height() const;
|
||||
|
||||
// return width of the tile in meters
|
||||
/**
|
||||
* @return the width of the tile in meters.
|
||||
*/
|
||||
double get_width_m() const;
|
||||
// return height of the tile in meters
|
||||
|
||||
/**
|
||||
* @return the height of the tile in meters.
|
||||
*/
|
||||
double get_height_m() const;
|
||||
|
||||
// Informational methods
|
||||
// Informational methods.
|
||||
|
||||
/**
|
||||
* @return the lon of the lower left corner of this tile.
|
||||
*/
|
||||
inline int get_lon() const { return lon; }
|
||||
|
||||
/**
|
||||
* @return the lat of the lower left corner of this tile.
|
||||
*/
|
||||
inline int get_lat() const { return lat; }
|
||||
|
||||
/**
|
||||
* @return the x coord within the 1x1 degree chunk this tile.
|
||||
*/
|
||||
inline int get_x() const { return x; }
|
||||
|
||||
/**
|
||||
* @return the y coord within the 1x1 degree chunk this tile.
|
||||
*/
|
||||
inline int get_y() const { return y; }
|
||||
|
||||
// friends
|
||||
|
||||
friend ostream& operator<< ( ostream&, const SGBucket& );
|
||||
friend bool operator== ( const SGBucket&, const SGBucket& );
|
||||
};
|
||||
|
||||
|
||||
// offset a bucket specified by dlon, dlat by the specified tile units
|
||||
// in the X & Y direction
|
||||
/**
|
||||
* \relates SGBucket
|
||||
* Return the bucket which is offset from the specified dlon, dlat by
|
||||
* the specified tile units in the X & Y direction.
|
||||
* @param dlon starting lon in degrees
|
||||
* @param dlat starting lat in degrees
|
||||
* @param x number of bucket units to offset in x (lon) direction
|
||||
* @param y number of bucket units to offset in y (lat) direction
|
||||
* @return offset bucket
|
||||
*/
|
||||
SGBucket sgBucketOffset( double dlon, double dlat, int x, int y );
|
||||
|
||||
|
||||
// calculate the offset between two buckets
|
||||
/**
|
||||
* \relates SGBucket
|
||||
* Calculate the offset between two buckets (in quantity of buckets).
|
||||
* @param b1 bucket 1
|
||||
* @param b2 bucket 2
|
||||
* @param dx offset distance (lon) in tile units
|
||||
* @param dy offset distance (lat) in tile units
|
||||
*/
|
||||
void sgBucketDiff( const SGBucket& b1, const SGBucket& b2, int *dx, int *dy );
|
||||
|
||||
|
||||
/**
|
||||
* Write the bucket lon, lat, x, and y to the output stream.
|
||||
* @param out output stream
|
||||
* @param b bucket
|
||||
*/
|
||||
inline ostream&
|
||||
operator<< ( ostream& out, const SGBucket& b )
|
||||
{
|
||||
@@ -219,6 +322,12 @@ operator<< ( ostream& out, const SGBucket& b )
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compare two bucket structures for equality.
|
||||
* @param b1 bucket 1
|
||||
* @param b2 bucket 2
|
||||
* @return comparison result
|
||||
*/
|
||||
inline bool
|
||||
operator== ( const SGBucket& b1, const SGBucket& b2 )
|
||||
{
|
||||
|
||||
@@ -17,37 +17,59 @@
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef _COMPILER_H
|
||||
#define _COMPILER_H
|
||||
/** \file compiler.h
|
||||
* A set of defines to encapsulate compiler and platform differences.
|
||||
* Please refer to the source code for full documentation on this file.
|
||||
*
|
||||
* Here is a summary of what this file does.
|
||||
*
|
||||
* (1) Defines macros for some STL includes which may be affected
|
||||
* by file name length limitations.
|
||||
*
|
||||
* (2) Defines macros for some features not supported by all C++ compilers.
|
||||
*
|
||||
* (3) Defines 'explicit' as a null macro if the compiler doesn't support
|
||||
* the explicit keyword.
|
||||
*
|
||||
* (4) Defines 'typename' as a null macro if the compiler doesn't support
|
||||
* the typename keyword.
|
||||
*
|
||||
* (5) Defines bool, true and false if the compiler doesn't do so.
|
||||
*
|
||||
* (6) Defines SG_EXPLICIT_FUNCTION_TMPL_ARGS if the compiler
|
||||
* supports calling a function template by providing its template
|
||||
* arguments explicitly.
|
||||
*
|
||||
* (7) Defines SG_NEED_AUTO_PTR if STL doesn't provide auto_ptr<>.
|
||||
*
|
||||
* (8) Defines SG_NO_ARROW_OPERATOR if the compiler is unable
|
||||
* to support operator->() for iterators.
|
||||
*
|
||||
* (9) Defines SG_USE_EXCEPTIONS if the compiler supports exceptions.
|
||||
* Note: no FlightGear code uses exceptions.
|
||||
*
|
||||
* (10) Define SG_NAMESPACES if the compiler supports namespaces.
|
||||
*
|
||||
* (11) SG_MATH_FN_IN_NAMESPACE_STD -- not used??
|
||||
*
|
||||
* (12) Define SG_HAVE_STD if std namespace is supported.
|
||||
*
|
||||
* (13) Defines SG_CLASS_PARTIAL_SPECIALIZATION if the compiler
|
||||
* supports partial specialization of class templates.
|
||||
*
|
||||
* (14) Defines SG_HAVE_STD_INCLUDES to use ISO C++ Standard headers.
|
||||
*
|
||||
* (15) Defines SG_HAVE_STREAMBUF if <streambuf> of <streambuf.h> are present.
|
||||
*
|
||||
* (16) Define SG_MATH_EXCEPTION_CLASH if math.h defines an exception class
|
||||
* that clashes with the one defined in <stdexcept>.
|
||||
*/
|
||||
|
||||
// What this file does.
|
||||
// (1) Defines macros for some STL includes which may be affected
|
||||
// by file name length limitations.
|
||||
// (2) Defines macros for some features not supported by all C++ compilers.
|
||||
// (3) Defines 'explicit' as a null macro if the compiler doesn't support
|
||||
// the explicit keyword.
|
||||
// (4) Defines 'typename' as a null macro if the compiler doesn't support
|
||||
// the typename keyword.
|
||||
// (5) Defines bool, true and false if the compiler doesn't do so.
|
||||
// (6) Defines FG_EXPLICIT_FUNCTION_TMPL_ARGS if the compiler
|
||||
// supports calling a function template by providing its template
|
||||
// arguments explicitly.
|
||||
// (7) Defines FG_NEED_AUTO_PTR if STL doesn't provide auto_ptr<>.
|
||||
// (8) Defines FG_NO_ARROW_OPERATOR if the compiler is unable
|
||||
// to support operator->() for iterators.
|
||||
// (9) Defines FG_USE_EXCEPTIONS if the compiler supports exceptions.
|
||||
// Note: no FlightGear code uses exceptions.
|
||||
// (10) Define FG_NAMESPACES if the compiler supports namespaces.
|
||||
// (11) FG_MATH_FN_IN_NAMESPACE_STD -- not used??
|
||||
// (12) Define FG_HAVE_STD if std namespace is supported.
|
||||
// (13) Defines FG_CLASS_PARTIAL_SPECIALIZATION if the compiler
|
||||
// supports partial specialization of class templates.
|
||||
// (14) Defines FG_HAVE_STD_INCLUDES to use ISO C++ Standard headers.
|
||||
// (15) Defines FG_HAVE_STREAMBUF if <streambuf> of <streambuf.h> are present.
|
||||
// (16) Define FG_MATH_EXCEPTION_CLASH if math.h defines an exception class
|
||||
// that clashes with the one defined in <stdexcept>.
|
||||
#ifndef _SG_COMPILER_H
|
||||
#define _SG_COMPILER_H
|
||||
|
||||
#ifdef __GNUC__
|
||||
# if __GNUC__ == 2
|
||||
@@ -58,37 +80,60 @@
|
||||
# define STL_FUNCTIONAL <functional>
|
||||
# define STL_IOMANIP <iomanip.h>
|
||||
# define STL_IOSTREAM <iostream.h>
|
||||
# define STL_ITERATOR <iterator.h>
|
||||
# define STL_FSTREAM <fstream.h>
|
||||
# define STL_STDEXCEPT <stdexcept>
|
||||
# define STL_STRING <string>
|
||||
# define STL_STRSTREAM <strstream.h>
|
||||
|
||||
# define FG_NEED_AUTO_PTR
|
||||
# define FG_NO_DEFAULT_TEMPLATE_ARGS
|
||||
# define FG_INCOMPLETE_FUNCTIONAL
|
||||
# define FG_NO_ARROW_OPERATOR
|
||||
# define SG_NEED_AUTO_PTR
|
||||
# define SG_NO_DEFAULT_TEMPLATE_ARGS
|
||||
# define SG_INCOMPLETE_FUNCTIONAL
|
||||
# define SG_NO_ARROW_OPERATOR
|
||||
|
||||
# elif __GNUC_MINOR__ >= 8
|
||||
|
||||
// g++-2.8.x and egcs-1.x
|
||||
# define FG_EXPLICIT_FUNCTION_TMPL_ARGS
|
||||
# define FG_NEED_AUTO_PTR
|
||||
# define FG_MEMBER_TEMPLATES
|
||||
# define FG_NAMESPACES
|
||||
# define FG_HAVE_STD
|
||||
# define FG_HAVE_STREAMBUF
|
||||
# define FG_CLASS_PARTIAL_SPECIALIZATION
|
||||
# define SG_EXPLICIT_FUNCTION_TMPL_ARGS
|
||||
# define SG_NEED_AUTO_PTR
|
||||
# define SG_MEMBER_TEMPLATES
|
||||
# define SG_NAMESPACES
|
||||
# define SG_HAVE_STD
|
||||
# define SG_HAVE_STREAMBUF
|
||||
# define SG_CLASS_PARTIAL_SPECIALIZATION
|
||||
|
||||
# define STL_ALGORITHM <algorithm>
|
||||
# define STL_FUNCTIONAL <functional>
|
||||
# define STL_IOMANIP <iomanip>
|
||||
# define STL_IOSTREAM <iostream>
|
||||
# define STL_ITERATOR <iterator>
|
||||
# define STL_FSTREAM <fstream>
|
||||
# define STL_STDEXCEPT <stdexcept>
|
||||
# define STL_STRING <string>
|
||||
# define STL_STRSTREAM <strstream>
|
||||
|
||||
# endif
|
||||
# elif __GNUC__ == 3
|
||||
// g++-3.0.x
|
||||
# define SG_EXPLICIT_FUNCTION_TMPL_ARGS
|
||||
# define SG_NEED_AUTO_PTR
|
||||
# define SG_MEMBER_TEMPLATES
|
||||
# define SG_NAMESPACES
|
||||
# define SG_HAVE_STD
|
||||
# define SG_HAVE_STREAMBUF
|
||||
# define SG_CLASS_PARTIAL_SPECIALIZATION
|
||||
# define SG_HAVE_STD_INCLUDES
|
||||
|
||||
# define STL_ALGORITHM <algorithm>
|
||||
# define STL_FUNCTIONAL <functional>
|
||||
# define STL_IOMANIP <iomanip>
|
||||
# define STL_IOSTREAM <iostream>
|
||||
# define STL_ITERATOR <iterator>
|
||||
# define STL_FSTREAM <fstream>
|
||||
# define STL_STDEXCEPT <stdexcept>
|
||||
# define STL_STRING <string>
|
||||
# define STL_STRSTREAM <strstream>
|
||||
|
||||
# else
|
||||
# error Time to upgrade. GNU compilers < 2.7 not supported
|
||||
# endif
|
||||
@@ -97,16 +142,17 @@
|
||||
/* KAI C++ */
|
||||
#if defined(__KCC)
|
||||
|
||||
# define FG_NAMESPACES
|
||||
# define FG_HAVE_STD
|
||||
# define FG_HAVE_STREAMBUF
|
||||
# define FG_HAVE_TRAITS
|
||||
# define FG_HAVE_STD_INCLUDES
|
||||
# define SG_NAMESPACES
|
||||
# define SG_HAVE_STD
|
||||
# define SG_HAVE_STREAMBUF
|
||||
# define SG_HAVE_TRAITS
|
||||
# define SG_HAVE_STD_INCLUDES
|
||||
|
||||
# define STL_ALGORITHM <algorithm>
|
||||
# define STL_FUNCTIONAL <functional>
|
||||
# define STL_IOMANIP <iomanip>
|
||||
# define STL_IOSTREAM <iostream>
|
||||
# define STL_ITERATOR <iterator>
|
||||
# define STL_FSTREAM <fstream>
|
||||
# define STL_STDEXCEPT <stdexcept>
|
||||
# define STL_STRING <string>
|
||||
@@ -120,15 +166,16 @@
|
||||
/*
|
||||
CodeWarrior compiler from Metrowerks, Inc.
|
||||
*/
|
||||
# define FG_HAVE_TRAITS
|
||||
# define FG_HAVE_STD_INCLUDES
|
||||
# define FG_HAVE_STD
|
||||
# define FG_NAMESPACES
|
||||
# define SG_HAVE_TRAITS
|
||||
# define SG_HAVE_STD_INCLUDES
|
||||
# define SG_HAVE_STD
|
||||
# define SG_NAMESPACES
|
||||
|
||||
# define STL_ALGORITHM <algorithm>
|
||||
# define STL_FUNCTIONAL <functional>
|
||||
# define STL_IOMANIP <iomanip>
|
||||
# define STL_IOSTREAM <iostream>
|
||||
# define STL_ITERATOR <iterator>
|
||||
# define STL_FSTREAM <fstream>
|
||||
# define STL_STDEXCEPT <stdexcept>
|
||||
# define STL_STRING <string>
|
||||
@@ -151,15 +198,16 @@
|
||||
# define FG_MEM_COPY(to,from,n) memcpy(to, from, n)
|
||||
|
||||
# if _MSC_VER == 1200 // msvc++ 6.0
|
||||
# define FG_NAMESPACES
|
||||
# define FG_HAVE_STD
|
||||
# define FG_HAVE_STD_INCLUDES
|
||||
# define FG_HAVE_STREAMBUF
|
||||
# define SG_NAMESPACES
|
||||
# define SG_HAVE_STD
|
||||
# define SG_HAVE_STD_INCLUDES
|
||||
# define SG_HAVE_STREAMBUF
|
||||
|
||||
# define STL_ALGORITHM <algorithm>
|
||||
# define STL_FUNCTIONAL <functional>
|
||||
# define STL_IOMANIP <iomanip>
|
||||
# define STL_IOSTREAM <iostream>
|
||||
# define STL_ITERATOR <iterator>
|
||||
# define STL_FSTREAM <fstream>
|
||||
# define STL_STDEXCEPT <stdexcept>
|
||||
# define STL_STRING <string>
|
||||
@@ -168,27 +216,6 @@
|
||||
# pragma warning(disable: 4786) // identifier was truncated to '255' characters
|
||||
# pragma warning(disable: 4244) // conversion from double to float
|
||||
# pragma warning(disable: 4305) //
|
||||
|
||||
# elif _MSC_VER == 1100 // msvc++ 5.0
|
||||
# define NEEDNAMESPACESTD
|
||||
# define FG_NAMESPACES
|
||||
# define FG_HAVE_STD
|
||||
# define FG_HAVE_STD_INCLUDES
|
||||
# define FG_HAVE_STREAMBUF
|
||||
|
||||
# define STL_ALGORITHM <algorithm>
|
||||
# define STL_FUNCTIONAL <functional>
|
||||
# define STL_IOMANIP <iomanip>
|
||||
# define STL_IOSTREAM <iostream>
|
||||
# define STL_FSTREAM <fstream>
|
||||
# define STL_STDEXCEPT <stdexcept>
|
||||
# define STL_STRING <string>
|
||||
# define STL_STRSTREAM <strstream>
|
||||
|
||||
# pragma warning(disable: 4786) // identifier was truncated to '255' characters
|
||||
# pragma warning(disable: 4244) // conversion from double to float
|
||||
# pragma warning(disable: 4305) //
|
||||
|
||||
# else
|
||||
# error What version of MSVC++ is this?
|
||||
# endif
|
||||
@@ -202,7 +229,7 @@
|
||||
# define STL_ALGORITHM "algorithm"
|
||||
# define STL_FUNCTIONAL "functional"
|
||||
|
||||
# define FG_MATH_EXCEPTION_CLASH
|
||||
# define SG_MATH_EXCEPTION_CLASH
|
||||
|
||||
# else
|
||||
|
||||
@@ -212,16 +239,17 @@
|
||||
# define STL_STDEXCEPT <stdexcept>
|
||||
# define STL_STRSTREAM <strstream>
|
||||
|
||||
# define FG_INCOMPLETE_FUNCTIONAL
|
||||
# define SG_INCOMPLETE_FUNCTIONAL
|
||||
|
||||
# endif // HAVE_SGI_STL_PORT
|
||||
|
||||
# define STL_IOSTREAM <iostream>
|
||||
# define STL_ITERATOR <iterator>
|
||||
# define STL_FSTREAM <fstream>
|
||||
# define STL_STRING <string>
|
||||
# define FG_NO_DEFAULT_TEMPLATE_ARGS
|
||||
# define FG_NAMESPACES
|
||||
// # define FG_HAVE_STD
|
||||
# define SG_NO_DEFAULT_TEMPLATE_ARGS
|
||||
# define SG_NAMESPACES
|
||||
// # define SG_HAVE_STD
|
||||
|
||||
#endif // __BORLANDC__
|
||||
|
||||
@@ -230,23 +258,25 @@
|
||||
//
|
||||
|
||||
#if defined ( sgi ) && !defined( __GNUC__ )
|
||||
# define FG_HAVE_NATIVE_SGI_COMPILERS
|
||||
# define SG_HAVE_NATIVE_SGI_COMPILERS
|
||||
|
||||
# define FG_EXPLICIT_FUNCTION_TMPL_ARGS
|
||||
# define FG_NEED_AUTO_PTR
|
||||
# define FG_MEMBER_TEMPLATES
|
||||
# define FG_NAMESPACES
|
||||
# define FG_HAVE_STD
|
||||
# define FG_CLASS_PARTIAL_SPECIALIZATION
|
||||
# define SG_EXPLICIT_FUNCTION_TMPL_ARGS
|
||||
# define SG_NEED_AUTO_PTR
|
||||
# define SG_MEMBER_TEMPLATES
|
||||
# define SG_NAMESPACES
|
||||
# define SG_HAVE_STD
|
||||
# define SG_CLASS_PARTIAL_SPECIALIZATION
|
||||
# define SG_HAVE_TRAITS
|
||||
|
||||
# define STL_ALGORITHM <algorithm>
|
||||
# define STL_FUNCTIONAL <functional>
|
||||
# define STL_IOMANIP <iomanip.h>
|
||||
# define STL_IOSTREAM <iostream.h>
|
||||
# define STL_ITERATOR <iterator.h>
|
||||
# define STL_FSTREAM <fstream.h>
|
||||
# define STL_STDEXCEPT <stdexcept>
|
||||
# define STL_STRING <string>
|
||||
# define STL_STRSTREAM <strstream>
|
||||
# define STL_STRSTREAM <strstream.h>
|
||||
|
||||
#endif // Native SGI compilers
|
||||
|
||||
@@ -268,59 +298,62 @@
|
||||
// No user modifiable definitions beyond here.
|
||||
//
|
||||
|
||||
#ifdef FG_NEED_EXPLICIT
|
||||
#ifdef SG_NEED_EXPLICIT
|
||||
# define explicit
|
||||
#endif
|
||||
|
||||
#ifdef FG_NEED_TYPENAME
|
||||
#ifdef SG_NEED_TYPENAME
|
||||
# define typename
|
||||
#endif
|
||||
|
||||
#ifdef FG_NEED_MUTABLE
|
||||
#ifdef SG_NEED_MUTABLE
|
||||
# define mutable
|
||||
#endif
|
||||
|
||||
#ifdef FG_NEED_BOOL
|
||||
#ifdef SG_NEED_BOOL
|
||||
typedef int bool;
|
||||
# define true 1
|
||||
# define false 0
|
||||
#endif
|
||||
|
||||
#ifdef FG_EXPLICIT_FUNCTION_TMPL_ARGS
|
||||
# define FG_NULL_TMPL_ARGS <>
|
||||
#ifdef SG_EXPLICIT_FUNCTION_TMPL_ARGS
|
||||
# define SG_NULL_TMPL_ARGS <>
|
||||
#else
|
||||
# define FG_NULL_TMPL_ARGS
|
||||
# define SG_NULL_TMPL_ARGS
|
||||
#endif
|
||||
|
||||
#ifdef FG_CLASS_PARTIAL_SPECIALIZATION
|
||||
# define FG_TEMPLATE_NULL template<>
|
||||
#ifdef SG_CLASS_PARTIAL_SPECIALIZATION
|
||||
# define SG_TEMPLATE_NULL template<>
|
||||
#else
|
||||
# define FG_TEMPLATE_NULL
|
||||
# define SG_TEMPLATE_NULL
|
||||
#endif
|
||||
|
||||
// FG_NO_NAMESPACES is a hook so that users can disable namespaces
|
||||
// SG_NO_NAMESPACES is a hook so that users can disable namespaces
|
||||
// without having to edit library headers.
|
||||
#if defined(FG_NAMESPACES) && !defined(FG_NO_NAMESPACES)
|
||||
# define FG_NAMESPACE(X) namespace X {
|
||||
# define FG_NAMESPACE_END }
|
||||
# define FG_USING_NAMESPACE(X) using namespace X
|
||||
#if defined(SG_NAMESPACES) && !defined(SG_NO_NAMESPACES)
|
||||
# define SG_NAMESPACE(X) namespace X {
|
||||
# define SG_NAMESPACE_END }
|
||||
# define SG_USING_NAMESPACE(X) using namespace X
|
||||
# else
|
||||
# define FG_NAMESPACE(X)
|
||||
# define FG_NAMESPACE_END
|
||||
# define FG_USING_NAMESPACE(X)
|
||||
# define SG_NAMESPACE(X)
|
||||
# define SG_NAMESPACE_END
|
||||
# define SG_USING_NAMESPACE(X)
|
||||
#endif
|
||||
|
||||
# ifdef FG_HAVE_STD
|
||||
# define FG_USING_STD(X) using std::X
|
||||
/** \def SG_USING_STD(x)
|
||||
* Expands to using std::x if SG_HAVE_STD is defined
|
||||
*/
|
||||
# ifdef SG_HAVE_STD
|
||||
# define SG_USING_STD(X) using std::X
|
||||
# define STD std
|
||||
# else
|
||||
# define FG_USING_STD(X)
|
||||
# define SG_USING_STD(X)
|
||||
# define STD
|
||||
# endif
|
||||
|
||||
// Additional <functional> implementation from SGI STL 3.11
|
||||
// Adapter function objects: pointers to member functions
|
||||
#ifdef FG_INCOMPLETE_FUNCTIONAL
|
||||
#ifdef SG_INCOMPLETE_FUNCTIONAL
|
||||
|
||||
template <class _Ret, class _Tp>
|
||||
class const_mem_fun_ref_t
|
||||
@@ -339,6 +372,6 @@ template <class _Ret, class _Tp>
|
||||
inline const_mem_fun_ref_t<_Ret,_Tp> mem_fun_ref(_Ret (_Tp::*__f)() const)
|
||||
{ return const_mem_fun_ref_t<_Ret,_Tp>(__f); }
|
||||
|
||||
#endif // FG_INCOMPLETE_FUNCTIONAL
|
||||
#endif // SG_INCOMPLETE_FUNCTIONAL
|
||||
|
||||
#endif // _COMPILER_H
|
||||
#endif // _SG_COMPILER_H
|
||||
|
||||
@@ -21,125 +21,112 @@
|
||||
//
|
||||
// $Id$
|
||||
|
||||
/** \file constants.h
|
||||
* Various constant definitions.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _SG_CONSTANTS_H
|
||||
#define _SG_CONSTANTS_H
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#ifdef FG_HAVE_STD_INCLUDES
|
||||
#ifdef SG_HAVE_STD_INCLUDES
|
||||
# include <cmath>
|
||||
#else
|
||||
# ifdef FG_MATH_EXCEPTION_CLASH
|
||||
# ifdef SG_MATH_EXCEPTION_CLASH
|
||||
# define exception C_exception
|
||||
# endif
|
||||
# include <math.h>
|
||||
#endif
|
||||
|
||||
#include <plib/sg.h>
|
||||
|
||||
|
||||
// Make sure PI is defined in its various forms
|
||||
|
||||
// PI, only PI, and nothing but PI
|
||||
#ifdef M_PI
|
||||
# define FG_PI M_PI
|
||||
#else
|
||||
# define FG_PI 3.14159265358979323846
|
||||
#endif
|
||||
// SG_PI and SGD_PI (float and double) come from plib/sg.h
|
||||
|
||||
// 2 * PI
|
||||
#define FG_2PI 6.28318530717958647692
|
||||
/** 2 * PI */
|
||||
#define SGD_2PI 6.28318530717958647692
|
||||
|
||||
// PI / 2
|
||||
/** PI / 2 */
|
||||
#ifdef M_PI_2
|
||||
# define FG_PI_2 M_PI_2
|
||||
# define SGD_PI_2 M_PI_2
|
||||
#else
|
||||
# define FG_PI_2 1.57079632679489661923
|
||||
# define SGD_PI_2 1.57079632679489661923
|
||||
#endif
|
||||
|
||||
// PI / 4
|
||||
#define FG_PI_4 0.78539816339744830961
|
||||
/** PI / 4 */
|
||||
#define SGD_PI_4 0.78539816339744830961
|
||||
|
||||
#ifndef M_E
|
||||
# define M_E 2.7182818284590452354
|
||||
/** \def SG_E "e" */
|
||||
#ifdef M_E
|
||||
# define SG_E M_E
|
||||
#else
|
||||
# define SG_E 2.7182818284590452354
|
||||
#endif
|
||||
|
||||
// ONE_SECOND is pi/180/60/60, or about 100 feet at earths' equator
|
||||
#define ONE_SECOND 4.848136811E-6
|
||||
/** pi/180/60/60, or about 100 feet at earths' equator */
|
||||
#define SG_ONE_SECOND 4.848136811E-6
|
||||
|
||||
|
||||
// Radius of Earth in kilometers at the equator. Another source had
|
||||
// 6378.165 but this is probably close enough
|
||||
#define EARTH_RAD 6378.155
|
||||
/** Radius of Earth in kilometers at the equator. Another source had
|
||||
* 6378.165 but this is probably close enough */
|
||||
#define SG_EARTH_RAD 6378.155
|
||||
|
||||
|
||||
// Earth parameters for WGS 84, taken from LaRCsim/ls_constants.h
|
||||
|
||||
// Value of earth radius from [8]
|
||||
#define EQUATORIAL_RADIUS_FT 20925650. // ft
|
||||
#define EQUATORIAL_RADIUS_M 6378138.12 // meter
|
||||
// Radius squared
|
||||
#define RESQ_FT 437882827922500. // ft
|
||||
#define RESQ_M 40680645877797.1344 // meter
|
||||
/** Value of earth radius from LaRCsim (ft) */
|
||||
#define SG_EQUATORIAL_RADIUS_FT 20925650.
|
||||
|
||||
#if 0
|
||||
// Value of earth flattening parameter from ref [8]
|
||||
//
|
||||
// Note: FP = f
|
||||
// E = 1-f
|
||||
// EPS = sqrt(1-(1-f)^2)
|
||||
//
|
||||
/** Value of earth radius from LaRCsim (meter) */
|
||||
#define SG_EQUATORIAL_RADIUS_M 6378138.12
|
||||
|
||||
#define FP 0.003352813178
|
||||
#define E 0.996647186
|
||||
#define EPS 0.081819221
|
||||
#define INVG 0.031080997
|
||||
/** Radius squared (ft) */
|
||||
#define SG_EQ_RAD_SQUARE_FT 437882827922500.
|
||||
|
||||
// Time Related Parameters
|
||||
|
||||
#define MJD0 2415020.0
|
||||
#define J2000 (2451545.0 - MJD0)
|
||||
#define SIDRATE .9972695677
|
||||
#endif
|
||||
/** Radius squared (meter) */
|
||||
#define SG_EQ_RAD_SQUARE_M 40680645877797.1344
|
||||
|
||||
// Conversions
|
||||
|
||||
// Degrees to Radians
|
||||
#define DEG_TO_RAD 0.017453292 // deg*pi/180 = rad
|
||||
/** Arc seconds to radians. (arcsec*pi)/(3600*180) = rad */
|
||||
#define SG_ARCSEC_TO_RAD 4.84813681109535993589e-06
|
||||
|
||||
// Radians to Degrees
|
||||
#define RAD_TO_DEG 57.29577951 // rad*180/pi = deg
|
||||
/** Radians to arc seconds. (rad*3600*180)/pi = arcsec */
|
||||
#define SG_RAD_TO_ARCSEC 206264.806247096355156
|
||||
|
||||
// Arc seconds to radians // (arcsec*pi)/(3600*180) = rad
|
||||
#define ARCSEC_TO_RAD 4.84813681109535993589e-06
|
||||
/** Feet to Meters */
|
||||
#define SG_FEET_TO_METER 0.3048
|
||||
|
||||
// Radians to arc seconds // (rad*3600*180)/pi = arcsec
|
||||
#define RAD_TO_ARCSEC 206264.806247096355156
|
||||
/** Meters to Feet */
|
||||
#define SG_METER_TO_FEET 3.28083989501312335958
|
||||
|
||||
// Feet to Meters
|
||||
#define FEET_TO_METER 0.3048
|
||||
/** Meters to Nautical Miles. 1 nm = 6076.11549 feet */
|
||||
#define SG_METER_TO_NM 0.00053995680
|
||||
|
||||
// Meters to Feet
|
||||
#define METER_TO_FEET 3.28083989501312335958
|
||||
/** Nautical Miles to Meters */
|
||||
#define SG_NM_TO_METER 1852.0000
|
||||
|
||||
// Meters to Nautical Miles, 1 nm = 6076.11549 feet
|
||||
#define METER_TO_NM 0.00053995680
|
||||
/** Radians to Nautical Miles. 1 nm = 1/60 of a degree */
|
||||
#define SG_NM_TO_RAD 0.00029088820866572159
|
||||
|
||||
// Nautical Miles to Meters
|
||||
#define NM_TO_METER 1852.0000
|
||||
/** Nautical Miles to Radians */
|
||||
#define SG_RAD_TO_NM 3437.7467707849392526
|
||||
|
||||
// Radians to Nautical Miles, 1 nm = 1/60 of a degree
|
||||
#define NM_TO_RAD 0.00029088820866572159
|
||||
/** For divide by zero avoidance, this will be close enough to zero */
|
||||
#define SG_EPSILON 0.0000001
|
||||
|
||||
// Nautical Miles to Radians
|
||||
#define RAD_TO_NM 3437.7467707849392526
|
||||
|
||||
// For divide by zero avoidance, this will be close enough to zero
|
||||
#define FG_EPSILON 0.0000001
|
||||
/** Highest binobj format version we know how to read/write. This starts at
|
||||
* 0 and can go up to 65535 */
|
||||
#define SG_BINOBJ_VERSION 5
|
||||
|
||||
/** for backwards compatibility */
|
||||
#define SG_SCENERY_FILE_FORMAT "0.4"
|
||||
|
||||
|
||||
#endif // _SG_CONSTANTS_H
|
||||
|
||||
@@ -1,38 +1,43 @@
|
||||
// NB: To add a dbg_class, add it here, and add it to the structure in
|
||||
// fg_debug.c
|
||||
/** \file debug_types.h
|
||||
* Define the various logging classes and prioritiess
|
||||
*/
|
||||
|
||||
/**
|
||||
* Define the possible classes/categories of logging messages
|
||||
*/
|
||||
typedef enum {
|
||||
FG_NONE = 0x00000000,
|
||||
SG_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_IO = 0x00001000,
|
||||
FG_CLIPPER = 0x00002000,
|
||||
FG_NETWORK = 0x00004000,
|
||||
FG_UNDEFD = 0x00008000, // For range checking
|
||||
SG_TERRAIN = 0x00000001,
|
||||
SG_ASTRO = 0x00000002,
|
||||
SG_FLIGHT = 0x00000004,
|
||||
SG_INPUT = 0x00000008,
|
||||
SG_GL = 0x00000010,
|
||||
SG_VIEW = 0x00000020,
|
||||
SG_COCKPIT = 0x00000040,
|
||||
SG_GENERAL = 0x00000080,
|
||||
SG_MATH = 0x00000100,
|
||||
SG_EVENT = 0x00000200,
|
||||
SG_AIRCRAFT = 0x00000400,
|
||||
SG_AUTOPILOT = 0x00000800,
|
||||
SG_IO = 0x00001000,
|
||||
SG_CLIPPER = 0x00002000,
|
||||
SG_NETWORK = 0x00004000,
|
||||
SG_UNDEFD = 0x00008000, // For range checking
|
||||
|
||||
FG_ALL = 0xFFFFFFFF
|
||||
} fgDebugClass;
|
||||
SG_ALL = 0xFFFFFFFF
|
||||
} sgDebugClass;
|
||||
|
||||
|
||||
// NB: To add a priority, add it here.
|
||||
/**
|
||||
* Define the possible logging priorities (and their order).
|
||||
*/
|
||||
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;
|
||||
|
||||
SG_BULK, // For frequent messages
|
||||
SG_DEBUG, // Less frequent debug type messages
|
||||
SG_INFO, // Informatory messages
|
||||
SG_WARN, // Possible impending problem
|
||||
SG_ALERT // Very possible impending problem
|
||||
// SG_EXIT, // Problem (no core)
|
||||
// SG_ABORT // Abandon ship (core)
|
||||
} sgDebugPriority;
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
#include "logstream.hxx"
|
||||
|
||||
bool logbuf::logging_enabled = true;
|
||||
fgDebugClass logbuf::logClass = FG_NONE;
|
||||
fgDebugPriority logbuf::logPriority = FG_INFO;
|
||||
sgDebugClass logbuf::logClass = SG_NONE;
|
||||
sgDebugPriority logbuf::logPriority = SG_INFO;
|
||||
streambuf* logbuf::sbuf = NULL;
|
||||
|
||||
logbuf::logbuf()
|
||||
@@ -50,14 +50,14 @@ logbuf::set_sb( streambuf* sb )
|
||||
}
|
||||
|
||||
void
|
||||
logbuf::set_log_level( fgDebugClass c, fgDebugPriority p )
|
||||
logbuf::set_log_level( sgDebugClass c, sgDebugPriority p )
|
||||
{
|
||||
logClass = c;
|
||||
logPriority = p;
|
||||
}
|
||||
|
||||
void
|
||||
logstream::setLogLevels( fgDebugClass c, fgDebugPriority p )
|
||||
logstream::setLogLevels( sgDebugClass c, sgDebugPriority p )
|
||||
{
|
||||
logbuf::set_log_level( c, p );
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// Stream based logging mechanism.
|
||||
//
|
||||
/** \file logstream.hxx
|
||||
* Stream based logging mechanism.
|
||||
*/
|
||||
|
||||
// Written by Bernie Bright, 1998
|
||||
//
|
||||
// Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au
|
||||
@@ -24,32 +26,34 @@
|
||||
#ifndef _LOGSTREAM_H
|
||||
#define _LOGSTREAM_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#ifdef FG_HAVE_STD_INCLUDES
|
||||
// At least Irix needs this
|
||||
#ifdef SG_HAVE_NATIVE_SGI_COMPILERS
|
||||
#include <char_traits.h>
|
||||
#endif
|
||||
|
||||
#ifdef SG_HAVE_STD_INCLUDES
|
||||
# include <streambuf>
|
||||
# include <iostream>
|
||||
#else
|
||||
# include <iostream.h>
|
||||
# include <simgear/fg_traits.hxx>
|
||||
# include <simgear/sg_traits.hxx>
|
||||
#endif
|
||||
|
||||
#include <simgear/debug/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);
|
||||
#ifndef SG_HAVE_NATIVE_SGI_COMPILERS
|
||||
SG_USING_STD(streambuf);
|
||||
SG_USING_STD(ostream);
|
||||
SG_USING_STD(cerr);
|
||||
SG_USING_STD(endl);
|
||||
#else
|
||||
SG_USING_STD(char_traits);
|
||||
#endif
|
||||
|
||||
#ifdef __MWERKS__
|
||||
FG_USING_STD(iostream);
|
||||
SG_USING_STD(iostream);
|
||||
#endif
|
||||
|
||||
//
|
||||
@@ -60,43 +64,61 @@ FG_USING_STD(iostream);
|
||||
// 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.
|
||||
//
|
||||
/**
|
||||
* 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
|
||||
#ifndef SG_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;
|
||||
// typedef char_traits<char>::pos_type pos_type;
|
||||
// typedef char_traits<char>::off_type off_type;
|
||||
#endif
|
||||
// logbuf( streambuf* sb ) : sbuf(sb) {}
|
||||
// logbuf( streambuf* sb ) : sbuf(sb) {}
|
||||
/** Constructor */
|
||||
logbuf();
|
||||
|
||||
/** Destructor */
|
||||
~logbuf();
|
||||
|
||||
// Is logging enabled?
|
||||
/**
|
||||
* Is logging enabled?
|
||||
* @return true or false*/
|
||||
bool enabled() { return logging_enabled; }
|
||||
|
||||
// Set the logging level of subsequent messages.
|
||||
void set_log_state( fgDebugClass c, fgDebugPriority p );
|
||||
/**
|
||||
* Set the logging level of subsequent messages.
|
||||
* @param c debug class
|
||||
* @param p priority
|
||||
*/
|
||||
void set_log_state( sgDebugClass c, sgDebugPriority p );
|
||||
|
||||
// Set the global logging level.
|
||||
static void set_log_level( fgDebugClass c, fgDebugPriority p );
|
||||
/**
|
||||
* Set the global logging level.
|
||||
* @param c debug class
|
||||
* @param p priority
|
||||
*/
|
||||
static void set_log_level( sgDebugClass c, sgDebugPriority p );
|
||||
|
||||
//
|
||||
/**
|
||||
* Set the stream buffer
|
||||
* @param sb stream buffer
|
||||
*/
|
||||
void set_sb( streambuf* sb );
|
||||
|
||||
protected:
|
||||
|
||||
/** sync/flush */
|
||||
inline virtual int sync();
|
||||
|
||||
/** overflow */
|
||||
int_type overflow( int ch );
|
||||
// int xsputn( const char* s, istreamsize n );
|
||||
// int xsputn( const char* s, istreamsize n );
|
||||
|
||||
private:
|
||||
|
||||
@@ -104,8 +126,8 @@ private:
|
||||
static streambuf* sbuf;
|
||||
|
||||
static bool logging_enabled;
|
||||
static fgDebugClass logClass;
|
||||
static fgDebugPriority logPriority;
|
||||
static sgDebugClass logClass;
|
||||
static sgDebugPriority logPriority;
|
||||
|
||||
private:
|
||||
|
||||
@@ -117,7 +139,7 @@ private:
|
||||
inline int
|
||||
logbuf::sync()
|
||||
{
|
||||
#ifdef FG_HAVE_STD_INCLUDES
|
||||
#ifdef SG_HAVE_STD_INCLUDES
|
||||
return sbuf->pubsync();
|
||||
#else
|
||||
return sbuf->sync();
|
||||
@@ -125,7 +147,7 @@ logbuf::sync()
|
||||
}
|
||||
|
||||
inline void
|
||||
logbuf::set_log_state( fgDebugClass c, fgDebugPriority p )
|
||||
logbuf::set_log_state( sgDebugClass c, sgDebugPriority p )
|
||||
{
|
||||
logging_enabled = ((c & logClass) != 0 && p >= logPriority);
|
||||
}
|
||||
@@ -136,54 +158,65 @@ logbuf::overflow( int c )
|
||||
return logging_enabled ? sbuf->sputc(c) : (EOF == 0 ? 1: 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// logstream manipulator for setting the log level of a message.
|
||||
//
|
||||
/**
|
||||
* logstream manipulator for setting the log level of a message.
|
||||
*/
|
||||
struct loglevel
|
||||
{
|
||||
loglevel( fgDebugClass c, fgDebugPriority p )
|
||||
loglevel( sgDebugClass c, sgDebugPriority p )
|
||||
: logClass(c), logPriority(p) {}
|
||||
|
||||
fgDebugClass logClass;
|
||||
fgDebugPriority logPriority;
|
||||
sgDebugClass logClass;
|
||||
sgDebugPriority 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.
|
||||
//
|
||||
/**
|
||||
* 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( streambuf* sb ) : lbuf(sb) {}
|
||||
logstream_base() {}
|
||||
|
||||
logbuf lbuf;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
/**
|
||||
* Class to manage the debug logging stream.
|
||||
*/
|
||||
class logstream : private logstream_base, public ostream
|
||||
{
|
||||
public:
|
||||
// The default is to send messages to cerr.
|
||||
/**
|
||||
* The default is to send messages to cerr.
|
||||
* @param out output stream
|
||||
*/
|
||||
logstream( ostream& out )
|
||||
// : logstream_base(out.rdbuf()),
|
||||
// : logstream_base(out.rdbuf()),
|
||||
: logstream_base(),
|
||||
ostream(&lbuf) { lbuf.set_sb(out.rdbuf());}
|
||||
|
||||
/**
|
||||
* Set the output stream
|
||||
* @param out output stream
|
||||
*/
|
||||
void set_output( ostream& out ) { lbuf.set_sb( out.rdbuf() ); }
|
||||
|
||||
// Set the global log class and priority level.
|
||||
void setLogLevels( fgDebugClass c, fgDebugPriority p );
|
||||
/**
|
||||
* Set the global log class and priority level.
|
||||
* @param c debug class
|
||||
* @param p priority
|
||||
*/
|
||||
void setLogLevels( sgDebugClass c, sgDebugPriority p );
|
||||
|
||||
// Output operator to capture the debug level and priority of a message.
|
||||
/**
|
||||
* Output operator to capture the debug level and priority of a message.
|
||||
* @param l log level
|
||||
*/
|
||||
inline ostream& operator<< ( const loglevel& l );
|
||||
};
|
||||
|
||||
@@ -194,26 +227,36 @@ logstream::operator<< ( const loglevel& l )
|
||||
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.
|
||||
//
|
||||
|
||||
/**
|
||||
* \relates logstream
|
||||
* 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.
|
||||
* @return current logstream
|
||||
*/
|
||||
inline logstream&
|
||||
fglog()
|
||||
sglog()
|
||||
{
|
||||
static logstream logstrm( cerr );
|
||||
return logstrm;
|
||||
}
|
||||
|
||||
|
||||
/** \def SG_LOG(C,P,M)
|
||||
* Log a message.
|
||||
* @param C debug class
|
||||
* @param P priority
|
||||
* @param M message
|
||||
*/
|
||||
#ifdef FG_NDEBUG
|
||||
# define FG_LOG(C,P,M)
|
||||
# define SG_LOG(C,P,M)
|
||||
#elif defined( __MWERKS__ )
|
||||
# define FG_LOG(C,P,M) ::fglog() << ::loglevel(C,P) << M << std::endl
|
||||
# define SG_LOG(C,P,M) ::sglog() << ::loglevel(C,P) << M << std::endl
|
||||
#else
|
||||
# define FG_LOG(C,P,M) fglog() << loglevel(C,P) << M << endl
|
||||
# define SG_LOG(C,P,M) sglog() << loglevel(C,P) << M << endl
|
||||
#endif
|
||||
|
||||
|
||||
#endif // _LOGSTREAM_H
|
||||
|
||||
|
||||
@@ -4,20 +4,20 @@
|
||||
int
|
||||
main( int argc, char* argv[] )
|
||||
{
|
||||
fglog().setLogLevels( FG_ALL, FG_INFO );
|
||||
fglog().setLogLevels( SG_ALL, SG_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" );
|
||||
SG_LOG( FG_TERRAIN, FG_BULK, "terrain::bulk" ); // shouldnt appear
|
||||
SG_LOG( FG_TERRAIN, SG_DEBUG, "terrain::debug" ); // shouldnt appear
|
||||
SG_LOG( FG_TERRAIN, SG_INFO, "terrain::info" );
|
||||
SG_LOG( FG_TERRAIN, FG_WARN, "terrain::warn" );
|
||||
SG_LOG( FG_TERRAIN, SG_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 "
|
||||
SG_LOG( SG_EVENT, SG_INFO, "event::info "
|
||||
<< "i=" << i
|
||||
<< ", l=" << l
|
||||
<< ", d=" << d
|
||||
@@ -25,7 +25,7 @@ main( int argc, char* argv[] )
|
||||
<< ", s=\"" << s << "\"" );
|
||||
|
||||
// This shouldn't appear in log output:
|
||||
FG_LOG( FG_EVENT, FG_DEBUG, "event::debug "
|
||||
SG_LOG( SG_EVENT, SG_DEBUG, "event::debug "
|
||||
<< "- this should be seen - "
|
||||
<< "d=" << d
|
||||
<< ", s=\"" << s << "\"" );
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#ifdef FG_MATH_EXCEPTION_CLASH
|
||||
#ifdef SG_MATH_EXCEPTION_CLASH
|
||||
# define exception c_exception
|
||||
#endif
|
||||
#include <math.h>
|
||||
@@ -62,7 +62,7 @@ void CelestialBody::updatePosition(double mjd, Star *ourSun)
|
||||
actTime = sgCalcActTime(mjd);
|
||||
|
||||
// calcualate the angle bewteen ecliptic and equatorial coordinate system
|
||||
ecl = DEG_TO_RAD * (23.4393 - 3.563E-7 *actTime);
|
||||
ecl = SGD_DEGREES_TO_RADIANS * (23.4393 - 3.563E-7 *actTime);
|
||||
|
||||
eccAnom = sgCalcEccAnom(M, e); //calculate the eccentric anomaly
|
||||
xv = a * (cos(eccAnom) - e);
|
||||
@@ -88,7 +88,7 @@ void CelestialBody::updatePosition(double mjd, Star *ourSun)
|
||||
ze = yg * sin(ecl) + zg * cos(ecl);
|
||||
rightAscension = atan2(ye, xe);
|
||||
declination = atan2(ze, sqrt(xe*xe + ye*ye));
|
||||
/* FG_LOG(FG_GENERAL, FG_INFO, "Planet found at : "
|
||||
/* SG_LOG(SG_GENERAL, SG_INFO, "Planet found at : "
|
||||
<< rightAscension << " (ra), " << declination << " (dec)" ); */
|
||||
|
||||
//calculate some variables specific to calculating the magnitude
|
||||
@@ -107,7 +107,7 @@ void CelestialBody::updatePosition(double mjd, Star *ourSun)
|
||||
tmp = -1.0;
|
||||
}
|
||||
|
||||
FV = RAD_TO_DEG * acos( tmp );
|
||||
FV = SGD_RADIANS_TO_DEGREES * acos( tmp );
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@@ -152,7 +152,7 @@ double CelestialBody::sgCalcEccAnom(double M, double e)
|
||||
diff = fabs(E0 - E1);
|
||||
E0 = E1;
|
||||
}
|
||||
while (diff > (DEG_TO_RAD * 0.001));
|
||||
while (diff > (SGD_DEGREES_TO_RADIANS * 0.001));
|
||||
return E0;
|
||||
}
|
||||
return eccAnom;
|
||||
|
||||
@@ -150,10 +150,10 @@ inline CelestialBody::CelestialBody(double Nf, double Ns,
|
||||
inline void CelestialBody::updateOrbElements(double mjd)
|
||||
{
|
||||
double actTime = sgCalcActTime(mjd);
|
||||
M = DEG_TO_RAD * (MFirst + (MSec * actTime));
|
||||
w = DEG_TO_RAD * (wFirst + (wSec * actTime));
|
||||
N = DEG_TO_RAD * (NFirst + (NSec * actTime));
|
||||
i = DEG_TO_RAD * (iFirst + (iSec * actTime));
|
||||
M = SGD_DEGREES_TO_RADIANS * (MFirst + (MSec * actTime));
|
||||
w = SGD_DEGREES_TO_RADIANS * (wFirst + (wSec * actTime));
|
||||
N = SGD_DEGREES_TO_RADIANS * (NFirst + (NSec * actTime));
|
||||
i = SGD_DEGREES_TO_RADIANS * (iFirst + (iSec * actTime));
|
||||
e = eFirst + (eSec * actTime);
|
||||
a = aFirst + (aSec * actTime);
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ SGEphemeris::SGEphemeris( const string &path ) {
|
||||
saturn = new Saturn;
|
||||
uranus = new Uranus;
|
||||
neptune = new Neptune;
|
||||
stars = new SGStarData( FGPath(path) );
|
||||
stars = new SGStarData( SGPath(path) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// ephemeris.hxx -- Top level class for calculating current positions of
|
||||
// astronomical objects
|
||||
//
|
||||
/** \file ephemeris.hxx
|
||||
* Top level class for calculating current positions of astronomical objects.
|
||||
*/
|
||||
|
||||
// Top level interface written by Curtis Olson, started March 2000.
|
||||
//
|
||||
// All the core code underneath this is written by Durk Talsma. See
|
||||
@@ -30,10 +31,6 @@
|
||||
#define _EPHEMERIS_HXX
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <plib/sg.h>
|
||||
|
||||
#include <simgear/ephemeris/star.hxx>
|
||||
@@ -48,6 +45,28 @@
|
||||
#include <simgear/ephemeris/stardata.hxx>
|
||||
|
||||
|
||||
/** Ephemeris class
|
||||
*
|
||||
* Written by Durk Talsma <d.talsma@direct.a2000.nl> and Curtis Olson
|
||||
* <curt@flightgear.org>
|
||||
*
|
||||
* Introduction
|
||||
*
|
||||
* The SGEphemeris class computes and stores the positions of the Sun,
|
||||
* the Moon, the planets, and the brightest stars. These positions
|
||||
* can then be used to accurately render the dominant visible items in
|
||||
* the Earth's sky. Note, this class isn't intended for use in an
|
||||
* interplanetary/interstellar/intergalactic type application. It is
|
||||
* calculates everything relative to the Earth and is therefore best
|
||||
* suited for Earth centric applications.
|
||||
*
|
||||
* The positions of the various astronomical objects are time
|
||||
* dependent, so to maintain accuracy, you will need to periodically
|
||||
* call the update() method. The SGTime class conveniently provides
|
||||
* the two time related values you need to pass to the update()
|
||||
* method.
|
||||
*/
|
||||
|
||||
class SGEphemeris {
|
||||
|
||||
Star *our_sun;
|
||||
@@ -71,40 +90,84 @@ class SGEphemeris {
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
/**
|
||||
* Constructor.
|
||||
* This creates an instance of the SGEphemeris object. When
|
||||
* calling the constructor you need to provide a path pointing to
|
||||
* your star database file.
|
||||
* @param path path to your star database */
|
||||
SGEphemeris( const string &path );
|
||||
|
||||
// Destructor
|
||||
/** Destructor */
|
||||
~SGEphemeris( void );
|
||||
|
||||
// Update (recalculate) the positions of all objects for the
|
||||
// specified time
|
||||
/**
|
||||
* Update (recalculate) the positions of all objects for the
|
||||
* specified time. The update() method requires you to pass in
|
||||
* the current modified Julian date, the current local sidereal
|
||||
* time, and the current latitude. The update() method is designed
|
||||
* to be called by the host application before every frame.
|
||||
* @param mjd modified julian date
|
||||
* @param lst current local sidereal time
|
||||
* @param lat current latitude
|
||||
*/
|
||||
void update(double mjd, double lst, double lat);
|
||||
|
||||
// sun
|
||||
/**
|
||||
* @return a pointer to a Star class containing all the positional
|
||||
* information for Earth's Sun.
|
||||
*/
|
||||
inline Star *get_sun() const { return our_sun; }
|
||||
|
||||
/** @return the right ascension of the Sun. */
|
||||
inline double getSunRightAscension() const {
|
||||
return our_sun->getRightAscension();
|
||||
}
|
||||
|
||||
/** @return the declination of the Sun. */
|
||||
inline double getSunDeclination() const {
|
||||
return our_sun->getDeclination();
|
||||
}
|
||||
|
||||
// moon
|
||||
/**
|
||||
* @return a pointer to a Moon class containing all the positional
|
||||
* information for Earth's Moon.
|
||||
*/
|
||||
inline MoonPos *get_moon() const { return moon; }
|
||||
|
||||
/** @return the right ascension of the Moon. */
|
||||
inline double getMoonRightAscension() const {
|
||||
return moon->getRightAscension();
|
||||
}
|
||||
|
||||
/** @return the declination of the Moon. */
|
||||
inline double getMoonDeclination() const {
|
||||
return moon->getDeclination();
|
||||
}
|
||||
|
||||
// planets
|
||||
/** @return the numbers of defined planets. */
|
||||
inline int getNumPlanets() const { return nplanets; }
|
||||
|
||||
/**
|
||||
* Returns a pointer to an array of planet data in sgdVec3
|
||||
* format. (See plib.sourceforge.net for information on plib and
|
||||
* the ``sg'' package.) An sgdVec3 is a 3 element double
|
||||
* array. The first element is the right ascension of the planet,
|
||||
* the second is the declination, and the third is the magnitude.
|
||||
* @return planets array
|
||||
*/
|
||||
inline sgdVec3 *getPlanets() { return planets; }
|
||||
|
||||
// planets
|
||||
/** @return the numbers of defined stars. */
|
||||
inline int getNumStars() const { return stars->getNumStars(); }
|
||||
|
||||
/**
|
||||
* Returns a pointer to an array of star data in sgdVec3
|
||||
* format. An The first element of the sgdVec3 is the right
|
||||
* ascension of the planet, the second is the declination, and the
|
||||
* third is the magnitude.
|
||||
* @returns star array
|
||||
*/
|
||||
inline sgdVec3 *getStars() { return stars->getStars(); }
|
||||
};
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/misc/fgpath.hxx>
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
# define exception c_exception
|
||||
@@ -92,7 +91,7 @@ void MoonPos::updatePosition(double mjd, double lst, double lat, Star *ourSun)
|
||||
|
||||
// calculate the angle between ecliptic and equatorial coordinate system
|
||||
// in Radians
|
||||
ecl = ((DEG_TO_RAD * 23.4393) - (DEG_TO_RAD * 3.563E-7) * actTime);
|
||||
ecl = ((SGD_DEGREES_TO_RADIANS * 23.4393) - (SGD_DEGREES_TO_RADIANS * 3.563E-7) * actTime);
|
||||
eccAnom = sgCalcEccAnom(M, e); // Calculate the eccentric anomaly
|
||||
xv = a * (cos(eccAnom) - e);
|
||||
yv = a * (sqrt(1.0 - e*e) * sin(eccAnom));
|
||||
@@ -116,7 +115,7 @@ void MoonPos::updatePosition(double mjd, double lst, double lat, Star *ourSun)
|
||||
D = Lm - Ls;
|
||||
F = Lm - N;
|
||||
|
||||
lonEcl += DEG_TO_RAD * (-1.274 * sin (M - 2*D)
|
||||
lonEcl += SGD_DEGREES_TO_RADIANS * (-1.274 * sin (M - 2*D)
|
||||
+0.658 * sin (2*D)
|
||||
-0.186 * sin(ourSun->getM())
|
||||
-0.059 * sin(2*M - 2*D)
|
||||
@@ -129,7 +128,7 @@ void MoonPos::updatePosition(double mjd, double lst, double lat, Star *ourSun)
|
||||
-0.015 * sin(2*F - 2*D)
|
||||
+0.011 * sin(M - 4*D)
|
||||
);
|
||||
latEcl += DEG_TO_RAD * (-0.173 * sin(F-2*D)
|
||||
latEcl += SGD_DEGREES_TO_RADIANS * (-0.173 * sin(F-2*D)
|
||||
-0.055 * sin(M - F - 2*D)
|
||||
-0.046 * sin(M + F - 2*D)
|
||||
+0.033 * sin(F + 2*D)
|
||||
@@ -138,7 +137,7 @@ void MoonPos::updatePosition(double mjd, double lst, double lat, Star *ourSun)
|
||||
r += (-0.58 * cos(M - 2*D)
|
||||
-0.46 * cos(2*D)
|
||||
);
|
||||
// FG_LOG(FG_GENERAL, FG_INFO, "Running moon update");
|
||||
// SG_LOG(SG_GENERAL, SG_INFO, "Running moon update");
|
||||
xg = r * cos(lonEcl) * cos(latEcl);
|
||||
yg = r * sin(lonEcl) * cos(latEcl);
|
||||
zg = r * sin(latEcl);
|
||||
@@ -150,9 +149,9 @@ void MoonPos::updatePosition(double mjd, double lst, double lat, Star *ourSun)
|
||||
geoRa = atan2(ye, xe);
|
||||
geoDec = atan2(ze, sqrt(xe*xe + ye*ye));
|
||||
|
||||
/* FG_LOG( FG_GENERAL, FG_INFO,
|
||||
"(geocentric) geoRa = (" << (RAD_TO_DEG * geoRa)
|
||||
<< "), geoDec= (" << (RAD_TO_DEG * geoDec) << ")" ); */
|
||||
/* SG_LOG( SG_GENERAL, SG_INFO,
|
||||
"(geocentric) geoRa = (" << (SGD_RADIANS_TO_DEGREES * geoRa)
|
||||
<< "), geoDec= (" << (SGD_RADIANS_TO_DEGREES * geoDec) << ")" ); */
|
||||
|
||||
|
||||
// Given the moon's geocentric ra and dec, calculate its
|
||||
@@ -162,30 +161,40 @@ void MoonPos::updatePosition(double mjd, double lst, double lat, Star *ourSun)
|
||||
// First calculate the moon's parrallax, that is, the apparent size of the
|
||||
// (equatorial) radius of the earth, as seen from the moon
|
||||
mpar = asin ( 1 / r);
|
||||
// FG_LOG( FG_GENERAL, FG_INFO, "r = " << r << " mpar = " << mpar );
|
||||
// FG_LOG( FG_GENERAL, FG_INFO, "lat = " << f->get_Latitude() );
|
||||
// SG_LOG( SG_GENERAL, SG_INFO, "r = " << r << " mpar = " << mpar );
|
||||
// SG_LOG( SG_GENERAL, SG_INFO, "lat = " << f->get_Latitude() );
|
||||
|
||||
gclat = lat - 0.003358 *
|
||||
sin (2 * DEG_TO_RAD * lat );
|
||||
// FG_LOG( FG_GENERAL, FG_INFO, "gclat = " << gclat );
|
||||
sin (2 * SGD_DEGREES_TO_RADIANS * lat );
|
||||
// SG_LOG( SG_GENERAL, SG_INFO, "gclat = " << gclat );
|
||||
|
||||
rho = 0.99883 + 0.00167 * cos(2 * DEG_TO_RAD * lat);
|
||||
// FG_LOG( FG_GENERAL, FG_INFO, "rho = " << rho );
|
||||
rho = 0.99883 + 0.00167 * cos(2 * SGD_DEGREES_TO_RADIANS * lat);
|
||||
// SG_LOG( SG_GENERAL, SG_INFO, "rho = " << rho );
|
||||
|
||||
if (geoRa < 0)
|
||||
geoRa += (2*FG_PI);
|
||||
geoRa += (2*SGD_PI);
|
||||
|
||||
HA = lst - (3.8197186 * geoRa);
|
||||
/* FG_LOG( FG_GENERAL, FG_INFO, "t->getLst() = " << t->getLst()
|
||||
/* SG_LOG( SG_GENERAL, SG_INFO, "t->getLst() = " << t->getLst()
|
||||
<< " HA = " << HA ); */
|
||||
|
||||
g = atan (tan(gclat) / cos ((HA / 3.8197186)));
|
||||
// FG_LOG( FG_GENERAL, FG_INFO, "g = " << g );
|
||||
// SG_LOG( SG_GENERAL, SG_INFO, "g = " << g );
|
||||
|
||||
rightAscension = geoRa - mpar * rho * cos(gclat) * sin(HA) / cos (geoDec);
|
||||
declination = geoDec - mpar * rho * sin (gclat) * sin (g - geoDec) / sin(g);
|
||||
if (fabs(lat) > 0) {
|
||||
declination
|
||||
= geoDec - mpar * rho * sin (gclat) * sin (g - geoDec) / sin(g);
|
||||
} else {
|
||||
declination = geoDec;
|
||||
// cerr << "Geocentric vs. Topocentric position" << endl;
|
||||
// cerr << "RA (difference) : "
|
||||
// << SGD_RADIANS_TO_DEGREES * (geoRa - rightAscension) << endl;
|
||||
// cerr << "Dec (difference) : "
|
||||
// << SGD_RADIANS_TO_DEGREES * (geoDec - declination) << endl;
|
||||
}
|
||||
|
||||
/* FG_LOG( FG_GENERAL, FG_INFO,
|
||||
"Ra = (" << (RAD_TO_DEG *rightAscension)
|
||||
<< "), Dec= (" << (RAD_TO_DEG *declination) << ")" ); */
|
||||
/* SG_LOG( SG_GENERAL, SG_INFO,
|
||||
"Ra = (" << (SGD_RADIANS_TO_DEGREES *rightAscension)
|
||||
<< "), Dec= (" << (SGD_RADIANS_TO_DEGREES *declination) << ")" ); */
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ void Star::updatePosition(double mjd)
|
||||
updateOrbElements(mjd);
|
||||
|
||||
actTime = sgCalcActTime(mjd);
|
||||
ecl = DEG_TO_RAD * (23.4393 - 3.563E-7 * actTime); // Angle in Radians
|
||||
ecl = SGD_DEGREES_TO_RADIANS * (23.4393 - 3.563E-7 * actTime); // Angle in Radians
|
||||
eccAnom = sgCalcEccAnom(M, e); // Calculate the eccentric Anomaly (also known as solving Kepler's equation)
|
||||
|
||||
xv = cos(eccAnom) - e;
|
||||
|
||||
@@ -23,20 +23,20 @@
|
||||
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/misc/fgstream.hxx>
|
||||
#include <simgear/misc/sgstream.hxx>
|
||||
|
||||
#include "stardata.hxx"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
FG_USING_STD(getline);
|
||||
#if defined (_MSC_VER) || defined (SG_HAVE_NATIVE_SGI_COMPILERS)
|
||||
SG_USING_STD(getline);
|
||||
#endif
|
||||
|
||||
// Constructor
|
||||
SGStarData::SGStarData() {
|
||||
}
|
||||
|
||||
SGStarData::SGStarData( FGPath path ) {
|
||||
data_path = FGPath( path );
|
||||
SGStarData::SGStarData( SGPath path ) {
|
||||
data_path = SGPath( path );
|
||||
load();
|
||||
}
|
||||
|
||||
@@ -54,11 +54,11 @@ bool SGStarData::load() {
|
||||
|
||||
// build the full path name to the stars data base file
|
||||
data_path.append( "stars" );
|
||||
FG_LOG( FG_ASTRO, FG_INFO, " Loading stars from " << data_path.str() );
|
||||
SG_LOG( SG_ASTRO, SG_INFO, " Loading stars from " << data_path.str() );
|
||||
|
||||
fg_gzifstream in( data_path.str() );
|
||||
sg_gzifstream in( data_path.str() );
|
||||
if ( ! in.is_open() ) {
|
||||
FG_LOG( FG_ASTRO, FG_ALERT, "Cannot open star file: "
|
||||
SG_LOG( SG_ASTRO, SG_ALERT, "Cannot open star file: "
|
||||
<< data_path.str() );
|
||||
exit(-1);
|
||||
}
|
||||
@@ -116,7 +116,7 @@ bool SGStarData::load() {
|
||||
++nstars;
|
||||
}
|
||||
|
||||
FG_LOG( FG_ASTRO, FG_INFO, " Loaded " << nstars << " stars" );
|
||||
SG_LOG( SG_ASTRO, SG_INFO, " Loaded " << nstars << " stars" );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
#include <plib/sg.h>
|
||||
|
||||
#include <simgear/misc/fgpath.hxx>
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
|
||||
|
||||
#define SG_MAX_STARS 850
|
||||
@@ -39,13 +39,13 @@ class SGStarData {
|
||||
int nstars;
|
||||
sgdVec3 *stars;
|
||||
|
||||
FGPath data_path;
|
||||
SGPath data_path;
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
SGStarData();
|
||||
SGStarData( FGPath path );
|
||||
SGStarData( SGPath path );
|
||||
|
||||
// Destructor
|
||||
~SGStarData();
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
/**************************************************************************
|
||||
* fg_zlib.h -- a zlib wrapper to replace zlib calls with normal uncompressed
|
||||
* calls for systems that have problems building zlib.
|
||||
*
|
||||
* Written by Curtis Olson, started April 1998.
|
||||
*
|
||||
* Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* $Id$
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#ifndef _FG_ZLIB_H
|
||||
#define _FG_ZLIB_H
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef AVOID_USING_ZLIB
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define fgFile FILE *
|
||||
|
||||
/* fgFile fgopen(char *filename, const char *flags) */
|
||||
#define fgopen(P, F) (fopen((P), (F)))
|
||||
|
||||
/* int fgseek(fgFile *file, long offset, int whence) */
|
||||
#define fgseek(F, O, W) (fseek((F), (O), (W)))
|
||||
|
||||
/* fgread(fgFile file, void *buf, int size); */
|
||||
#define fgread(F, B, S) (fread((B), (S), 1, (F)))
|
||||
|
||||
/* int fggets(fgFile fd, char *buffer, int len) */
|
||||
#define fggets(F, B, L) (fgets((B), (L), (F)))
|
||||
|
||||
/* int fgclose(fgFile fd) */
|
||||
#define fgclose(F) (fclose((F)))
|
||||
#else
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
#include <zlib.h>
|
||||
#else
|
||||
#include <simgear/zlib/zlib.h>
|
||||
#endif
|
||||
|
||||
#define fgFile gzFile
|
||||
|
||||
/* fgFile fgopen(char *filename, const char *flags) */
|
||||
#define fgopen(P, F) (gzopen((P), (F)))
|
||||
|
||||
/* int fgseek(fgFile *file, long offset, int whence) */
|
||||
#define fgseek(F, O, W) (gzseek((F), (O), (W)))
|
||||
|
||||
/* fgread(fgFile file, void *buf, int size); */
|
||||
#define fgread(F, B, S) (gzread((F), (B), (S)))
|
||||
|
||||
/* int fggets(fgFile fd, char *buffer, int len) */
|
||||
#define fggets(F, B, L) (gzgets((F), (B), (L)))
|
||||
|
||||
/* int fgclose(fgFile fd) */
|
||||
#define fgclose(F) (gzclose((F)))
|
||||
|
||||
#endif /* #ifdef AVOID_USING_ZLIB #else #endif */
|
||||
|
||||
|
||||
#endif /* _FG_ZLIB_H */
|
||||
|
||||
|
||||
@@ -4,22 +4,45 @@ lib_LIBRARIES = libsgio.a
|
||||
|
||||
include_HEADERS = \
|
||||
iochannel.hxx \
|
||||
lowlevel.hxx \
|
||||
sg_binobj.hxx \
|
||||
sg_file.hxx \
|
||||
sg_serial.hxx \
|
||||
sg_socket.hxx
|
||||
|
||||
libsgio_a_SOURCES = \
|
||||
iochannel.cxx \
|
||||
lowlevel.cxx \
|
||||
sg_binobj.cxx \
|
||||
sg_file.cxx \
|
||||
sg_serial.cxx \
|
||||
sg_socket.cxx
|
||||
|
||||
INCLUDES += -I$(top_srcdir)
|
||||
|
||||
noinst_PROGRAMS = socktest
|
||||
noinst_PROGRAMS = decode_binobj socktest lowtest
|
||||
|
||||
socktest_SOURCES = socktest.cxx
|
||||
|
||||
socktest_LDADD = \
|
||||
$(top_builddir)/simgear/bucket/libsgbucket.a \
|
||||
$(top_builddir)/simgear/io/libsgio.a \
|
||||
$(top_builddir)/simgear/debug/libsgdebug.a \
|
||||
$(top_builddir)/simgear/misc/libsgmisc.a \
|
||||
$(top_builddir)/simgear/xml/libsgxml.a \
|
||||
-lz
|
||||
|
||||
lowtest_SOURCES = lowtest.cxx
|
||||
|
||||
lowtest_LDADD = \
|
||||
$(top_builddir)/simgear/io/libsgio.a
|
||||
|
||||
decode_binobj_SOURCES = decode_binobj.cxx
|
||||
|
||||
decode_binobj_LDADD = \
|
||||
$(top_builddir)/simgear/io/libsgio.a \
|
||||
$(top_builddir)/simgear/debug/libsgdebug.a
|
||||
$(top_builddir)/simgear/bucket/libsgbucket.a \
|
||||
$(top_builddir)/simgear/misc/libsgmisc.a \
|
||||
$(top_builddir)/simgear/debug/libsgdebug.a \
|
||||
$(top_builddir)/simgear/xml/libsgxml.a \
|
||||
-lz
|
||||
|
||||
115
simgear/io/decode_binobj.cxx
Normal file
115
simgear/io/decode_binobj.cxx
Normal file
@@ -0,0 +1,115 @@
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include STL_IOSTREAM
|
||||
|
||||
#if !defined(SG_HAVE_NATIVE_SGI_COMPILERS)
|
||||
SG_USING_STD(cout);
|
||||
SG_USING_STD(endl);
|
||||
#endif
|
||||
|
||||
#include "sg_binobj.hxx"
|
||||
|
||||
|
||||
int main( int argc, char **argv ) {
|
||||
int i, j;
|
||||
|
||||
// check usage
|
||||
if ( argc != 2 ) {
|
||||
cout << "Usage: " << argv[0] << " binary_obj_file" << endl;
|
||||
}
|
||||
|
||||
SGBinObject obj;
|
||||
bool result = obj.read_bin( argv[1] );
|
||||
if ( !result ) {
|
||||
cout << "error loading: " << argv[1] << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
cout << "# FGFS Scenery" << endl;
|
||||
cout << "# Version " << obj.get_version() << endl;
|
||||
cout << endl;
|
||||
|
||||
printf("# gbs %.5f %.5f %.5f %.2f\n", obj.get_gbs_center().x(),
|
||||
obj.get_gbs_center().y(), obj.get_gbs_center().z(),
|
||||
obj.get_gbs_radius());
|
||||
cout << endl;
|
||||
|
||||
point_list nodes = obj.get_wgs84_nodes();
|
||||
cout << "# vertex list" << endl;
|
||||
for ( i = 0; i < (int)nodes.size(); ++i ) {
|
||||
printf("v %.5f %.5f %.5f\n", nodes[i].x(), nodes[i].y(), nodes[i].z() );
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
point_list normals = obj.get_normals();
|
||||
cout << "# vertex normal list" << endl;
|
||||
for ( i = 0; i < (int)normals.size(); ++i ) {
|
||||
printf("vn %.5f %.5f %.5f\n",
|
||||
normals[i].x(), normals[i].y(), normals[i].z() );
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
point_list texcoords = obj.get_texcoords();
|
||||
cout << "# texture coordinate list" << endl;
|
||||
for ( i = 0; i < (int)texcoords.size(); ++i ) {
|
||||
printf("vt %.5f %.5f\n",
|
||||
texcoords[i].x(), texcoords[i].y() );
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
cout << "# triangle groups" << endl;
|
||||
cout << endl;
|
||||
|
||||
string material;
|
||||
int_list vertex_index;
|
||||
int_list tex_index;
|
||||
|
||||
// generate triangles
|
||||
string_list tri_materials = obj.get_tri_materials();
|
||||
group_list tris_v = obj.get_tris_v();
|
||||
group_list tris_tc = obj.get_tris_tc();
|
||||
for ( i = 0; i < (int)tris_v.size(); ++i ) {
|
||||
material = tri_materials[i];
|
||||
vertex_index = tris_v[i];
|
||||
tex_index = tris_tc[i];
|
||||
cout << "# usemtl " << material << endl;
|
||||
cout << "f ";
|
||||
for ( j = 0; j < (int)vertex_index.size(); ++j ) {
|
||||
cout << vertex_index[j] << "/" << tex_index[j] << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
// generate strips
|
||||
string_list strip_materials = obj.get_strip_materials();
|
||||
group_list strips_v = obj.get_strips_v();
|
||||
group_list strips_tc = obj.get_strips_tc();
|
||||
for ( i = 0; i < (int)strips_v.size(); ++i ) {
|
||||
material = strip_materials[i];
|
||||
vertex_index = strips_v[i];
|
||||
tex_index = strips_tc[i];
|
||||
cout << "# usemtl " << material << endl;
|
||||
cout << "ts ";
|
||||
for ( j = 0; j < (int)vertex_index.size(); ++j ) {
|
||||
cout << vertex_index[j] << "/" << tex_index[j] << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
// generate fans
|
||||
string_list fan_materials = obj.get_fan_materials();
|
||||
group_list fans_v = obj.get_fans_v();
|
||||
group_list fans_tc = obj.get_fans_tc();
|
||||
for ( i = 0; i < (int)fans_v.size(); ++i ) {
|
||||
material = fan_materials[i];
|
||||
vertex_index = fans_v[i];
|
||||
tex_index = fans_tc[i];
|
||||
cout << "# usemtl " << material << endl;
|
||||
cout << "tf ";
|
||||
for ( j = 0; j < (int)vertex_index.size(); ++j ) {
|
||||
cout << vertex_index[j] << "/" << tex_index[j] << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
// iochannel.hxx -- High level IO channel class
|
||||
//
|
||||
/**
|
||||
* \file iochannel.hxx
|
||||
* High level IO channel base class.
|
||||
*/
|
||||
|
||||
// Written by Curtis Olson, started November 1999.
|
||||
//
|
||||
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
|
||||
@@ -32,12 +35,16 @@
|
||||
#include STL_STRING
|
||||
#include <vector>
|
||||
|
||||
FG_USING_STD(vector);
|
||||
FG_USING_STD(string);
|
||||
SG_USING_STD(vector);
|
||||
SG_USING_STD(string);
|
||||
|
||||
|
||||
#define SG_IO_MAX_MSG_SIZE 16384
|
||||
|
||||
/**
|
||||
* Specify if this is a read (IN), write (OUT), or r/w (BI) directional
|
||||
* channel
|
||||
*/
|
||||
enum SGProtocolDir {
|
||||
SG_IO_NONE = 0,
|
||||
SG_IO_IN = 1,
|
||||
@@ -45,13 +52,27 @@ enum SGProtocolDir {
|
||||
SG_IO_BI = 3
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Specify the channel type
|
||||
*/
|
||||
enum SGChannelType {
|
||||
sgFileType = 0,
|
||||
sgSerialType = 1,
|
||||
sgSocketType = 2
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The SGIOChannel base class provides a consistent method for
|
||||
* applications to communication through various mediums. By providing
|
||||
* a base class with multiple derived classes, and application such as
|
||||
* FlightGear can implement a way to speak any protocol via any kind
|
||||
* of I/O channel.
|
||||
*
|
||||
* All of the SGIOChannel derived classes have exactly the same usage
|
||||
* interface once an instance has been created.
|
||||
*
|
||||
*/
|
||||
class SGIOChannel {
|
||||
|
||||
SGChannelType type;
|
||||
@@ -60,14 +81,75 @@ class SGIOChannel {
|
||||
|
||||
public:
|
||||
|
||||
/** Constructor */
|
||||
SGIOChannel();
|
||||
|
||||
/** Destructor */
|
||||
virtual ~SGIOChannel();
|
||||
|
||||
/** Open a channel.
|
||||
* @param d channel communication "direction"
|
||||
* Direction can be one of:
|
||||
* - SG_IO_IN - data will be flowing into this object to the application.
|
||||
* - SG_IO_OUT - data will be flowing out of this object from the
|
||||
* application.
|
||||
* - SG_IO_BI - data will be flowing in both directions.
|
||||
* - SG_IO_NONE - data will not be flowing in either direction.
|
||||
* This is here for the sake of completeness.
|
||||
* @return result of open
|
||||
*/
|
||||
virtual bool open( const SGProtocolDir d );
|
||||
|
||||
/**
|
||||
* The read() method is modeled after the read() Unix system
|
||||
* call. You must provide a pointer to a character buffer that has
|
||||
* enough allocated space for your potential read. You can also
|
||||
* specify the maximum number of bytes allowed for this particular
|
||||
* read. The actual number of bytes read is returned. You are
|
||||
* responsible to ensure that the size of buf is large enough to
|
||||
* accomodate your input message
|
||||
* @param buf a char pointer to your input buffer
|
||||
* @param length max number of bytes to read
|
||||
* @return number of bytes read
|
||||
*/
|
||||
virtual int read( char *buf, int length );
|
||||
|
||||
/**
|
||||
* The readline() method is similar to read() except that it will
|
||||
* stop at the first end of line encountered in the input buffer.
|
||||
* @param buf a char pointer to your input buffer
|
||||
* @param length max number of bytes to read
|
||||
* @return number of bytes read
|
||||
*/
|
||||
virtual int readline( char *buf, int length );
|
||||
|
||||
|
||||
/**
|
||||
* The write() method is modeled after the write() Unix system
|
||||
* call and is analogous to the read() method. You provide a
|
||||
* pointer to a buffer of data, and then length of that data to be
|
||||
* written out. The number of bytes written is returned.
|
||||
* @param buf a char pointer to your output buffer
|
||||
* @param length number of bytes to write
|
||||
* @return number of bytes written
|
||||
*/
|
||||
virtual int write( const char *buf, const int length );
|
||||
|
||||
/**
|
||||
* The writestring() method is a simple wrapper that will
|
||||
* calculate the length of a null terminated character array and
|
||||
* write it to the output channel.
|
||||
* @param buf a char pointer to your output buffer
|
||||
* @return number of bytes written
|
||||
*/
|
||||
virtual int writestring( const char *str );
|
||||
|
||||
/**
|
||||
* The close() method is modeled after the close() Unix system
|
||||
* call and will close an open device. You should call this method
|
||||
* when you are done using your IO class, before it is destructed.
|
||||
* @return result of close
|
||||
*/
|
||||
virtual bool close();
|
||||
|
||||
inline void set_type( SGChannelType t ) { type = t; }
|
||||
|
||||
497
simgear/io/lowlevel.cxx
Normal file
497
simgear/io/lowlevel.cxx
Normal file
@@ -0,0 +1,497 @@
|
||||
// lowlevel.cxx -- routines to handle lowlevel compressed binary IO of
|
||||
// various datatypes
|
||||
//
|
||||
// Shamelessly adapted from plib (plib.sourceforge.net) January 2001
|
||||
//
|
||||
// Original version Copyright (C) 2000 the plib team
|
||||
// Local changes Copyright (C) 2000 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$
|
||||
|
||||
|
||||
#include <string.h> // for memcpy()
|
||||
|
||||
#include "lowlevel.hxx"
|
||||
|
||||
|
||||
static int read_error = false ;
|
||||
static int write_error = false ;
|
||||
|
||||
void sgClearReadError() { read_error = false; }
|
||||
void sgClearWriteError() { write_error = false; }
|
||||
int sgReadError() { return read_error ; }
|
||||
int sgWriteError() { return write_error ; }
|
||||
|
||||
|
||||
void sgReadChar ( gzFile fd, char *var )
|
||||
{
|
||||
if ( gzread ( fd, var, sizeof(char) ) != sizeof(char) ) {
|
||||
read_error = true ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sgWriteChar ( gzFile fd, const char var )
|
||||
{
|
||||
if ( gzwrite ( fd, (void *)(&var), sizeof(char) ) != sizeof(char) ) {
|
||||
write_error = true ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sgReadFloat ( gzFile fd, float *var )
|
||||
{
|
||||
if ( gzread ( fd, var, sizeof(float) ) != sizeof(float) ) {
|
||||
read_error = true ;
|
||||
}
|
||||
if ( sgIsBigEndian() ) {
|
||||
sgEndianSwap( (unsigned int*)var);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sgWriteFloat ( gzFile fd, const float var )
|
||||
{
|
||||
if ( sgIsBigEndian() ) {
|
||||
sgEndianSwap( (unsigned int*)&var);
|
||||
}
|
||||
if ( gzwrite ( fd, (void *)(&var), sizeof(float) ) != sizeof(float) ) {
|
||||
write_error = true ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sgReadDouble ( gzFile fd, double *var )
|
||||
{
|
||||
if ( gzread ( fd, var, sizeof(double) ) != sizeof(double) ) {
|
||||
read_error = true ;
|
||||
}
|
||||
if ( sgIsBigEndian() ) {
|
||||
sgEndianSwap( (uint64*)var);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sgWriteDouble ( gzFile fd, const double var )
|
||||
{
|
||||
if ( sgIsBigEndian() ) {
|
||||
sgEndianSwap( (uint64*)&var);
|
||||
}
|
||||
if ( gzwrite ( fd, (void *)(&var), sizeof(double) ) != sizeof(double) ) {
|
||||
write_error = true ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sgReadUInt ( gzFile fd, unsigned int *var )
|
||||
{
|
||||
if ( gzread ( fd, var, sizeof(unsigned int) ) != sizeof(unsigned int) ) {
|
||||
read_error = true ;
|
||||
}
|
||||
if ( sgIsBigEndian() ) {
|
||||
sgEndianSwap( (unsigned int*)var);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sgWriteUInt ( gzFile fd, const unsigned int var )
|
||||
{
|
||||
if ( sgIsBigEndian() ) {
|
||||
sgEndianSwap( (unsigned int*)&var);
|
||||
}
|
||||
if ( gzwrite ( fd, (void *)(&var), sizeof(unsigned int) )
|
||||
!= sizeof(unsigned int) )
|
||||
{
|
||||
write_error = true ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sgReadInt ( gzFile fd, int *var )
|
||||
{
|
||||
if ( gzread ( fd, var, sizeof(int) ) != sizeof(int) ) {
|
||||
read_error = true ;
|
||||
}
|
||||
if ( sgIsBigEndian() ) {
|
||||
sgEndianSwap( (unsigned int*)var);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sgWriteInt ( gzFile fd, const int var )
|
||||
{
|
||||
if ( sgIsBigEndian() ) {
|
||||
sgEndianSwap( (unsigned int*)&var);
|
||||
}
|
||||
if ( gzwrite ( fd, (void *)(&var), sizeof(int) ) != sizeof(int) ) {
|
||||
write_error = true ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sgReadLong ( gzFile fd, long int *var )
|
||||
{
|
||||
if ( gzread ( fd, var, sizeof(long int) ) != sizeof(long int) ) {
|
||||
read_error = true ;
|
||||
}
|
||||
if ( sgIsBigEndian() ) {
|
||||
sgEndianSwap( (unsigned int*)var);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sgWriteLong ( gzFile fd, const long int var )
|
||||
{
|
||||
if ( sgIsBigEndian() ) {
|
||||
sgEndianSwap( (unsigned int*)&var);
|
||||
}
|
||||
if ( gzwrite ( fd, (void *)(&var), sizeof(long int) )
|
||||
!= sizeof(long int) )
|
||||
{
|
||||
write_error = true ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sgReadLongLong ( gzFile fd, int64 *var )
|
||||
{
|
||||
if ( gzread ( fd, var, sizeof(int64) ) != sizeof(int64) ) {
|
||||
read_error = true ;
|
||||
}
|
||||
if ( sgIsBigEndian() ) {
|
||||
sgEndianSwap( (uint64*)var);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sgWriteLongLong ( gzFile fd, const int64 var )
|
||||
{
|
||||
if ( sgIsBigEndian() ) {
|
||||
sgEndianSwap( (uint64*)&var);
|
||||
}
|
||||
if ( gzwrite ( fd, (void *)(&var), sizeof(int64) )
|
||||
!= sizeof(int64) )
|
||||
{
|
||||
write_error = true ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sgReadUShort ( gzFile fd, unsigned short *var )
|
||||
{
|
||||
if ( gzread ( fd, var, sizeof(unsigned short) ) != sizeof(unsigned short) ){
|
||||
read_error = true ;
|
||||
}
|
||||
if ( sgIsBigEndian() ) {
|
||||
sgEndianSwap( (unsigned short int*)var);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sgWriteUShort ( gzFile fd, const unsigned short var )
|
||||
{
|
||||
if ( sgIsBigEndian() ) {
|
||||
sgEndianSwap( (unsigned short*)&var);
|
||||
}
|
||||
if ( gzwrite ( fd, (void *)(&var), sizeof(unsigned short) )
|
||||
!= sizeof(unsigned short) )
|
||||
{
|
||||
write_error = true ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sgReadShort ( gzFile fd, short *var )
|
||||
{
|
||||
if ( gzread ( fd, var, sizeof(short) ) != sizeof(short) ) {
|
||||
read_error = true ;
|
||||
}
|
||||
if ( sgIsBigEndian() ) {
|
||||
sgEndianSwap( (unsigned short int*)var);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sgWriteShort ( gzFile fd, const short var )
|
||||
{
|
||||
if ( sgIsBigEndian() ) {
|
||||
sgEndianSwap( (unsigned short*)&var);
|
||||
}
|
||||
if ( gzwrite ( fd, (void *)(&var), sizeof(short) ) != sizeof(short) ) {
|
||||
write_error = true ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sgReadFloat ( gzFile fd, const unsigned int n, float *var )
|
||||
{
|
||||
if ( gzread ( fd, var, sizeof(float) * n ) != (int)(sizeof(float) * n) ) {
|
||||
read_error = true ;
|
||||
}
|
||||
if ( sgIsBigEndian() ) {
|
||||
for ( unsigned int i = 0; i < n; ++i ) {
|
||||
sgEndianSwap( (unsigned int*)var++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sgWriteFloat ( gzFile fd, const unsigned int n, const float *var )
|
||||
{
|
||||
if ( sgIsBigEndian() ) {
|
||||
float *swab = new float[n];
|
||||
float *ptr = swab;
|
||||
memcpy( swab, var, sizeof(float) * n );
|
||||
for ( unsigned int i = 0; i < n; ++i ) {
|
||||
sgEndianSwap( (unsigned int*)ptr++);
|
||||
}
|
||||
var = swab;
|
||||
}
|
||||
if ( gzwrite ( fd, (void *)var, sizeof(float) * n )
|
||||
!= (int)(sizeof(float) * n) )
|
||||
{
|
||||
write_error = true ;
|
||||
}
|
||||
}
|
||||
|
||||
void sgReadDouble ( gzFile fd, const unsigned int n, double *var )
|
||||
{
|
||||
if ( gzread ( fd, var, sizeof(double) * n ) != (int)(sizeof(double) * n) ) {
|
||||
read_error = true ;
|
||||
}
|
||||
if ( sgIsBigEndian() ) {
|
||||
for ( unsigned int i = 0; i < n; ++i ) {
|
||||
sgEndianSwap( (uint64*)var++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sgWriteDouble ( gzFile fd, const unsigned int n, const double *var )
|
||||
{
|
||||
if ( sgIsBigEndian() ) {
|
||||
double *swab = new double[n];
|
||||
double *ptr = swab;
|
||||
memcpy( swab, var, sizeof(double) * n );
|
||||
for ( unsigned int i = 0; i < n; ++i ) {
|
||||
sgEndianSwap( (uint64*)ptr++);
|
||||
}
|
||||
var = swab;
|
||||
}
|
||||
if ( gzwrite ( fd, (void *)var, sizeof(double) * n )
|
||||
!= (int)(sizeof(double) * n) )
|
||||
{
|
||||
write_error = true ;
|
||||
}
|
||||
}
|
||||
|
||||
void sgReadBytes ( gzFile fd, const unsigned int n, void *var )
|
||||
{
|
||||
if ( n == 0) return;
|
||||
if ( gzread ( fd, var, n ) != (int)n ) {
|
||||
read_error = true ;
|
||||
}
|
||||
}
|
||||
|
||||
void sgWriteBytes ( gzFile fd, const unsigned int n, const void *var )
|
||||
{
|
||||
if ( n == 0) return;
|
||||
if ( gzwrite ( fd, (void *)var, n ) != (int)n ) {
|
||||
write_error = true ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sgReadUShort ( gzFile fd, const unsigned int n, unsigned short *var )
|
||||
{
|
||||
if ( gzread ( fd, var, sizeof(unsigned short) * n )
|
||||
!= (int)(sizeof(unsigned short) * n) )
|
||||
{
|
||||
read_error = true ;
|
||||
}
|
||||
if ( sgIsBigEndian() ) {
|
||||
for ( unsigned int i = 0; i < n; ++i ) {
|
||||
sgEndianSwap( (unsigned short int*)var++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sgWriteUShort ( gzFile fd, const unsigned int n, const unsigned short *var )
|
||||
{
|
||||
if ( sgIsBigEndian() ) {
|
||||
unsigned short *swab = new unsigned short[n];
|
||||
unsigned short *ptr = swab;
|
||||
memcpy( swab, var, sizeof(unsigned short) * n );
|
||||
for ( unsigned int i = 0; i < n; ++i ) {
|
||||
sgEndianSwap( (unsigned short*)ptr++);
|
||||
}
|
||||
var = swab;
|
||||
}
|
||||
if ( gzwrite ( fd, (void *)var, sizeof(unsigned short) * n )
|
||||
!= (int)(sizeof(unsigned short) * n) )
|
||||
{
|
||||
write_error = true ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void sgReadShort ( gzFile fd, const unsigned int n, short *var )
|
||||
{
|
||||
if ( gzread ( fd, var, sizeof(short) * n )
|
||||
!= (int)(sizeof(short) * n) )
|
||||
{
|
||||
read_error = true ;
|
||||
}
|
||||
if ( sgIsBigEndian() ) {
|
||||
for ( unsigned int i = 0; i < n; ++i ) {
|
||||
sgEndianSwap( (unsigned short int*)var++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sgWriteShort ( gzFile fd, const unsigned int n, const short *var )
|
||||
{
|
||||
if ( sgIsBigEndian() ) {
|
||||
short *swab = new short[n];
|
||||
short *ptr = swab;
|
||||
memcpy( swab, var, sizeof(short) * n );
|
||||
for ( unsigned int i = 0; i < n; ++i ) {
|
||||
sgEndianSwap( (unsigned short*)ptr++);
|
||||
}
|
||||
var = swab;
|
||||
}
|
||||
if ( gzwrite ( fd, (void *)var, sizeof(short) * n )
|
||||
!= (int)(sizeof(short) * n) )
|
||||
{
|
||||
write_error = true ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sgReadUInt ( gzFile fd, const unsigned int n, unsigned int *var )
|
||||
{
|
||||
if ( gzread ( fd, var, sizeof(unsigned int) * n )
|
||||
!= (int)(sizeof(unsigned int) * n) )
|
||||
{
|
||||
read_error = true ;
|
||||
}
|
||||
if ( sgIsBigEndian() ) {
|
||||
for ( unsigned int i = 0; i < n; ++i ) {
|
||||
sgEndianSwap( (unsigned int*)var++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sgWriteUInt ( gzFile fd, const unsigned int n, const unsigned int *var )
|
||||
{
|
||||
if ( sgIsBigEndian() ) {
|
||||
unsigned int *swab = new unsigned int[n];
|
||||
unsigned int *ptr = swab;
|
||||
memcpy( swab, var, sizeof(unsigned int) * n );
|
||||
for ( unsigned int i = 0; i < n; ++i ) {
|
||||
sgEndianSwap( (unsigned int*)ptr++);
|
||||
}
|
||||
var = swab;
|
||||
}
|
||||
if ( gzwrite ( fd, (void *)var, sizeof(unsigned int) * n )
|
||||
!= (int)(sizeof(unsigned int) * n) )
|
||||
{
|
||||
write_error = true ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void sgReadInt ( gzFile fd, const unsigned int n, int *var )
|
||||
{
|
||||
if ( gzread ( fd, var, sizeof(int) * n )
|
||||
!= (int)(sizeof(int) * n) )
|
||||
{
|
||||
read_error = true ;
|
||||
}
|
||||
if ( sgIsBigEndian() ) {
|
||||
for ( unsigned int i = 0; i < n; ++i ) {
|
||||
sgEndianSwap( (unsigned int*)var++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sgWriteInt ( gzFile fd, const unsigned int n, const int *var )
|
||||
{
|
||||
if ( sgIsBigEndian() ) {
|
||||
int *swab = new int[n];
|
||||
int *ptr = swab;
|
||||
memcpy( swab, var, sizeof(int) * n );
|
||||
for ( unsigned int i = 0; i < n; ++i ) {
|
||||
sgEndianSwap( (unsigned int*)ptr++);
|
||||
}
|
||||
var = swab;
|
||||
}
|
||||
if ( gzwrite ( fd, (void *)var, sizeof(int) * n )
|
||||
!= (int)(sizeof(int) * n) )
|
||||
{
|
||||
write_error = true ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define MAX_ENTITY_NAME_LENGTH 1024
|
||||
|
||||
void sgReadString ( gzFile fd, char **var )
|
||||
{
|
||||
int i ;
|
||||
char s [ MAX_ENTITY_NAME_LENGTH ] ;
|
||||
|
||||
for ( i = 0 ; i < MAX_ENTITY_NAME_LENGTH ; i++ ) {
|
||||
int c = gzgetc ( fd ) ;
|
||||
s [ i ] = c ;
|
||||
|
||||
if ( c == '\0' )
|
||||
break ;
|
||||
}
|
||||
|
||||
if ( i >= MAX_ENTITY_NAME_LENGTH-1 )
|
||||
s [ MAX_ENTITY_NAME_LENGTH-1 ] = '\0' ;
|
||||
|
||||
|
||||
if ( s[0] == '\0' )
|
||||
*var = NULL ;
|
||||
else {
|
||||
*var = new char [ strlen(s)+1 ] ;
|
||||
strcpy ( *var, s ) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sgWriteString ( gzFile fd, const char *var )
|
||||
{
|
||||
if ( var != NULL ) {
|
||||
if ( gzwrite ( fd, (void *)var, strlen(var) + 1 ) ==
|
||||
(int)(strlen(var) + 1) )
|
||||
return ;
|
||||
} else {
|
||||
gzputc( fd, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
177
simgear/io/lowlevel.hxx
Normal file
177
simgear/io/lowlevel.hxx
Normal file
@@ -0,0 +1,177 @@
|
||||
// lowlevel.hxx -- routines to handle lowlevel compressed binary IO of
|
||||
// various datatypes
|
||||
//
|
||||
// Shamelessly adapted from plib January 2001
|
||||
//
|
||||
// Original version Copyright (C) 2000 the plib team
|
||||
// Local changes Copyright (C) 2000 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 _SG_LOWLEVEL_HXX
|
||||
#define _SG_LOWLEVEL_HXX
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
# include <zlib.h>
|
||||
#else
|
||||
# include <simgear/zlib/zlib.h>
|
||||
#endif
|
||||
|
||||
#include <plib/sg.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
typedef __int64 int64;
|
||||
typedef __int64 uint64;
|
||||
#else
|
||||
typedef long long int64;
|
||||
typedef unsigned long long uint64;
|
||||
#endif
|
||||
|
||||
// Note that output is written in little endian form (and converted as
|
||||
// necessary for big endian machines)
|
||||
|
||||
void sgReadChar ( gzFile fd, char *var ) ;
|
||||
void sgWriteChar ( gzFile fd, const char var ) ;
|
||||
void sgReadFloat ( gzFile fd, float *var ) ;
|
||||
void sgWriteFloat ( gzFile fd, const float var ) ;
|
||||
void sgReadDouble ( gzFile fd, double *var ) ;
|
||||
void sgWriteDouble ( gzFile fd, const double var ) ;
|
||||
void sgReadUInt ( gzFile fd, unsigned int *var ) ;
|
||||
void sgWriteUInt ( gzFile fd, const unsigned int var ) ;
|
||||
void sgReadInt ( gzFile fd, int *var ) ;
|
||||
void sgWriteInt ( gzFile fd, const int var ) ;
|
||||
void sgReadLong ( gzFile fd, long int *var ) ;
|
||||
void sgWriteLong ( gzFile fd, const long int var ) ;
|
||||
void sgReadLongLong ( gzFile fd, int64 *var ) ;
|
||||
void sgWriteLongLong ( gzFile fd, const int64 var ) ;
|
||||
void sgReadUShort ( gzFile fd, unsigned short *var ) ;
|
||||
void sgWriteUShort ( gzFile fd, const unsigned short var ) ;
|
||||
void sgReadShort ( gzFile fd, short *var ) ;
|
||||
void sgWriteShort ( gzFile fd, const short var ) ;
|
||||
|
||||
void sgReadFloat ( gzFile fd, const unsigned int n, float *var ) ;
|
||||
void sgWriteFloat ( gzFile fd, const unsigned int n, const float *var ) ;
|
||||
void sgReadDouble ( gzFile fd, const unsigned int n, double *var ) ;
|
||||
void sgWriteDouble ( gzFile fd, const unsigned int n, const double *var ) ;
|
||||
void sgReadUInt ( gzFile fd, const unsigned int n, unsigned int *var ) ;
|
||||
void sgWriteUInt ( gzFile fd, const unsigned int n, const unsigned int *var ) ;
|
||||
void sgReadInt ( gzFile fd, const unsigned int n, int *var ) ;
|
||||
void sgWriteInt ( gzFile fd, const unsigned int n, const int *var ) ;
|
||||
void sgReadUShort ( gzFile fd, const unsigned int n, unsigned short *var ) ;
|
||||
void sgWriteUShort ( gzFile fd, const unsigned int n, const unsigned short *var ) ;
|
||||
void sgReadShort ( gzFile fd, const unsigned int n, short *var ) ;
|
||||
void sgWriteShort ( gzFile fd, const unsigned int n, const short *var ) ;
|
||||
void sgReadBytes ( gzFile fd, const unsigned int n, void *var ) ;
|
||||
void sgWriteBytes ( gzFile fd, const unsigned int n, const void *var ) ;
|
||||
|
||||
void sgReadString ( gzFile fd, char **var ) ;
|
||||
void sgWriteString ( gzFile fd, const char *var ) ;
|
||||
|
||||
inline void sgReadVec2 ( gzFile fd, sgVec2 var ) {
|
||||
sgReadFloat ( fd, 2, var ) ;
|
||||
}
|
||||
inline void sgWriteVec2 ( gzFile fd, const sgVec2 var ) {
|
||||
sgWriteFloat ( fd, 2, var ) ;
|
||||
}
|
||||
|
||||
inline void sgReadVec3 ( gzFile fd, sgVec3 var ) {
|
||||
sgReadFloat ( fd, 3, var ) ;
|
||||
}
|
||||
inline void sgWriteVec3 ( gzFile fd, const sgVec3 var ) {
|
||||
sgWriteFloat ( fd, 3, var ) ;
|
||||
}
|
||||
|
||||
inline void sgReaddVec3 ( gzFile fd, sgdVec3 var ) {
|
||||
sgReadDouble ( fd, 3, var ) ;
|
||||
}
|
||||
inline void sgWritedVec3 ( gzFile fd, const sgdVec3 var ) {
|
||||
sgWriteDouble ( fd, 3, var ) ;
|
||||
}
|
||||
|
||||
inline void sgReadVec4 ( gzFile fd, sgVec4 var ) {
|
||||
sgReadFloat ( fd, 4, var ) ;
|
||||
}
|
||||
inline void sgWriteVec4 ( gzFile fd, const sgVec4 var ) {
|
||||
sgWriteFloat ( fd, 4, var ) ;
|
||||
}
|
||||
|
||||
inline void sgReadMat4 ( gzFile fd, sgMat4 var ) {
|
||||
sgReadFloat ( fd, 16, (float *)var ) ;
|
||||
}
|
||||
inline void sgWriteMat4 ( gzFile fd, const sgMat4 var ) {
|
||||
sgWriteFloat ( fd, 16, (float *)var ) ;
|
||||
}
|
||||
|
||||
void sgClearReadError();
|
||||
void sgClearWriteError();
|
||||
int sgReadError();
|
||||
int sgWriteError();
|
||||
|
||||
inline bool sgIsLittleEndian() {
|
||||
static const int sgEndianTest = 1;
|
||||
return (*((char *) &sgEndianTest ) != 0);
|
||||
}
|
||||
|
||||
inline bool sgIsBigEndian() {
|
||||
static const int sgEndianTest = 1;
|
||||
return (*((char *) &sgEndianTest ) == 0);
|
||||
}
|
||||
|
||||
inline void sgEndianSwap(unsigned short *x) {
|
||||
*x =
|
||||
(( *x >> 8 ) & 0x00FF ) |
|
||||
(( *x << 8 ) & 0xFF00 ) ;
|
||||
}
|
||||
|
||||
inline void sgEndianSwap(unsigned int *x) {
|
||||
*x =
|
||||
(( *x >> 24 ) & 0x000000FF ) |
|
||||
(( *x >> 8 ) & 0x0000FF00 ) |
|
||||
(( *x << 8 ) & 0x00FF0000 ) |
|
||||
(( *x << 24 ) & 0xFF000000 ) ;
|
||||
}
|
||||
|
||||
inline void sgEndianSwap(uint64 *x) {
|
||||
#ifndef _MSC_VER
|
||||
*x =
|
||||
(( *x >> 56 ) & 0x00000000000000FFULL ) |
|
||||
(( *x >> 40 ) & 0x000000000000FF00ULL ) |
|
||||
(( *x >> 24 ) & 0x0000000000FF0000ULL ) |
|
||||
(( *x >> 8 ) & 0x00000000FF000000ULL ) |
|
||||
(( *x << 8 ) & 0x000000FF00000000ULL ) |
|
||||
(( *x << 24 ) & 0x0000FF0000000000ULL ) |
|
||||
(( *x << 40 ) & 0x00FF000000000000ULL ) |
|
||||
(( *x << 56 ) & 0xFF00000000000000ULL ) ;
|
||||
#else
|
||||
*x =
|
||||
(( *x >> 56 ) & 0x00000000000000FF ) |
|
||||
(( *x >> 40 ) & 0x000000000000FF00 ) |
|
||||
(( *x >> 24 ) & 0x0000000000FF0000 ) |
|
||||
(( *x >> 8 ) & 0x00000000FF000000 ) |
|
||||
(( *x << 8 ) & 0x000000FF00000000 ) |
|
||||
(( *x << 24 ) & 0x0000FF0000000000 ) |
|
||||
(( *x << 40 ) & 0x00FF000000000000 ) |
|
||||
(( *x << 56 ) & 0xFF00000000000000 ) ;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // _SG_LOWLEVEL_HXX
|
||||
46
simgear/io/lowtest.cxx
Normal file
46
simgear/io/lowtest.cxx
Normal file
@@ -0,0 +1,46 @@
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include STL_IOSTREAM
|
||||
#include "lowlevel.hxx"
|
||||
|
||||
#if !defined(SG_HAVE_NATIVE_SGI_COMPILERS)
|
||||
SG_USING_STD(cout);
|
||||
SG_USING_STD(endl);
|
||||
#endif
|
||||
|
||||
|
||||
static const int sgEndianTest = 1;
|
||||
#define sgIsLittleEndian (*((char *) &sgEndianTest ) != 0)
|
||||
#define sgIsBigEndian (*((char *) &sgEndianTest ) == 0)
|
||||
|
||||
|
||||
int main() {
|
||||
cout << "This machine is ";
|
||||
if ( sgIsLittleEndian ) {
|
||||
cout << "little ";
|
||||
} else {
|
||||
cout << "big ";
|
||||
}
|
||||
cout << "endian" << endl;
|
||||
|
||||
short s = 1111;
|
||||
cout << "short s = " << s << endl;
|
||||
sgEndianSwap((unsigned short *)&s);
|
||||
cout << "short s = " << s << endl;
|
||||
sgEndianSwap((unsigned short *)&s);
|
||||
cout << "short s = " << s << endl;
|
||||
|
||||
int i = 1111111;
|
||||
cout << "int i = " << i << endl;
|
||||
sgEndianSwap((unsigned int *)&i);
|
||||
cout << "int i = " << i << endl;
|
||||
sgEndianSwap((unsigned int *)&i);
|
||||
cout << "int i = " << i << endl;
|
||||
|
||||
double x = 1111111111;
|
||||
cout << "double x = " << x << endl;
|
||||
sgEndianSwap((unsigned long long *)&x);
|
||||
cout << "double x = " << x << endl;
|
||||
sgEndianSwap((unsigned long long *)&x);
|
||||
cout << "double x = " << x << endl;
|
||||
}
|
||||
1006
simgear/io/sg_binobj.cxx
Normal file
1006
simgear/io/sg_binobj.cxx
Normal file
File diff suppressed because it is too large
Load Diff
190
simgear/io/sg_binobj.hxx
Normal file
190
simgear/io/sg_binobj.hxx
Normal file
@@ -0,0 +1,190 @@
|
||||
/**
|
||||
* \file sg_binobj.hxx
|
||||
* Routines to read and write the low level (binary) simgear 3d object format.
|
||||
*/
|
||||
|
||||
// Written by Curtis Olson, started January 2000.
|
||||
//
|
||||
// Copyright (C) 2000 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 _SG_BINOBJ_HXX
|
||||
#define _SG_BINOBJ_HXX
|
||||
|
||||
|
||||
#include <plib/sg.h>
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
#include <simgear/constants.h>
|
||||
#include <simgear/math/sg_types.hxx>
|
||||
#include <simgear/bucket/newbucket.hxx>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <list>
|
||||
#include STL_STRING
|
||||
|
||||
|
||||
|
||||
/** STL Structure used to store object information */
|
||||
typedef vector < int_list > group_list;
|
||||
typedef group_list::iterator group_list_iterator;
|
||||
typedef group_list::const_iterator const_group_list_iterator;
|
||||
|
||||
|
||||
/** Magic Number for our file format */
|
||||
#define SG_FILE_MAGIC_NUMBER ( ('S'<<24) + ('G'<<16) + SG_BINOBJ_VERSION )
|
||||
|
||||
|
||||
/**
|
||||
* A class to manipulate the simgear 3d object format.
|
||||
* This class provides functionality to both read and write the binary format.
|
||||
*
|
||||
* Here is a really quick overview of the file syntax:
|
||||
*
|
||||
* - scenery-file: magic, nobjects, object+
|
||||
*
|
||||
* - magic: "TG" + version
|
||||
*
|
||||
* - object: obj_typecode, nproperties, nelements, property+, element+
|
||||
*
|
||||
* - element: nbytes, BYTE+
|
||||
*
|
||||
* - property: prop_typecode, nbytes, BYTE+
|
||||
*
|
||||
* - obj_typecode: bounding sphere | vertices | normals | texcoords |
|
||||
* triangles | fans | strips
|
||||
*
|
||||
* - prop_typecode: material_name | ???
|
||||
*
|
||||
* - nelements: SHORT (Gives us 65536 which ought to be enough, right?)
|
||||
*
|
||||
* - nproperties: SHORT
|
||||
*
|
||||
* - *_typecode: CHAR
|
||||
*
|
||||
* - nbytes: INTEGER (If we used short here that would mean 65536 bytes = 16384
|
||||
* floats = 5461 vertices which is not enough for future
|
||||
* growth)
|
||||
*
|
||||
* - vertex: FLOAT, FLOAT, FLOAT
|
||||
*/
|
||||
class SGBinObject {
|
||||
unsigned short version;
|
||||
|
||||
Point3D gbs_center;
|
||||
float gbs_radius;
|
||||
point_list wgs84_nodes;
|
||||
point_list normals;
|
||||
point_list texcoords;
|
||||
group_list tris_v;
|
||||
group_list tris_tc;
|
||||
string_list tri_materials;
|
||||
group_list strips_v;
|
||||
group_list strips_tc;
|
||||
string_list strip_materials;
|
||||
group_list fans_v;
|
||||
group_list fans_tc;
|
||||
string_list fan_materials;
|
||||
|
||||
public:
|
||||
|
||||
inline unsigned short get_version() const { return version; }
|
||||
|
||||
inline Point3D get_gbs_center() const { return gbs_center; }
|
||||
inline void set_gbs_center( Point3D p ) { gbs_center = p; }
|
||||
|
||||
inline float get_gbs_radius() const { return gbs_radius; }
|
||||
inline void set_gbs_radius( float r ) { gbs_radius = r; }
|
||||
|
||||
inline point_list get_wgs84_nodes() const { return wgs84_nodes; }
|
||||
inline void set_wgs84_nodes( point_list n ) { wgs84_nodes = n; }
|
||||
|
||||
inline point_list get_normals() const { return normals; }
|
||||
inline void set_normals( point_list n ) { normals = n; }
|
||||
|
||||
inline point_list get_texcoords() const { return texcoords; }
|
||||
inline void set_texcoords( point_list t ) { texcoords = t; }
|
||||
|
||||
inline group_list get_tris_v() const { return tris_v; }
|
||||
inline void set_tris_v( group_list g ) { tris_v = g; }
|
||||
inline group_list get_tris_tc() const { return tris_tc; }
|
||||
inline void set_tris_tc( group_list g ) { tris_tc = g; }
|
||||
inline string_list get_tri_materials() const { return tri_materials; }
|
||||
inline void set_tri_materials( string_list s ) { tri_materials = s; }
|
||||
|
||||
inline group_list get_strips_v() const { return strips_v; }
|
||||
inline void set_strips_v( group_list g ) { strips_v = g; }
|
||||
inline group_list get_strips_tc() const { return strips_tc; }
|
||||
inline void set_strips_tc( group_list g ) { strips_tc = g; }
|
||||
inline string_list get_strip_materials() const { return strip_materials; }
|
||||
inline void set_strip_materials( string_list s ) { strip_materials = s; }
|
||||
|
||||
inline group_list get_fans_v() const { return fans_v; }
|
||||
inline void set_fans_v( group_list g ) { fans_v = g; }
|
||||
inline group_list get_fans_tc() const { return fans_tc; }
|
||||
inline void set_fans_tc( group_list g ) { fans_tc = g; }
|
||||
inline string_list get_fan_materials() const { return fan_materials; }
|
||||
inline void set_fan_materials( string_list s ) { fan_materials = s; }
|
||||
|
||||
/**
|
||||
* Read a binary file object and populate the provided structures.
|
||||
* @param file input file name
|
||||
* @return result of read
|
||||
*/
|
||||
bool read_bin( const string& file );
|
||||
|
||||
/**
|
||||
* Write out the structures to a binary file. We assume that the
|
||||
* groups come to us sorted by material property. If not, things
|
||||
* don't break, but the result won't be as optimal.
|
||||
* @param base name of output path
|
||||
* @param name name of output file
|
||||
* @param b bucket for object location
|
||||
* @return result of write
|
||||
*/
|
||||
bool write_bin( const string& base, const string& name, const SGBucket& b );
|
||||
|
||||
/**
|
||||
* Write out the structures to an ASCII file. We assume that the
|
||||
* groups come to us sorted by material property. If not, things
|
||||
* don't break, but the result won't be as optimal.
|
||||
* @param base name of output path
|
||||
* @param name name of output file
|
||||
* @param b bucket for object location
|
||||
* @return result of write
|
||||
*/
|
||||
bool write_ascii( const string& base, const string& name,
|
||||
const SGBucket& b );
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \relates SGBinObject
|
||||
* Calculate the bounding sphere of a set of nodes.
|
||||
* Center is the center of the tile and zero elevation.
|
||||
* @param center center of our bounding radius
|
||||
* @param wgs84_nodes list of points in wgs84 coordinates
|
||||
* @return radius
|
||||
*/
|
||||
double sgCalcBoundingRadius( Point3D center, point_list& wgs84_nodes );
|
||||
|
||||
|
||||
#endif // _SG_BINOBJ_HXX
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
#include "sg_file.hxx"
|
||||
|
||||
FG_USING_STD(string);
|
||||
SG_USING_STD(string);
|
||||
|
||||
|
||||
SGFile::SGFile( const string &file) {
|
||||
@@ -60,13 +60,13 @@ bool SGFile::open( const SGProtocolDir d ) {
|
||||
} else if ( get_dir() == SG_IO_IN ) {
|
||||
fp = ::open( file_name.c_str(), O_RDONLY );
|
||||
} else {
|
||||
FG_LOG( FG_IO, FG_ALERT,
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"Error: bidirection mode not available for files." );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( fp == -1 ) {
|
||||
FG_LOG( FG_IO, FG_ALERT, "Error opening file: " << file_name );
|
||||
SG_LOG( SG_IO, SG_ALERT, "Error opening file: " << file_name );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ int SGFile::readline( char *buf, int length ) {
|
||||
int SGFile::write( const char *buf, const int length ) {
|
||||
int result = ::write( fp, buf, length );
|
||||
if ( result != length ) {
|
||||
FG_LOG( FG_IO, FG_ALERT, "Error writing data: " << file_name );
|
||||
SG_LOG( SG_IO, SG_ALERT, "Error writing data: " << file_name );
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// sg_file.hxx -- File I/O routines
|
||||
//
|
||||
/** \file sg_file.hxx
|
||||
* File I/O routines.
|
||||
*/
|
||||
|
||||
// Written by Curtis Olson, started November 1999.
|
||||
//
|
||||
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
|
||||
@@ -42,9 +44,12 @@
|
||||
|
||||
#include "iochannel.hxx"
|
||||
|
||||
FG_USING_STD(string);
|
||||
SG_USING_STD(string);
|
||||
|
||||
|
||||
/**
|
||||
* A file I/O class based on SGIOChannel.
|
||||
*/
|
||||
class SGFile : public SGIOChannel {
|
||||
|
||||
string file_name;
|
||||
@@ -52,7 +57,16 @@ class SGFile : public SGIOChannel {
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Create an instance of SGFile.
|
||||
* When calling the constructor you need to provide a file
|
||||
* name. This file is not opened immediately, but instead will be
|
||||
* opened when the open() method is called.
|
||||
* @param file name of file to open
|
||||
*/
|
||||
SGFile( const string& file );
|
||||
|
||||
/** Destructor */
|
||||
~SGFile();
|
||||
|
||||
// open the file based on specified direction
|
||||
@@ -73,6 +87,7 @@ public:
|
||||
// close file
|
||||
bool close();
|
||||
|
||||
/** @return the name of the file being manipulated. */
|
||||
inline string get_file_name() const { return file_name; }
|
||||
};
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
#include "sg_serial.hxx"
|
||||
|
||||
FG_USING_STD(string);
|
||||
SG_USING_STD(string);
|
||||
|
||||
|
||||
SGSerial::SGSerial( const string& device_name, const string& baud_rate ) :
|
||||
@@ -51,14 +51,14 @@ bool SGSerial::open( const SGProtocolDir d ) {
|
||||
set_dir( d );
|
||||
|
||||
if ( ! port.open_port( device ) ) {
|
||||
FG_LOG( FG_IO, FG_ALERT, "Error opening device: " << device );
|
||||
SG_LOG( SG_IO, SG_ALERT, "Error opening device: " << device );
|
||||
return false;
|
||||
}
|
||||
|
||||
// cout << "fd = " << port.fd << endl;
|
||||
|
||||
if ( ! port.set_baud( atoi( baud.c_str() ) ) ) {
|
||||
FG_LOG( FG_IO, FG_ALERT, "Error setting baud: " << baud );
|
||||
SG_LOG( SG_IO, SG_ALERT, "Error setting baud: " << baud );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ int SGSerial::readline( char *buf, int length ) {
|
||||
// copy to external buffer
|
||||
strncpy( buf, save_buf, result );
|
||||
buf[result] = '\0';
|
||||
FG_LOG( FG_IO, FG_INFO, "fg_serial line = " << buf );
|
||||
SG_LOG( SG_IO, SG_INFO, "fg_serial line = " << buf );
|
||||
|
||||
// shift save buffer
|
||||
for ( i = result; i < save_len; ++i ) {
|
||||
@@ -133,7 +133,7 @@ int SGSerial::write( const char *buf, const int length ) {
|
||||
int result = port.write_port( buf, length );
|
||||
|
||||
if ( result != length ) {
|
||||
FG_LOG( FG_IO, FG_ALERT, "Error writing data: " << device );
|
||||
SG_LOG( SG_IO, SG_ALERT, "Error writing data: " << device );
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
// sg_serial.hxx -- Serial I/O routines
|
||||
//
|
||||
/**
|
||||
* \file sg_serial.hxx
|
||||
* Serial I/O routines
|
||||
*/
|
||||
|
||||
// Written by Curtis Olson, started November 1999.
|
||||
//
|
||||
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
|
||||
@@ -33,7 +36,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
// #ifdef FG_HAVE_STD_INCLUDES
|
||||
// #ifdef SG_HAVE_STD_INCLUDES
|
||||
// # include <ctime>
|
||||
// #else
|
||||
// # include <time.h>
|
||||
@@ -43,9 +46,11 @@
|
||||
|
||||
#include "iochannel.hxx"
|
||||
|
||||
FG_USING_STD(string);
|
||||
|
||||
SG_USING_STD(string);
|
||||
|
||||
/**
|
||||
* A serial I/O class based on SGIOChannel.
|
||||
*/
|
||||
class SGSerial : public SGIOChannel {
|
||||
|
||||
string device;
|
||||
@@ -57,7 +62,21 @@ class SGSerial : public SGIOChannel {
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Create an instance of SGSerial.
|
||||
* This creates an instance of the SGSerial class. You need to
|
||||
* provide the serial device name and desired baud rate. For Unix
|
||||
* style systems, device names will be similar to
|
||||
* ``/dev/ttyS0''. For DOS style systems you may want to use
|
||||
* something similar to ``COM1:''. As with the SGFile class,
|
||||
* device is not opened immediately, but instead will be opened
|
||||
* when the open() method is called.
|
||||
* @param device_name name of serial device
|
||||
* @param baud_rate speed of communication
|
||||
*/
|
||||
SGSerial( const string& device_name, const string& baud_rate );
|
||||
|
||||
/** Destructor */
|
||||
~SGSerial();
|
||||
|
||||
// open the serial port based on specified direction
|
||||
@@ -78,7 +97,10 @@ public:
|
||||
// close port
|
||||
bool close();
|
||||
|
||||
/** @return the serial port device name */
|
||||
inline string get_device() const { return device; }
|
||||
|
||||
/** @return the baud rate */
|
||||
inline string get_baud() const { return baud; }
|
||||
};
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ SGSocket::SGSocket( const string& host, const string& port,
|
||||
{
|
||||
#if defined(_MSC_VER)
|
||||
if (!wsock_init && !wsastartup()) {
|
||||
FG_LOG( FG_IO, FG_ALERT, "Winsock not available");
|
||||
SG_LOG( SG_IO, SG_ALERT, "Winsock not available");
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -60,7 +60,7 @@ SGSocket::SGSocket( const string& host, const string& port,
|
||||
sock_style = SOCK_STREAM;
|
||||
} else {
|
||||
sock_style = SOCK_DGRAM;
|
||||
FG_LOG( FG_IO, FG_ALERT,
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"Error: SGSocket() unknown style = " << style );
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ SGSocket::SocketType SGSocket::make_server_socket () {
|
||||
// Create the socket.
|
||||
sock = socket (PF_INET, sock_style, 0);
|
||||
if (sock == INVALID_SOCKET) {
|
||||
FG_LOG( FG_IO, FG_ALERT,
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"Error: socket() failed in make_server_socket()" );
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
@@ -95,7 +95,7 @@ SGSocket::SocketType SGSocket::make_server_socket () {
|
||||
name.sin_port = htons(port); // set port to zero to let system pick
|
||||
name.sin_addr.s_addr = htonl (INADDR_ANY);
|
||||
if (bind (sock, (struct sockaddr *) &name, sizeof (name)) != 0) {
|
||||
FG_LOG( FG_IO, FG_ALERT,
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"Error: bind() failed in make_server_socket()" );
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
@@ -103,7 +103,7 @@ SGSocket::SocketType SGSocket::make_server_socket () {
|
||||
// Find the assigned port number
|
||||
length = sizeof(struct sockaddr_in);
|
||||
if ( getsockname(sock, (struct sockaddr *) &name, &length) ) {
|
||||
FG_LOG( FG_IO, FG_ALERT,
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"Error: getsockname() failed in make_server_socket()" );
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
@@ -117,12 +117,12 @@ SGSocket::SocketType SGSocket::make_client_socket () {
|
||||
struct sockaddr_in name;
|
||||
struct hostent *hp;
|
||||
|
||||
FG_LOG( FG_IO, FG_INFO, "Make client socket()" );
|
||||
SG_LOG( SG_IO, SG_INFO, "Make client socket()" );
|
||||
|
||||
// Create the socket.
|
||||
sock = socket (PF_INET, sock_style, 0);
|
||||
if (sock == INVALID_SOCKET) {
|
||||
FG_LOG( FG_IO, FG_ALERT,
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"Error: socket() failed in make_server_socket()" );
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
@@ -132,6 +132,10 @@ SGSocket::SocketType SGSocket::make_client_socket () {
|
||||
|
||||
// get the hosts official name/info
|
||||
hp = gethostbyname( hostname.c_str() );
|
||||
if (hp == NULL) {
|
||||
SG_LOG( SG_IO, SG_ALERT, "Error: hostname lookup failed" );
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
// Connect this socket to the host and the port specified on the
|
||||
// command line
|
||||
@@ -146,7 +150,7 @@ SGSocket::SocketType SGSocket::make_client_socket () {
|
||||
sizeof(struct sockaddr_in)) != 0 )
|
||||
{
|
||||
closesocket(sock);
|
||||
FG_LOG( FG_IO, FG_ALERT,
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"Error: connect() failed in make_client_socket()" );
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
@@ -201,11 +205,11 @@ bool SGSocket::open( const SGProtocolDir d ) {
|
||||
// pick any available port.
|
||||
sock = make_server_socket();
|
||||
if ( sock == INVALID_SOCKET ) {
|
||||
FG_LOG( FG_IO, FG_ALERT, "socket creation failed" );
|
||||
SG_LOG( SG_IO, SG_ALERT, "socket creation failed" );
|
||||
return false;
|
||||
}
|
||||
|
||||
FG_LOG( FG_IO, FG_INFO, "socket is connected to port = " << port );
|
||||
SG_LOG( SG_IO, SG_INFO, "socket is connected to port = " << port );
|
||||
|
||||
if ( sock_style == SOCK_DGRAM ) {
|
||||
// Non-blocking UDP
|
||||
@@ -235,19 +239,19 @@ bool SGSocket::open( const SGProtocolDir d ) {
|
||||
sock = make_server_socket();
|
||||
// TODO: check for error.
|
||||
|
||||
FG_LOG( FG_IO, FG_INFO, "socket is connected to port = " << port );
|
||||
SG_LOG( SG_IO, SG_INFO, "socket is connected to port = " << port );
|
||||
|
||||
// Blocking TCP
|
||||
// Specify the maximum length of the connection queue
|
||||
listen( sock, SG_MAX_SOCKET_QUEUE );
|
||||
} else {
|
||||
FG_LOG( FG_IO, FG_ALERT,
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"Error: bidirection mode not available for UDP sockets." );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( sock < 0 ) {
|
||||
FG_LOG( FG_IO, FG_ALERT, "Error opening socket: " << hostname
|
||||
SG_LOG( SG_IO, SG_ALERT, "Error opening socket: " << hostname
|
||||
<< ":" << port );
|
||||
return false;
|
||||
}
|
||||
@@ -296,7 +300,7 @@ int SGSocket::read( char *buf, int length ) {
|
||||
}
|
||||
|
||||
if ( result != length ) {
|
||||
FG_LOG( FG_IO, FG_INFO,
|
||||
SG_LOG( SG_IO, SG_INFO,
|
||||
"Warning: read() not enough bytes." );
|
||||
}
|
||||
}
|
||||
@@ -355,7 +359,7 @@ int SGSocket::readline( char *buf, int length ) {
|
||||
// could cause problems so if you see connections
|
||||
// dropping for unexplained reasons, LOOK HERE!
|
||||
if ( result == 0 && save_len == 0 && first_read == true ) {
|
||||
FG_LOG( FG_IO, FG_ALERT,
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"Connection closed by foreign host." );
|
||||
closesocket(sock);
|
||||
open( get_dir() );
|
||||
@@ -412,7 +416,7 @@ int SGSocket::write( const char *buf, const int length ) {
|
||||
bool error_condition = false;
|
||||
|
||||
if ( writesocket(sock, buf, length) < 0 ) {
|
||||
FG_LOG( FG_IO, FG_ALERT, "Error writing to socket: " << port );
|
||||
SG_LOG( SG_IO, SG_ALERT, "Error writing to socket: " << port );
|
||||
error_condition = true;
|
||||
}
|
||||
|
||||
@@ -433,7 +437,7 @@ int SGSocket::write( const char *buf, const int length ) {
|
||||
if ( FD_ISSET(sock, &ready) ) {
|
||||
int msgsock = accept(sock, 0, 0);
|
||||
if ( msgsock < 0 ) {
|
||||
FG_LOG( FG_IO, FG_ALERT,
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"Error: accept() failed in write()" );
|
||||
return 0;
|
||||
} else {
|
||||
@@ -441,7 +445,7 @@ int SGSocket::write( const char *buf, const int length ) {
|
||||
}
|
||||
}
|
||||
|
||||
FG_LOG( FG_IO, FG_INFO, "Client connections = " <<
|
||||
SG_LOG( SG_IO, SG_INFO, "Client connections = " <<
|
||||
client_connections.size() );
|
||||
for ( int i = 0; i < (int)client_connections.size(); ++i ) {
|
||||
int msgsock = client_connections[i];
|
||||
@@ -452,7 +456,7 @@ int SGSocket::write( const char *buf, const int length ) {
|
||||
|
||||
// write the interesting data to the socket
|
||||
if ( writesocket(msgsock, buf, length) == SOCKET_ERROR ) {
|
||||
FG_LOG( FG_IO, FG_ALERT, "Error writing to socket: " << port );
|
||||
SG_LOG( SG_IO, SG_ALERT, "Error writing to socket: " << port );
|
||||
error_condition = true;
|
||||
} else {
|
||||
#ifdef _POSIX_SYNCHRONIZED_IO
|
||||
@@ -504,7 +508,7 @@ bool SGSocket::nonblock() {
|
||||
u_long arg = 1;
|
||||
if (ioctlsocket( sock, FIONBIO, &arg ) != 0) {
|
||||
int error_code = WSAGetLastError();
|
||||
FG_LOG( FG_IO, FG_ALERT,
|
||||
SG_LOG( SG_IO, SG_ALERT,
|
||||
"Error " << error_code << ": unable to set non-blocking mode"
|
||||
);
|
||||
return false;
|
||||
@@ -529,14 +533,14 @@ SGSocket::wsastartup() {
|
||||
int err = WSAStartup( wVersionRequested, &wsaData );
|
||||
if (err != 0)
|
||||
{
|
||||
FG_LOG( FG_IO, FG_ALERT, "Error: Couldn't load winsock" );
|
||||
SG_LOG( SG_IO, SG_ALERT, "Error: Couldn't load winsock" );
|
||||
return false;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if ( LOBYTE( wsaData.wVersion ) != 2 ||
|
||||
HIBYTE( wsaData.wVersion ) != 2 ) {
|
||||
FG_LOG( FG_IO, FG_ALERT, "Couldn't load a suitable winsock");
|
||||
SG_LOG( SG_IO, SG_ALERT, "Couldn't load a suitable winsock");
|
||||
WSACleanup( );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
// sg_socket.hxx -- Socket I/O routines
|
||||
//
|
||||
/**
|
||||
* \file sg_socket.hxx
|
||||
* Socket I/O routines.
|
||||
*/
|
||||
|
||||
// Written by Curtis Olson, started November 1999.
|
||||
//
|
||||
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
|
||||
@@ -36,7 +39,7 @@
|
||||
#include <simgear/math/sg_types.hxx>
|
||||
#include <simgear/io/iochannel.hxx>
|
||||
|
||||
FG_USING_STD(string);
|
||||
SG_USING_STD(string);
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# include <winsock.h>
|
||||
@@ -45,6 +48,9 @@ FG_USING_STD(string);
|
||||
#define SG_MAX_SOCKET_QUEUE 32
|
||||
|
||||
|
||||
/**
|
||||
* A socket I/O class based on SGIOChannel.
|
||||
*/
|
||||
class SGSocket : public SGIOChannel {
|
||||
public:
|
||||
#if defined(_MSC_VER)
|
||||
@@ -89,7 +95,56 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Create an instance of SGSocket.
|
||||
*
|
||||
* When calling the constructor you need to provide a host name, a
|
||||
* port number, and a socket style. The convention used by the
|
||||
* SGSocket class is that the server side listens and the client
|
||||
* side sends. For a server socket, the host name should be
|
||||
* empty. For a server, the port number is optional, if you do not
|
||||
* specify a port, the system will assign one. For a client
|
||||
* socket, you need to specify both a destination host and
|
||||
* destination port. For both client and server sockets you must
|
||||
* specify the socket type. Type must be either udp or tcp. Here's
|
||||
* a quick breakdown of the major differences between UDP and TCP
|
||||
* type sockets.
|
||||
*
|
||||
* TCP sockets are the type where you establish a connection and
|
||||
* then can read and write to the socket from both ends. If one
|
||||
* end of TCP socket connect quits, the other end will likely
|
||||
* segfault if it doesn't take special precautions. But, the nice
|
||||
* thing about TCP connections is that the underlying protocol
|
||||
* guarantees that your message will get through. This imposes a
|
||||
* certain performance overhead though on the communication
|
||||
* because the protocol must resend failed messages. TCP sockets
|
||||
* are good for sending periodic command/response type messages
|
||||
* where performance isn't a big issues, but reliability is.
|
||||
*
|
||||
* UDP sockets on the other hand are a lower level protocol and
|
||||
* don't have the same sort of connection as TCP sockets. With UDP
|
||||
* sockets, the server end just sits and listens for incoming
|
||||
* packets from anywhere. The client end sends it's message and
|
||||
* forgets about it. It doesn't care if there isn't even a server
|
||||
* out there listening and all the packets are getting
|
||||
* lost. Although systems/networks usually do a pretty good job
|
||||
* (statistically) of getting your UDP packets to their
|
||||
* destination, there is no guarantee that any particular packet
|
||||
* will make it. But, because of this low level implementation and
|
||||
* lack of error checking, UDP packets are much faster and
|
||||
* efficient. UDP packets are good for sending positional
|
||||
* information to synchronize two applications. In this case, you
|
||||
* want the information to arrive as quickly as possible, and if
|
||||
* you lose a packet, you'd rather get new updated information
|
||||
* rather than have the system waste time resending a packet that
|
||||
* is becoming older and older with every retry.
|
||||
* @param host name of host if direction is SG_IO_OUT or SG_IO_BI
|
||||
* @param port port number if we care to choose one.
|
||||
* @param style specify "udp" or "tcp"
|
||||
*/
|
||||
SGSocket( const string& host, const string& port, const string& style );
|
||||
|
||||
/** Destructor */
|
||||
~SGSocket();
|
||||
|
||||
// If specified as a server (in direction for now) open the master
|
||||
@@ -112,14 +167,18 @@ public:
|
||||
// close file
|
||||
bool close();
|
||||
|
||||
// Enable non-blocking mode.
|
||||
/**
|
||||
* Enable non-blocking mode.
|
||||
* @return success/failure
|
||||
*/
|
||||
bool nonblock();
|
||||
|
||||
/** @return the remote host name */
|
||||
inline string get_hostname() const { return hostname; }
|
||||
|
||||
/** @return the port number (in string form) */
|
||||
inline string get_port_str() const { return port_str; }
|
||||
};
|
||||
|
||||
|
||||
#endif // _SG_SOCKET_HXX
|
||||
|
||||
|
||||
|
||||
@@ -1,9 +1,34 @@
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include STL_IOSTREAM
|
||||
|
||||
#include "sg_socket.hxx"
|
||||
#include "lowlevel.hxx"
|
||||
|
||||
#if !defined(SG_HAVE_NATIVE_SGI_COMPILERS)
|
||||
SG_USING_STD(cout);
|
||||
SG_USING_STD(endl);
|
||||
#endif
|
||||
|
||||
static const int sgEndianTest = 1;
|
||||
#define sgIsLittleEndian (*((char *) &sgEndianTest ) != 0)
|
||||
#define sgIsBigEndian (*((char *) &sgEndianTest ) == 0)
|
||||
|
||||
int main() {
|
||||
|
||||
if ( sgIsLittleEndian ) {
|
||||
cout << "this machine is little endian\n";
|
||||
}
|
||||
|
||||
if ( sgIsBigEndian ) {
|
||||
cout << "this machine is big endian\n";
|
||||
}
|
||||
|
||||
cout << "short = " << sizeof(unsigned short) << endl;
|
||||
cout << "int = " << sizeof(unsigned int) << endl;
|
||||
cout << "long long = " << sizeof(long long) << endl;
|
||||
|
||||
SGSocket s( "", "5500", "tcp" );
|
||||
|
||||
if ( !s.open( SG_IO_BI ) ) {
|
||||
|
||||
@@ -70,12 +70,11 @@
|
||||
#include <math.h>
|
||||
|
||||
#include <simgear/constants.h>
|
||||
#include <simgear/sg_inlines.h>
|
||||
|
||||
#include "coremag.hxx"
|
||||
|
||||
|
||||
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
static const double pi = 3.14159265358979;
|
||||
static const double a = 6378.16; /* major radius (km) IAU66 ellipsoid */
|
||||
static const double f = 1.0 / 298.25; /* inverse flattening IAU66 ellipsoid */
|
||||
@@ -243,7 +242,7 @@ double calc_magvar( double lat, double lon, double h, long dat, double* field )
|
||||
|
||||
for ( m = 0; m <= nmax; m++ ) {
|
||||
double mm = m*m;
|
||||
for ( n = max(m + 1, 2); n <= nmax; n++ ) {
|
||||
for ( n = SG_MAX2(m + 1, 2); n <= nmax; n++ ) {
|
||||
roots[m][n][0] = sqrt((n-1)*(n-1) - mm);
|
||||
roots[m][n][1] = 1.0 / sqrt( n*n - mm);
|
||||
}
|
||||
@@ -261,7 +260,7 @@ double calc_magvar( double lat, double lon, double h, long dat, double* field )
|
||||
/* lower triangle */
|
||||
for ( m = 0; m <= nmax; m++ ) {
|
||||
// double mm = m*m;
|
||||
for ( n = max(m + 1, 2); n <= nmax; n++ ) {
|
||||
for ( n = SG_MAX2(m + 1, 2); n <= nmax; n++ ) {
|
||||
// double root1 = sqrt((n-1)*(n-1) - mm);
|
||||
// double root2 = 1.0 / sqrt( n*n - mm);
|
||||
P[n][m] = (P[n-1][m] * c * (2.0*n-1) -
|
||||
@@ -387,7 +386,7 @@ double SGMagVarOrig( double lat, double lon, double h, long dat, double* field )
|
||||
|
||||
/* lower triangle */
|
||||
for ( m = 0; m <= nmax; m++ ) {
|
||||
for ( n = max(m + 1, 2); n <= nmax; n++ ) {
|
||||
for ( n = SG_MAX2(m + 1, 2); n <= nmax; n++ ) {
|
||||
P[n][m] = (P[n-1][m] * c * (2.0*n-1) - P[n-2][m] *
|
||||
sqrt(1.0*(n-1)*(n-1) - m * m)) /
|
||||
sqrt(1.0* n * n - m * m);
|
||||
|
||||
@@ -21,13 +21,8 @@
|
||||
// $Id$
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <simgear/misc/fgpath.hxx>
|
||||
#include <simgear/magvar/magvar.hxx>
|
||||
|
||||
#include "coremag.hxx"
|
||||
@@ -49,3 +44,11 @@ void SGMagVar::update( double lon, double lat, double alt_m, double jd ) {
|
||||
magdip = atan(field[5]/sqrt(field[3]*field[3]+field[4]*field[4]));
|
||||
}
|
||||
|
||||
|
||||
double sgGetMagVar( double lon, double lat, double alt_m, double jd ) {
|
||||
// cout << "lat = " << lat << " lon = " << lon << " elev = " << alt_m
|
||||
// << " JD = " << jd << endl;
|
||||
|
||||
double field[6];
|
||||
return calc_magvar( lat, lon, alt_m / 1000.0, (long)jd, field );
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
// magvar.hxx -- magnetic variation wrapper class
|
||||
//
|
||||
/**
|
||||
* \file magvar.hxx
|
||||
* Magnetic variation wrapper class.
|
||||
*/
|
||||
|
||||
// Written by Curtis Olson, started July 2000.
|
||||
//
|
||||
// Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org
|
||||
@@ -30,11 +33,21 @@
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Magnetic variation wrapper class.
|
||||
*
|
||||
* The SGMagVar class calculates the magnetic variation and dip for
|
||||
* any position, altitude, and time. It is a complete
|
||||
* re-implimentation of the NIMA WMM 2000 (not derived from their demo
|
||||
* code.)
|
||||
*
|
||||
* The SGMagVar class is really a simple wrapper around the core Ed
|
||||
* Williams code which does all the hard work. This class allows you
|
||||
* to crunch the math once and then do multiple polls of the
|
||||
* data. However, if your position, altitude, or time has changed
|
||||
* significantly, you should call the update() method to recrunch new
|
||||
* numbers.
|
||||
*/
|
||||
class SGMagVar {
|
||||
|
||||
private:
|
||||
@@ -44,15 +57,43 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* This creates an instance of the SGMagVar object.
|
||||
* You must call the update() method before any queries will be valid.
|
||||
*/
|
||||
SGMagVar();
|
||||
|
||||
/** Destructor */
|
||||
~SGMagVar();
|
||||
|
||||
// recalculate the magnetic offset and dip
|
||||
/** Recalculate the magnetic offset and dip.
|
||||
* The update() method requires you to pass in your position and
|
||||
* the julian date. Lon and lat are specified in radians, altitude
|
||||
* is specified in meters. Julian date can be conveniently
|
||||
* calculated by using an instance of the SGTime class.
|
||||
* @param lon longitude in radians
|
||||
* @param lat latitude in radians
|
||||
* @param alt_m altitude above sea level in meters
|
||||
* @param jd julian date
|
||||
*/
|
||||
void update( double lon, double lat, double alt_m, double jd );
|
||||
|
||||
/** @return the current magnetic variation in radians. */
|
||||
double get_magvar() const { return magvar; }
|
||||
|
||||
/** @return the current magnetic dip in radians. */
|
||||
double get_magdip() const { return magdip; }
|
||||
};
|
||||
|
||||
|
||||
#endif // _LIGHT_HXX
|
||||
/**
|
||||
* \relates SGMagVar
|
||||
* Lookup the magvar for any arbitrary location (This function doesn't
|
||||
* save state like the SGMagVar class. This function triggers a fair
|
||||
* amount of CPU work, so use it cautiously.
|
||||
* @return the magvar in radians
|
||||
*/
|
||||
double sgGetMagVar( double lon, double lat, double alt_m, double jd );
|
||||
|
||||
|
||||
#endif // _MAGVAR_HXX
|
||||
|
||||
@@ -42,15 +42,15 @@ if (argc == 8){
|
||||
}
|
||||
|
||||
|
||||
var = calc_magvar( DEG_TO_RAD * lat_deg, DEG_TO_RAD * lon_deg, h,
|
||||
var = calc_magvar( SGD_DEGREES_TO_RADIANS * lat_deg, SGD_DEGREES_TO_RADIANS * lon_deg, h,
|
||||
yymmdd_to_julian_days(yy,mm,dd), field );
|
||||
|
||||
fprintf(stdout,"%6.0lf %6.0lf %6.0lf\n", field[0], field[1], field[2] );
|
||||
fprintf(stdout,"%6.0lf %6.0lf %6.0lf\n", field[3], field[4], field[5] );
|
||||
fprintf(stdout,"%6.0lf %6.0lf %6.0lf %4.2lf %4.2lf \n",
|
||||
field[3],field[4],field[5],
|
||||
RAD_TO_DEG * (atan(field[5]/pow(field[3]*field[3]+field[4]*field[4],0.5))),
|
||||
RAD_TO_DEG * var);
|
||||
SGD_RADIANS_TO_DEGREES * (atan(field[5]/pow(field[3]*field[3]+field[4]*field[4],0.5))),
|
||||
SGD_RADIANS_TO_DEGREES * var);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,13 +9,13 @@ endif
|
||||
lib_LIBRARIES = libsgmath.a
|
||||
|
||||
include_HEADERS = \
|
||||
fg_memory.h \
|
||||
interpolater.hxx \
|
||||
leastsqs.hxx \
|
||||
localconsts.hxx \
|
||||
point3d.hxx \
|
||||
polar3d.hxx \
|
||||
sg_geodesy.hxx \
|
||||
sg_memory.h \
|
||||
sg_random.h \
|
||||
sg_types.hxx \
|
||||
vector.hxx
|
||||
|
||||
@@ -26,83 +26,102 @@
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#ifdef __MWERKS__
|
||||
#include <stdlib.h> // for exit()
|
||||
#endif
|
||||
|
||||
#include STL_STRING
|
||||
|
||||
#include <simgear/fg_zlib.h>
|
||||
// depricated - #include <simgear/sg_zlib.h>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/misc/fgstream.hxx>
|
||||
#include <simgear/misc/sgstream.hxx>
|
||||
|
||||
#include "interpolater.hxx"
|
||||
|
||||
SG_USING_STD(string);
|
||||
|
||||
// Constructor -- starts with an empty table.
|
||||
SGInterpTable::SGInterpTable()
|
||||
: size(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// Constructor -- loads the interpolation table from the specified
|
||||
// file
|
||||
fgINTERPTABLE::fgINTERPTABLE( const string& file ) {
|
||||
FG_LOG( FG_MATH, FG_INFO, "Initializing Interpolator for " << file );
|
||||
SGInterpTable::SGInterpTable( const string& file )
|
||||
: size(0)
|
||||
{
|
||||
SG_LOG( SG_MATH, SG_INFO, "Initializing Interpolator for " << file );
|
||||
|
||||
fg_gzifstream in( file );
|
||||
if ( !in ) {
|
||||
FG_LOG( FG_GENERAL, FG_ALERT, "Cannot open file: " << file );
|
||||
sg_gzifstream in( file );
|
||||
if ( !in.is_open() ) {
|
||||
SG_LOG( SG_GENERAL, SG_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);
|
||||
}
|
||||
double ind, dep;
|
||||
in >> ind >> dep;
|
||||
in >> skipws;
|
||||
table.push_back(Entry(ind, dep));
|
||||
size++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Add an entry to the table.
|
||||
void SGInterpTable::addEntry (double ind, double dep)
|
||||
{
|
||||
table.push_back(Entry(ind,dep));
|
||||
size++;
|
||||
}
|
||||
|
||||
|
||||
// Given an x value, linearly interpolate the y value from the table
|
||||
double fgINTERPTABLE::interpolate(double x) {
|
||||
double SGInterpTable::interpolate(double x) const
|
||||
{
|
||||
int i;
|
||||
double y;
|
||||
|
||||
if (size == 0.0) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
|
||||
while ( (x > table[i][0]) && (i < size) ) {
|
||||
while ( (i < size) && (x > table[i].ind) ) {
|
||||
// cout << " i = " << i << " table[i].ind = " << table[i].ind << endl;
|
||||
// cout << " size = " << size << endl;
|
||||
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 ( i <= 0 ) {
|
||||
SG_LOG( SG_MATH, SG_DEBUG,
|
||||
"interpolate(): lookup error, x to small = " << x );
|
||||
return table[0].dep;
|
||||
}
|
||||
|
||||
if ( x > table[i][0] ) {
|
||||
FG_LOG( FG_MATH, FG_ALERT,
|
||||
"fgInterpolateInit(): lookup error, x to big = " << x );
|
||||
return(0.0);
|
||||
// cout << " table[size-1].ind = " << table[size-1].ind << endl;
|
||||
if ( i >= size ) {
|
||||
SG_LOG( SG_MATH, SG_DEBUG,
|
||||
"interpolate(): lookup error, x to big = " << x );
|
||||
return table[size-1].dep;
|
||||
}
|
||||
|
||||
// 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]);
|
||||
y = table[i].dep +
|
||||
( (table[i-1].dep - table[i].dep) *
|
||||
(x - table[i].ind) ) /
|
||||
(table[i-1].ind - table[i].ind);
|
||||
|
||||
return(y);
|
||||
}
|
||||
|
||||
|
||||
// Destructor
|
||||
fgINTERPTABLE::~fgINTERPTABLE( void ) {
|
||||
SGInterpTable::~SGInterpTable() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
//
|
||||
// interpolater.hxx -- routines to handle linear interpolation from a table of
|
||||
// x,y The table must be sorted by "x" in ascending order
|
||||
//
|
||||
/**
|
||||
* \file interpolater.hxx
|
||||
* 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
|
||||
@@ -34,27 +36,66 @@
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <vector>
|
||||
SG_USING_STD(vector);
|
||||
|
||||
#include STL_STRING
|
||||
FG_USING_STD(string);
|
||||
|
||||
#define MAX_TABLE_SIZE 32
|
||||
SG_USING_STD(string);
|
||||
|
||||
|
||||
class fgINTERPTABLE {
|
||||
/**
|
||||
* A class that provids a simple linear 2d interpolation lookup table.
|
||||
* The actual table is expected to be loaded from a file. The
|
||||
* independant variable must be strictly ascending. The dependent
|
||||
* variable can be anything.
|
||||
*/
|
||||
class SGInterpTable {
|
||||
|
||||
struct Entry
|
||||
{
|
||||
Entry ()
|
||||
: ind(0.0L), dep(0.0L) {}
|
||||
Entry (double independent, double dependent)
|
||||
: ind(independent), dep(dependent) {}
|
||||
double ind;
|
||||
double dep;
|
||||
};
|
||||
|
||||
int size;
|
||||
double table[MAX_TABLE_SIZE][2];
|
||||
vector<Entry> table;
|
||||
|
||||
public:
|
||||
|
||||
// Constructor -- loads the interpolation table from the specified
|
||||
// file
|
||||
fgINTERPTABLE( const string& file );
|
||||
/**
|
||||
* Constructor. Creates a new, empty table.
|
||||
*/
|
||||
SGInterpTable();
|
||||
|
||||
// Given an x value, linearly interpolate the y value from the table
|
||||
double interpolate(double x);
|
||||
/**
|
||||
* Constructor. Loads the interpolation table from the specified file.
|
||||
* @param file name of interpolation file
|
||||
*/
|
||||
SGInterpTable( const string& file );
|
||||
|
||||
// Destructor
|
||||
~fgINTERPTABLE( void );
|
||||
|
||||
/**
|
||||
* Add an entry to the table, extending the table's length.
|
||||
*
|
||||
* @param ind The independent variable.
|
||||
* @param dep The dependent variable.
|
||||
*/
|
||||
void addEntry (double ind, double dep);
|
||||
|
||||
|
||||
/**
|
||||
* Given an x value, linearly interpolate the y value from the table.
|
||||
* @param x independent variable
|
||||
* @return interpolated dependent variable
|
||||
*/
|
||||
double interpolate(double x) const;
|
||||
|
||||
/** Destructor */
|
||||
~SGInterpTable();
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
// leastsqs.h -- Implements a simple linear least squares best fit routine
|
||||
//
|
||||
/**
|
||||
* \file leastsqs.hxx
|
||||
* Implements a simple linear least squares best fit routine.
|
||||
*/
|
||||
|
||||
// Written by Curtis Olson, started September 1997.
|
||||
//
|
||||
// Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
|
||||
@@ -20,7 +23,6 @@
|
||||
// Boston, MA 02111-1307, USA.
|
||||
//
|
||||
// $Id$
|
||||
///
|
||||
|
||||
|
||||
#ifndef _LEASTSQS_H
|
||||
@@ -32,39 +34,47 @@
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
Least squares fit:
|
||||
/**
|
||||
Classical least squares fit:
|
||||
|
||||
y = b0 + b1x
|
||||
\f[
|
||||
y = b_0 + b_1 * x
|
||||
\f]
|
||||
|
||||
n*sum(xi*yi) - (sum(xi)*sum(yi))
|
||||
b1 = --------------------------------
|
||||
n*sum(xi^2) - (sum(xi))^2
|
||||
\f[
|
||||
b_1 = \frac{n * \sum_0^{i-1} (x_i*y_i) - \sum_0^{i-1} x_i* \sum_0^{i-1} y_i}
|
||||
{n*\sum_0^{i-1} x_i^2 - (\sum_0^{i-1} x_i)^2}
|
||||
\f]
|
||||
|
||||
|
||||
b0 = sum(yi)/n - b1*(sum(xi)/n)
|
||||
\f[
|
||||
b_0 = \frac{\sum_0^{i-1} y_i}{n} - b_1 * \frac{\sum_0^{i-1} x_i}{n}
|
||||
\f]
|
||||
*/
|
||||
|
||||
void least_squares(double *x, double *y, int n, double *m, double *b);
|
||||
|
||||
/* incrimentally update existing values with a new data point */
|
||||
|
||||
/**
|
||||
* Incrimentally update existing values with a new data point.
|
||||
*/
|
||||
void least_squares_update(double x, double y, double *m, double *b);
|
||||
|
||||
|
||||
/*
|
||||
return the least squares error:
|
||||
/**
|
||||
@return the least squares error:.
|
||||
\f[
|
||||
|
||||
(y[i] - y_hat[i])^2
|
||||
-------------------
|
||||
n
|
||||
\frac{(y_i - \hat{y}_i)^2}{n}
|
||||
\f]
|
||||
*/
|
||||
double least_squares_error(double *x, double *y, int n, double m, double b);
|
||||
|
||||
|
||||
/*
|
||||
return the maximum least squares error:
|
||||
/**
|
||||
@return the maximum least squares error.
|
||||
|
||||
(y[i] - y_hat[i])^2
|
||||
\f[
|
||||
(y_i - \hat{y}_i)^2
|
||||
\f]
|
||||
*/
|
||||
double least_squares_max_error(double *x, double *y, int n, double m, double b);
|
||||
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
// point3d.hxx -- a 3d point class.
|
||||
//
|
||||
// Adapted from algebra3 by Jean-Francois Doue, started October 1998.
|
||||
//
|
||||
/**
|
||||
* \file point3d.hxx
|
||||
* A 3d point class (depricated). This class is depricated and we are
|
||||
* in the process of removing all usage of it in favor of plib's "sg"
|
||||
* library of point, vector, and math routines. Plib's sg lib is less
|
||||
* object oriented, but integrates more seamlessly with opengl.
|
||||
*
|
||||
* Adapted from algebra3 by Jean-Francois Doue, started October 1998.
|
||||
*/
|
||||
|
||||
// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
@@ -32,11 +38,11 @@
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#ifdef FG_MATH_EXCEPTION_CLASH
|
||||
#ifdef SG_MATH_EXCEPTION_CLASH
|
||||
# define exception c_exception
|
||||
#endif
|
||||
|
||||
#ifdef FG_HAVE_STD_INCLUDES
|
||||
#ifdef SG_HAVE_STD_INCLUDES
|
||||
# include <iostream>
|
||||
# include <cassert>
|
||||
# include <cmath>
|
||||
@@ -49,15 +55,15 @@
|
||||
#include <simgear/math/localconsts.hxx>
|
||||
|
||||
// I don't understand ... <math.h> or <cmath> should be included
|
||||
// already depending on how you defined FG_HAVE_STD_INCLUDES, but I
|
||||
// already depending on how you defined SG_HAVE_STD_INCLUDES, but I
|
||||
// can go ahead and add this -- CLO
|
||||
#ifdef __MWERKS__
|
||||
FG_USING_NAMESPACE(std);
|
||||
SG_USING_NAMESPACE(std);
|
||||
#endif
|
||||
|
||||
#ifndef FG_HAVE_NATIVE_SGI_COMPILERS
|
||||
FG_USING_STD(ostream);
|
||||
FG_USING_STD(istream);
|
||||
#ifndef SG_HAVE_NATIVE_SGI_COMPILERS
|
||||
SG_USING_STD(ostream);
|
||||
SG_USING_STD(istream);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -73,11 +79,9 @@ Point3D operator- (const Point3D& p); // -p1
|
||||
bool operator== (const Point3D& a, const Point3D& b); // p1 == p2?
|
||||
|
||||
|
||||
///////////////////////////
|
||||
//
|
||||
// 3D Point
|
||||
//
|
||||
///////////////////////////
|
||||
/**
|
||||
* 3D Point class.
|
||||
*/
|
||||
|
||||
class Point3D {
|
||||
|
||||
@@ -87,8 +91,7 @@ protected:
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
/** Default constructor */
|
||||
Point3D();
|
||||
Point3D(const double x, const double y, const double z);
|
||||
explicit Point3D(const double d);
|
||||
@@ -105,6 +108,10 @@ public:
|
||||
void setx(const double x);
|
||||
void sety(const double y);
|
||||
void setz(const double z);
|
||||
void setlon(const double x);
|
||||
void setlat(const double y);
|
||||
void setradius(const double z);
|
||||
void setelev(const double z);
|
||||
|
||||
// Queries
|
||||
|
||||
@@ -237,6 +244,22 @@ inline void Point3D::setz(const double z) {
|
||||
n[PZ] = z;
|
||||
}
|
||||
|
||||
inline void Point3D::setlon(const double x) {
|
||||
n[PX] = x;
|
||||
}
|
||||
|
||||
inline void Point3D::setlat(const double y) {
|
||||
n[PY] = y;
|
||||
}
|
||||
|
||||
inline void Point3D::setradius(const double z) {
|
||||
n[PZ] = z;
|
||||
}
|
||||
|
||||
inline void Point3D::setelev(const double z) {
|
||||
n[PZ] = z;
|
||||
}
|
||||
|
||||
// QUERIES
|
||||
|
||||
inline double& Point3D::operator [] ( int i)
|
||||
|
||||
@@ -39,17 +39,17 @@ double fgGeodAltFromCart(const Point3D& cp)
|
||||
double lat_geoc, radius;
|
||||
double result;
|
||||
|
||||
lat_geoc = FG_PI_2 - atan2( sqrt(cp.x()*cp.x() + cp.y()*cp.y()), cp.z() );
|
||||
lat_geoc = SGD_PI_2 - atan2( sqrt(cp.x()*cp.x() + cp.y()*cp.y()), cp.z() );
|
||||
radius = sqrt( cp.x()*cp.x() + cp.y()*cp.y() + cp.z()*cp.z() );
|
||||
|
||||
if( ( (FG_PI_2 - lat_geoc) < ONE_SECOND ) // near North pole
|
||||
|| ( (FG_PI_2 + lat_geoc) < ONE_SECOND ) ) // near South pole
|
||||
if( ( (SGD_PI_2 - lat_geoc) < SG_ONE_SECOND ) // near North pole
|
||||
|| ( (SGD_PI_2 + lat_geoc) < SG_ONE_SECOND ) ) // near South pole
|
||||
{
|
||||
result = radius - EQUATORIAL_RADIUS_M*E;
|
||||
result = radius - SG_EQUATORIAL_RADIUS_M*E;
|
||||
} else {
|
||||
t_lat = tan(lat_geoc);
|
||||
x_alpha = E*EQUATORIAL_RADIUS_M/sqrt(t_lat*t_lat + E*E);
|
||||
mu_alpha = atan2(sqrt(RESQ_M - x_alpha*x_alpha),E*x_alpha);
|
||||
x_alpha = E*SG_EQUATORIAL_RADIUS_M/sqrt(t_lat*t_lat + E*E);
|
||||
mu_alpha = atan2(sqrt(SG_EQ_RAD_SQUARE_M - x_alpha*x_alpha),E*x_alpha);
|
||||
if (lat_geoc < 0) {
|
||||
mu_alpha = - mu_alpha;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
// polar.hxx -- routines to deal with polar math and transformations
|
||||
//
|
||||
/**
|
||||
* \file polar3d.hxx
|
||||
* Routines to deal with polar math and transformations.
|
||||
*/
|
||||
|
||||
// Written by Curtis Olson, started June 1997.
|
||||
//
|
||||
// Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
|
||||
@@ -22,8 +25,8 @@
|
||||
// $Id$
|
||||
|
||||
|
||||
#ifndef _POLAR_HXX
|
||||
#define _POLAR_HXX
|
||||
#ifndef _POLAR3D_HXX
|
||||
#define _POLAR3D_HXX
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
@@ -37,15 +40,23 @@
|
||||
#include <simgear/math/point3d.hxx>
|
||||
|
||||
|
||||
// Find the Altitude above the Ellipsoid (WGS84) given the Earth
|
||||
// Centered Cartesian coordinate vector Distances are specified in
|
||||
// meters.
|
||||
/**
|
||||
* Find the Altitude above the Ellipsoid (WGS84) given the Earth
|
||||
* Centered Cartesian coordinate vector Distances are specified in
|
||||
* meters.
|
||||
* @param cp point specified in cartesian coordinates
|
||||
* @return altitude above the (wgs84) earth in meters
|
||||
*/
|
||||
double sgGeodAltFromCart(const Point3D& cp);
|
||||
|
||||
|
||||
// Convert a polar coordinate to a cartesian coordinate. Lon and Lat
|
||||
// must be specified in radians. The SG convention is for distances
|
||||
// to be specified in meters
|
||||
/**
|
||||
* Convert a polar coordinate to a cartesian coordinate. Lon and Lat
|
||||
* must be specified in radians. The SG convention is for distances
|
||||
* to be specified in meters
|
||||
* @param p point specified in polar coordinates
|
||||
* @return the same point in cartesian coordinates
|
||||
*/
|
||||
inline Point3D sgPolarToCart3d(const Point3D& p) {
|
||||
double tmp = cos( p.lat() ) * p.radius();
|
||||
|
||||
@@ -55,20 +66,30 @@ inline Point3D sgPolarToCart3d(const Point3D& p) {
|
||||
}
|
||||
|
||||
|
||||
// Convert a cartesian coordinate to polar coordinates (lon/lat
|
||||
// specified in radians. Distances are specified in meters.
|
||||
/**
|
||||
* Convert a cartesian coordinate to polar coordinates (lon/lat
|
||||
* specified in radians. Distances are specified in meters.
|
||||
* @param cp point specified in cartesian coordinates
|
||||
* @return the same point in polar coordinates
|
||||
*/
|
||||
inline Point3D sgCartToPolar3d(const Point3D& cp) {
|
||||
return Point3D( atan2( cp.y(), cp.x() ),
|
||||
FG_PI_2 -
|
||||
SGD_PI_2 -
|
||||
atan2( sqrt(cp.x()*cp.x() + cp.y()*cp.y()), cp.z() ),
|
||||
sqrt(cp.x()*cp.x() + cp.y()*cp.y() + cp.z()*cp.z()) );
|
||||
}
|
||||
|
||||
|
||||
// calc new lon/lat given starting lon/lat, and offset radial, and
|
||||
// distance. NOTE: starting point is specifed in radians, distance is
|
||||
// specified in meters (and converted internally to radians)
|
||||
// ... assumes a spherical world
|
||||
/**
|
||||
* Calculate new lon/lat given starting lon/lat, and offset radial, and
|
||||
* distance. NOTE: starting point is specifed in radians, distance is
|
||||
* specified in meters (and converted internally to radians)
|
||||
* ... assumes a spherical world.
|
||||
* @param orig specified in polar coordinates
|
||||
* @param course offset radial
|
||||
* @param dist offset distance
|
||||
* @return destination point in polar coordinates
|
||||
*/
|
||||
inline Point3D calc_gc_lon_lat( const Point3D& orig, double course,
|
||||
double dist ) {
|
||||
Point3D result;
|
||||
@@ -83,24 +104,105 @@ inline Point3D calc_gc_lon_lat( const Point3D& orig, double course,
|
||||
// printf("calc_lon_lat() offset.theta = %.2f offset.dist = %.2f\n",
|
||||
// offset.theta, offset.dist);
|
||||
|
||||
dist *= METER_TO_NM * NM_TO_RAD;
|
||||
dist *= SG_METER_TO_NM * SG_NM_TO_RAD;
|
||||
|
||||
result.sety( asin( sin(orig.y()) * cos(dist) +
|
||||
cos(orig.y()) * sin(dist) * cos(course) ) );
|
||||
|
||||
if ( cos(result.y()) < FG_EPSILON ) {
|
||||
if ( cos(result.y()) < SG_EPSILON ) {
|
||||
result.setx( orig.x() ); // endpoint a pole
|
||||
} else {
|
||||
result.setx(
|
||||
fmod(orig.x() - asin( sin(course) * sin(dist) /
|
||||
cos(result.y()) ) + FG_PI, FG_2PI) - FG_PI );
|
||||
cos(result.y()) )
|
||||
+ SGD_PI, SGD_2PI) - SGD_PI );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// calc course/dist
|
||||
/**
|
||||
* Calculate course/dist given two spherical points.
|
||||
* @param start starting point
|
||||
* @param dest ending point
|
||||
* @param course resulting course
|
||||
* @param dist resulting distance
|
||||
*/
|
||||
inline void calc_gc_course_dist( const Point3D& start, const Point3D& dest,
|
||||
double *course, double *dist )
|
||||
{
|
||||
// d = 2*asin(sqrt((sin((lat1-lat2)/2))^2 +
|
||||
// cos(lat1)*cos(lat2)*(sin((lon1-lon2)/2))^2))
|
||||
double cos_start_y = cos( start.y() );
|
||||
volatile double tmp1 = sin( (start.y() - dest.y()) * 0.5 );
|
||||
volatile double tmp2 = sin( (start.x() - dest.x()) * 0.5 );
|
||||
double d = 2.0 * asin( sqrt( tmp1 * tmp1 +
|
||||
cos_start_y * cos(dest.y()) * tmp2 * tmp2));
|
||||
|
||||
*dist = d * SG_RAD_TO_NM * SG_NM_TO_METER;
|
||||
|
||||
// We obtain the initial course, tc1, (at point 1) from point 1 to
|
||||
// point 2 by the following. The formula fails if the initial
|
||||
// point is a pole. We can special case this with:
|
||||
//
|
||||
// IF (cos(lat1) < EPS) // EPS a small number ~ machine precision
|
||||
// IF (lat1 > 0)
|
||||
// tc1= pi // starting from N pole
|
||||
// ELSE
|
||||
// tc1= 0 // starting from S pole
|
||||
// ENDIF
|
||||
// ENDIF
|
||||
//
|
||||
// For starting points other than the poles:
|
||||
//
|
||||
// IF sin(lon2-lon1)<0
|
||||
// tc1=acos((sin(lat2)-sin(lat1)*cos(d))/(sin(d)*cos(lat1)))
|
||||
// ELSE
|
||||
// tc1=2*pi-acos((sin(lat2)-sin(lat1)*cos(d))/(sin(d)*cos(lat1)))
|
||||
// ENDIF
|
||||
|
||||
// if ( cos(start.y()) < SG_EPSILON ) {
|
||||
// doing it this way saves a transcendental call
|
||||
double sin_start_y = sin( start.y() );
|
||||
if ( fabs(1.0-sin_start_y) < SG_EPSILON ) {
|
||||
// EPS a small number ~ machine precision
|
||||
if ( start.y() > 0 ) {
|
||||
*course = SGD_PI; // starting from N pole
|
||||
} else {
|
||||
*course = 0; // starting from S pole
|
||||
}
|
||||
} else {
|
||||
// For starting points other than the poles:
|
||||
// double tmp3 = sin(d)*cos_start_y);
|
||||
// double tmp4 = sin(dest.y())-sin(start.y())*cos(d);
|
||||
// double tmp5 = acos(tmp4/tmp3);
|
||||
|
||||
// Doing this way gaurentees that the temps are
|
||||
// not stored into memory
|
||||
double tmp5 = acos( (sin(dest.y()) - sin_start_y * cos(d)) /
|
||||
(sin(d) * cos_start_y) );
|
||||
|
||||
// if ( sin( dest.x() - start.x() ) < 0 ) {
|
||||
// the sin of the negative angle is just the opposite sign
|
||||
// of the sin of the angle so tmp2 will have the opposite
|
||||
// sign of sin( dest.x() - start.x() )
|
||||
if ( tmp2 >= 0 ) {
|
||||
*course = tmp5;
|
||||
} else {
|
||||
*course = 2 * SGD_PI - tmp5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Calculate course/dist given two spherical points.
|
||||
* @param start starting point
|
||||
* @param dest ending point
|
||||
* @param course resulting course
|
||||
* @param dist resulting distance
|
||||
*/
|
||||
inline void calc_gc_course_dist( const Point3D& start, const Point3D& dest,
|
||||
double *course, double *dist ) {
|
||||
// d = 2*asin(sqrt((sin((lat1-lat2)/2))^2 +
|
||||
@@ -132,10 +234,10 @@ inline void calc_gc_course_dist( const Point3D& start, const Point3D& dest,
|
||||
|
||||
double tc1;
|
||||
|
||||
if ( cos(start.y()) < FG_EPSILON ) {
|
||||
if ( cos(start.y()) < SG_EPSILON ) {
|
||||
// EPS a small number ~ machine precision
|
||||
if ( start.y() > 0 ) {
|
||||
tc1 = FG_PI; // starting from N pole
|
||||
tc1 = SGD_PI; // starting from N pole
|
||||
} else {
|
||||
tc1 = 0; // starting from S pole
|
||||
}
|
||||
@@ -149,11 +251,12 @@ inline void calc_gc_course_dist( const Point3D& start, const Point3D& dest,
|
||||
if ( sin( dest.x() - start.x() ) < 0 ) {
|
||||
tc1 = tmp5;
|
||||
} else {
|
||||
tc1 = 2 * FG_PI - tmp5;
|
||||
tc1 = 2 * SGD_PI - tmp5;
|
||||
}
|
||||
|
||||
*course = tc1;
|
||||
*dist = d * RAD_TO_NM * NM_TO_METER;
|
||||
*dist = d * SG_RAD_TO_NM * SG_NM_TO_METER;
|
||||
}
|
||||
#endif // 0
|
||||
|
||||
#endif // _POLAR_HXX
|
||||
#endif // _POLAR3D_HXX
|
||||
|
||||
@@ -9,12 +9,14 @@
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#ifdef FG_HAVE_STD_INCLUDES
|
||||
#ifdef SG_HAVE_STD_INCLUDES
|
||||
# include <cmath>
|
||||
# include <cerrno>
|
||||
# include <cstdio>
|
||||
#else
|
||||
# include <math.h>
|
||||
# include <errno.h>
|
||||
# include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/constants.h>
|
||||
@@ -25,12 +27,12 @@
|
||||
#include "localconsts.hxx"
|
||||
|
||||
|
||||
#ifndef FG_HAVE_NATIVE_SGI_COMPILERS
|
||||
FG_USING_STD(cout);
|
||||
#ifndef SG_HAVE_NATIVE_SGI_COMPILERS
|
||||
SG_USING_STD(cout);
|
||||
#endif
|
||||
|
||||
// ONE_SECOND is pi/180/60/60, or about 100 feet at earths' equator
|
||||
#define ONE_SECOND 4.848136811E-6
|
||||
|
||||
#define DOMAIN_ERR_DEBUG 1
|
||||
|
||||
|
||||
// sgGeocToGeod(lat_geoc, radius, *lat_geod, *alt, *sea_level_r)
|
||||
@@ -48,24 +50,41 @@ FG_USING_STD(cout);
|
||||
void sgGeocToGeod( double lat_geoc, double radius, double
|
||||
*lat_geod, double *alt, double *sea_level_r )
|
||||
{
|
||||
#ifdef DOMAIN_ERR_DEBUG
|
||||
errno = 0; // start with error zero'd
|
||||
#endif
|
||||
|
||||
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
|
||||
if( ( (SGD_PI_2 - lat_geoc) < SG_ONE_SECOND ) // near North pole
|
||||
|| ( (SGD_PI_2 + lat_geoc) < SG_ONE_SECOND ) ) // near South pole
|
||||
{
|
||||
*lat_geod = lat_geoc;
|
||||
*sea_level_r = EQUATORIAL_RADIUS_M*E;
|
||||
*sea_level_r = SG_EQUATORIAL_RADIUS_M*E;
|
||||
*alt = radius - *sea_level_r;
|
||||
} else {
|
||||
// cout << " lat_geoc = " << lat_geoc << endl;
|
||||
t_lat = tan(lat_geoc);
|
||||
// cout << " tan(t_lat) = " << t_lat << endl;
|
||||
x_alpha = E*EQUATORIAL_RADIUS_M/sqrt(t_lat*t_lat + E*E);
|
||||
x_alpha = E*SG_EQUATORIAL_RADIUS_M/sqrt(t_lat*t_lat + E*E);
|
||||
#ifdef DOMAIN_ERR_DEBUG
|
||||
if ( errno ) {
|
||||
perror("fgGeocToGeod()");
|
||||
SG_LOG( SG_GENERAL, SG_ALERT, "sqrt(" << t_lat*t_lat + E*E << ")" );
|
||||
}
|
||||
#endif
|
||||
// cout << " x_alpha = " << x_alpha << endl;
|
||||
double tmp = RESQ_M - x_alpha * x_alpha;
|
||||
double tmp = sqrt(SG_EQ_RAD_SQUARE_M - x_alpha * x_alpha);
|
||||
if ( tmp < 0.0 ) { tmp = 0.0; }
|
||||
mu_alpha = atan2(sqrt(tmp),E*x_alpha);
|
||||
#ifdef DOMAIN_ERR_DEBUG
|
||||
if ( errno ) {
|
||||
perror("fgGeocToGeod()");
|
||||
SG_LOG( SG_GENERAL, SG_ALERT, "sqrt(" << SG_EQ_RAD_SQUARE_M - x_alpha * x_alpha
|
||||
<< ")" );
|
||||
}
|
||||
#endif
|
||||
mu_alpha = atan2(tmp,E*x_alpha);
|
||||
if (lat_geoc < 0) mu_alpha = - mu_alpha;
|
||||
sin_mu_a = sin(mu_alpha);
|
||||
delt_lambda = mu_alpha - lat_geoc;
|
||||
@@ -73,27 +92,31 @@ void sgGeocToGeod( double lat_geoc, double radius, double
|
||||
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)/
|
||||
#ifdef DOMAIN_ERR_DEBUG
|
||||
if ( errno ) {
|
||||
perror("fgGeocToGeod()");
|
||||
SG_LOG( SG_GENERAL, SG_ALERT, "sqrt(" <<
|
||||
1-EPS*EPS*sin_mu_a*sin_mu_a << ")" );
|
||||
}
|
||||
#endif
|
||||
rho_alpha = SG_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 sgGeocToGeod!!!!" );
|
||||
*sea_level_r = 0.0;
|
||||
sqrt(SG_EQ_RAD_SQUARE_M / (1 + ((1/(E*E))-1)*sin_lambda_sl*sin_lambda_sl));
|
||||
#ifdef DOMAIN_ERR_DEBUG
|
||||
if ( errno ) {
|
||||
perror("fgGeocToGeod()");
|
||||
SG_LOG( SG_GENERAL, SG_ALERT, "sqrt(" <<
|
||||
SG_EQ_RAD_SQUARE_M / (1 + ((1/(E*E))-1)*sin_lambda_sl*sin_lambda_sl)
|
||||
<< ")" );
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -116,13 +139,25 @@ void sgGeodToGeoc( double lat_geod, double alt, double *sl_radius,
|
||||
{
|
||||
double lambda_sl, sin_lambda_sl, cos_lambda_sl, sin_mu, cos_mu, px, py;
|
||||
|
||||
#ifdef DOMAIN_ERR_DEBUG
|
||||
errno = 0;
|
||||
#endif
|
||||
|
||||
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));
|
||||
sqrt(SG_EQ_RAD_SQUARE_M / (1 + ((1/(E*E))-1)*sin_lambda_sl*sin_lambda_sl));
|
||||
#ifdef DOMAIN_ERR_DEBUG
|
||||
if ( errno ) {
|
||||
perror("fgGeodToGeoc()");
|
||||
SG_LOG( SG_GENERAL, SG_ALERT, "sqrt(" <<
|
||||
SG_EQ_RAD_SQUARE_M / (1 + ((1/(E*E))-1)*sin_lambda_sl*sin_lambda_sl)
|
||||
<< ")" );
|
||||
}
|
||||
#endif
|
||||
py = *sl_radius*sin_lambda_sl + alt*sin_mu;
|
||||
px = *sl_radius*cos_lambda_sl + alt*cos_mu;
|
||||
*lat_geoc = atan2( py, px );
|
||||
@@ -142,7 +177,7 @@ void sgGeodToGeoc( double lat_geod, double alt, double *sl_radius,
|
||||
//
|
||||
// modified for FlightGear to use WGS84 only -- Norman Vine
|
||||
|
||||
#define GEOD_INV_PI FG_PI
|
||||
#define GEOD_INV_PI SGD_PI
|
||||
|
||||
// s == distance
|
||||
// az = azimuth
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// sg_geodesy.hxx -- routines to convert between geodetic and geocentric
|
||||
// coordinate systems.
|
||||
//
|
||||
// Copied and adapted directly from LaRCsim/ls_geodesy.c
|
||||
//
|
||||
/**
|
||||
* \file sg_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$
|
||||
@@ -21,39 +22,37 @@
|
||||
#include <simgear/math/polar3d.hxx>
|
||||
|
||||
|
||||
// sgGeocToGeod(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)
|
||||
|
||||
/**
|
||||
* Convert from geocentric coordinates to geodetic coordinates
|
||||
* @param lat_geoc (in) Geocentric latitude, radians, + = North
|
||||
* @param radius (in) C.G. radius to earth center (meters)
|
||||
* @param lat_geod (out) Geodetic latitude, radians, + = North
|
||||
* @param alt (out) C.G. altitude above mean sea level (meters)
|
||||
* @param sea_level_r (out) radius from earth center to sea level at
|
||||
* local vertical (surface normal) of C.G. (meters)
|
||||
*/
|
||||
void sgGeocToGeod( double lat_geoc, double radius, double
|
||||
*lat_geod, double *alt, double *sea_level_r );
|
||||
|
||||
|
||||
// sgGeodToGeoc( 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
|
||||
//
|
||||
|
||||
/**
|
||||
* Convert from geodetic coordinates to geocentric coordinates
|
||||
* @param lat_geod (in) Geodetic latitude, radians, + = North
|
||||
* @param alt (in) C.G. altitude above mean sea level (meters)
|
||||
* @param sl_radius (out) SEA LEVEL radius to earth center (meters)
|
||||
* (add Altitude to get true distance from earth center.
|
||||
* @param lat_geoc (out) Geocentric latitude, radians, + = North
|
||||
*/
|
||||
void sgGeodToGeoc( 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
|
||||
|
||||
/**
|
||||
* Convert a geodetic point lon(radians), lat(radians), elev(meter) to
|
||||
* a cartesian point.
|
||||
* @param geodetic point
|
||||
* @return cartesian point
|
||||
*/
|
||||
inline Point3D sgGeodToCart(const Point3D& geod) {
|
||||
double gc_lon, gc_lat, sl_radius;
|
||||
|
||||
@@ -71,8 +70,18 @@ inline Point3D sgGeodToCart(const Point3D& geod) {
|
||||
}
|
||||
|
||||
|
||||
// given, alt, lat1, lon1, az1 and distance (s), calculate lat2, lon2
|
||||
// and az2. Lat, lon, and azimuth are in degrees. distance in meters
|
||||
/**
|
||||
* Given a starting position and an offset radial and distance,
|
||||
* calculate an ending positon on a wgs84 ellipsoid.
|
||||
* @param alt (in) meters
|
||||
* @param lat1 (in) degrees
|
||||
* @param lon1 (in) degrees
|
||||
* @param az1 (in) degrees
|
||||
* @param s (in) distance in meters
|
||||
* @param lat2 (out) degrees
|
||||
* @param lon2 (out) degrees
|
||||
* @param az2 (out) return course in degrees
|
||||
*/
|
||||
int geo_direct_wgs_84 ( double alt, double lat1, double lon1, double az1,
|
||||
double s, double *lat2, double *lon2, double *az2 );
|
||||
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
// fg_memory.h -- memcpy/bcopy portability declarations
|
||||
//
|
||||
/**
|
||||
* \file sg_memory.h
|
||||
* memcpy/bcopy portability declarations (not actually used by anything
|
||||
* as best as I can tell.
|
||||
*/
|
||||
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
@@ -18,8 +22,8 @@
|
||||
// $Id$
|
||||
|
||||
|
||||
#ifndef _FG_MEMORY_H
|
||||
#define _FG_MEMORY_H
|
||||
#ifndef _SG_MEMORY_H
|
||||
#define _SG_MEMORY_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
@@ -31,15 +35,15 @@
|
||||
# include <memory.h>
|
||||
# endif
|
||||
|
||||
# define fgmemcmp memcmp
|
||||
# define fgmemcpy memcpy
|
||||
# define fgmemzero(dest,len) memset(dest,0,len)
|
||||
# define sgmemcmp memcmp
|
||||
# define sgmemcpy memcpy
|
||||
# define sgmemzero(dest,len) memset(dest,0,len)
|
||||
|
||||
#elif defined(HAVE_BCOPY)
|
||||
|
||||
# define fgmemcmp bcmp
|
||||
# define fgmemcpy(dest,src,n) bcopy(src,dest,n)
|
||||
# define fgmemzero bzero
|
||||
# define sgmemcmp bcmp
|
||||
# define sgmemcpy(dest,src,n) bcopy(src,dest,n)
|
||||
# define sgmemzero bzero
|
||||
|
||||
#else
|
||||
|
||||
@@ -49,12 +53,12 @@
|
||||
*/
|
||||
|
||||
# include <zutil.h>
|
||||
# define fgmemcmp zmemcmp
|
||||
# define fgmemcpy zmemcpy
|
||||
# define fgmemzero zmemzero
|
||||
# define sgmemcmp zmemcmp
|
||||
# define sgmemcpy zmemcpy
|
||||
# define sgmemzero zmemzero
|
||||
|
||||
#endif
|
||||
|
||||
#endif // _FG_MEMORY_H
|
||||
#endif // _SG_MEMORY_H
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -41,7 +41,7 @@
|
||||
|
||||
#ifdef __SUNPRO_CC
|
||||
extern "C" {
|
||||
long int random(void);
|
||||
long int random();
|
||||
void srandom(unsigned int seed);
|
||||
}
|
||||
#endif
|
||||
@@ -49,7 +49,7 @@
|
||||
|
||||
// Seed the random number generater with time() so we don't see the
|
||||
// same sequence every time
|
||||
void sg_srandom_time(void) {
|
||||
void sg_srandom_time() {
|
||||
#ifdef HAVE_RAND
|
||||
srand(time(NULL));
|
||||
#else
|
||||
@@ -70,7 +70,7 @@ void sg_srandom( unsigned int seed ) {
|
||||
|
||||
|
||||
// return a random number between [0.0, 1.0)
|
||||
double sg_random(void) {
|
||||
double sg_random() {
|
||||
#ifdef HAVE_RAND
|
||||
return(rand() / (double)RAND_MAX);
|
||||
#else
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
// sg_random.h -- routines to handle random number generation
|
||||
//
|
||||
/**
|
||||
* \file sg_random.h
|
||||
* Routines to handle random number generation and hide platform differences.
|
||||
*/
|
||||
|
||||
// Written by Curtis Olson, started July 1997.
|
||||
//
|
||||
// Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
|
||||
@@ -31,16 +34,24 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
// Seed the random number generater with time() so we don't see the
|
||||
// same sequence every time
|
||||
void sg_srandom_time(void);
|
||||
/**
|
||||
* Seed the random number generater with time() so we don't see the
|
||||
* same sequence every time.
|
||||
*/
|
||||
void sg_srandom_time();
|
||||
|
||||
// Seed the random number generater with your own seed so can set up
|
||||
// repeatable randomization.
|
||||
/**
|
||||
* Seed the random number generater with your own seed so can set up
|
||||
* repeatable randomization.
|
||||
* @param seed random number generator seed
|
||||
*/
|
||||
void sg_srandom( unsigned int seed );
|
||||
|
||||
// return a random number between [0.0, 1.0)
|
||||
double sg_random(void);
|
||||
/**
|
||||
* Return a random number between [0.0, 1.0)
|
||||
* @return next "random" number in the "random" sequence
|
||||
*/
|
||||
double sg_random();
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
// fg_types.hxx -- commonly used types I don't want to have to keep redefining
|
||||
//
|
||||
/**
|
||||
* \file sg_types.hxx
|
||||
* Commonly used types I don't want to have to keep redefining.
|
||||
*/
|
||||
|
||||
// Written by Curtis Olson, started March 1999.
|
||||
//
|
||||
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
|
||||
@@ -22,8 +25,8 @@
|
||||
// $Id$
|
||||
|
||||
|
||||
#ifndef _FG_TYPES_HXX
|
||||
#define _FG_TYPES_HXX
|
||||
#ifndef _SG_TYPES_HXX
|
||||
#define _SG_TYPES_HXX
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
@@ -38,23 +41,29 @@
|
||||
|
||||
#include <simgear/math/point3d.hxx>
|
||||
|
||||
FG_USING_STD(vector);
|
||||
FG_USING_STD(string);
|
||||
|
||||
SG_USING_STD(vector);
|
||||
SG_USING_STD(string);
|
||||
|
||||
/** STL vector list of ints */
|
||||
typedef vector < int > int_list;
|
||||
typedef int_list::iterator int_list_iterator;
|
||||
typedef int_list::const_iterator const_int_list_iterator;
|
||||
|
||||
/** STL vector list of Point3D */
|
||||
typedef vector < Point3D > point_list;
|
||||
typedef point_list::iterator point_list_iterator;
|
||||
typedef point_list::const_iterator const_point_list_iterator;
|
||||
|
||||
/** STL vector list of strings */
|
||||
typedef vector < string > string_list;
|
||||
typedef string_list::iterator string_list_iterator;
|
||||
typedef string_list::const_iterator const_string_list_iterator;
|
||||
|
||||
|
||||
/**
|
||||
* Simple 2d point class where members can be accessed as x, dist, or lon
|
||||
* and y, theta, or lat
|
||||
*/
|
||||
class point2d {
|
||||
public:
|
||||
union {
|
||||
@@ -70,5 +79,5 @@ public:
|
||||
};
|
||||
|
||||
|
||||
#endif // _FG_TYPES_HXX
|
||||
#endif // _SG_TYPES_HXX
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
// vector.hxx -- additional vector routines
|
||||
//
|
||||
/**
|
||||
* \file vector.hxx
|
||||
* Additional vector routines.
|
||||
*/
|
||||
|
||||
// Written by Curtis Olson, started December 1997.
|
||||
//
|
||||
// Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
|
||||
@@ -30,15 +33,18 @@
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <plib/sg.h>
|
||||
|
||||
|
||||
/**
|
||||
* Map a vector onto a plane.
|
||||
* @param normal (in) normal vector for the plane
|
||||
* @param v0 (in) a point on the plane
|
||||
* @param vec (in) the vector to map onto the plane
|
||||
* @param result (out) the result vector
|
||||
*/
|
||||
inline void sgmap_vec_onto_cur_surface_plane( sgVec3 normal,
|
||||
sgVec3 v0,
|
||||
sgVec3 vec,
|
||||
@@ -84,6 +90,11 @@ inline void sgmap_vec_onto_cur_surface_plane( sgVec3 normal,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy and negate a vector.
|
||||
* @param dst (out) result vector
|
||||
* @param src (in) input vector
|
||||
*/
|
||||
inline void sgCopyNegateVec4( sgVec4 dst, sgVec4 src )
|
||||
{
|
||||
dst [ 0 ] = -src [ 0 ] ;
|
||||
@@ -92,31 +103,64 @@ inline void sgCopyNegateVec4( sgVec4 dst, sgVec4 src )
|
||||
dst [ 3 ] = -src [ 3 ] ;
|
||||
}
|
||||
|
||||
// Given a point p, and a line through p0 with direction vector d,
|
||||
// find the closest point (p1) on the line
|
||||
/**
|
||||
* Given a point p, and a line through p0 with direction vector d,
|
||||
* find the closest point (p1) on the line (float version).
|
||||
* @param p1 (out) closest point to p on the line
|
||||
* @param p (in) original point
|
||||
* @param p0 (in) point on the line
|
||||
* @param d (in) vector defining line direction
|
||||
*/
|
||||
void sgClosestPointToLine( sgVec3 p1, const sgVec3 p, const sgVec3 p0,
|
||||
const sgVec3 d );
|
||||
|
||||
// Given a point p, and a line through p0 with direction vector d,
|
||||
// find the closest point (p1) on the line
|
||||
/**
|
||||
* Given a point p, and a line through p0 with direction vector d,
|
||||
* find the closest point (p1) on the line (double version).
|
||||
* @param p1 (out) closest point to p on the line
|
||||
* @param p (in) original point
|
||||
* @param p0 (in) point on the line
|
||||
* @param d (in) vector defining line direction
|
||||
*/
|
||||
void sgdClosestPointToLine( sgdVec3 p1, const sgdVec3 p, const sgdVec3 p0,
|
||||
const sgdVec3 d );
|
||||
|
||||
// Given a point p, and a line through p0 with direction vector d,
|
||||
// find the shortest distance (squared) from the point to the line
|
||||
/**
|
||||
* Given a point p, and a line through p0 with direction vector d,
|
||||
* find the shortest distance (squared) from the point to the line (float
|
||||
* version.)
|
||||
* @param p (in) original point
|
||||
* @param p0 (in) point on the line
|
||||
* @param d (in) vector defining line direction
|
||||
* @return shortest distance (squared) from p to line
|
||||
*/
|
||||
double sgClosestPointToLineDistSquared( const sgVec3 p, const sgVec3 p0,
|
||||
const sgVec3 d );
|
||||
|
||||
// Given a point p, and a line through p0 with direction vector d,
|
||||
// find the shortest distance (squared) from the point to the line
|
||||
/**
|
||||
* Given a point p, and a line through p0 with direction vector d,
|
||||
* find the shortest distance (squared) from the point to the line (double
|
||||
* version.)
|
||||
* @param p (in) original point
|
||||
* @param p0 (in) point on the line
|
||||
* @param d (in) vector defining line direction
|
||||
* @return shortest distance (squared) from p to line
|
||||
*/
|
||||
double sgdClosestPointToLineDistSquared( const sgdVec3 p, const sgdVec3 p0,
|
||||
const sgdVec3 d );
|
||||
|
||||
// This is same as
|
||||
// sgMakeMatTrans4( sgMat4 sgTrans, sgVec3 trans )
|
||||
// sgPostMultMat4( sgMat, sgTRANS );
|
||||
/**
|
||||
* This is same as:
|
||||
*
|
||||
* <li> sgMakeMatTrans4( sgMat4 sgTrans, sgVec3 trans )
|
||||
* <li> sgPostMultMat4( sgMat4 src, sgTRANS );
|
||||
*
|
||||
* @param src starting sgMat4 matrix
|
||||
* @param trans translation vector
|
||||
*/
|
||||
void sgPostMultMat4ByTransMat4( sgMat4 src, const sgVec3 trans );
|
||||
|
||||
|
||||
#endif // _VECTOR_HXX
|
||||
|
||||
|
||||
|
||||
@@ -29,14 +29,22 @@
|
||||
/* in the conversion. */
|
||||
/* */
|
||||
/* Output:- An integer corresponding to the value in the character */
|
||||
/* array or MAXNEG (-2147483648) if the function is */
|
||||
/* array or INT32_MIN (-2147483647-1) if the function is */
|
||||
/* unable to acquire system storage. */
|
||||
/* */
|
||||
/* Modification History: */
|
||||
/* None */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
#ifndef INT32_MIN
|
||||
# define INT32_MIN (-2147483647-1)
|
||||
#endif
|
||||
|
||||
int antoi(char * string, int len)
|
||||
{
|
||||
|
||||
@@ -55,7 +63,7 @@ int antoi(char * string, int len)
|
||||
|
||||
tmpstr = (char *)malloc((len+1) * sizeof(char));
|
||||
|
||||
if (tmpstr == NULL) return (-2147483648);
|
||||
if (tmpstr == NULL) return INT32_MIN;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
tmpstr[i] = string[i];
|
||||
|
||||
@@ -65,13 +65,17 @@
|
||||
#define IMOD(i, j) (((i) % (j)) < 0 ? ((i) % (j))+(j) : ((i) % (j)))
|
||||
#define IN_RANGE(n, lo, hi) ((lo) <= (n) && (n) <= (hi))
|
||||
#define LOOPDN(r, n) for ((r) = (n)+1; --(r) > 0;)
|
||||
#define MAX(x, y) (((x) < (y)) ? (y) : (x))
|
||||
#ifndef max
|
||||
#define max(x, y) (((x) < (y)) ? (y) : (x))
|
||||
#ifndef MAX
|
||||
# define MAX(x, y) (((x) < (y)) ? (y) : (x))
|
||||
#endif
|
||||
#ifndef max
|
||||
# define max(x, y) (((x) < (y)) ? (y) : (x))
|
||||
#endif
|
||||
#ifndef MIN
|
||||
# define MIN(x, y) (((x) < (y)) ? (x) : (y))
|
||||
#endif
|
||||
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
|
||||
#ifndef min
|
||||
#define min(x, y) (((x) < (y)) ? (x) : (y))
|
||||
# define min(x, y) (((x) < (y)) ? (x) : (y))
|
||||
#endif
|
||||
#define STREQ(s, t) (strcmp(s, t) == 0)
|
||||
#define STRGT(s, t) (strcmp(s, t) > 0)
|
||||
|
||||
@@ -2,11 +2,13 @@ includedir = @includedir@/metar
|
||||
|
||||
lib_LIBRARIES = libsgmetar.a
|
||||
|
||||
include_HEADERS = MetarReport.h MetarStation.h
|
||||
|
||||
libsgmetar_a_SOURCES = \
|
||||
Antoi.cpp Charcmp.cpp Dcdmetar.cpp Dcdmtrmk.cpp Drvmetar.c \
|
||||
Fracpart.cpp Local.h Metar.h \
|
||||
MetarReport.cpp MetarReport.h \
|
||||
MetarStation.cpp MetarStation.h \
|
||||
MetarReport.cpp \
|
||||
MetarStation.cpp \
|
||||
Prtdmetr.cpp Stspack2.cpp Stspack3.cpp
|
||||
|
||||
INCLUDES += -I$(top_srcdir)
|
||||
|
||||
@@ -1,8 +1,17 @@
|
||||
// Metar report implementation class code
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include STL_IOSTREAM
|
||||
|
||||
#include "MetarReport.h"
|
||||
#include "Metar.h"
|
||||
|
||||
#if !defined (SG_HAVE_NATIVE_SGI_COMPILERS)
|
||||
SG_USING_STD(endl);
|
||||
SG_USING_STD(ostream);
|
||||
#endif
|
||||
|
||||
CMetarReport::CMetarReport(
|
||||
char *s ) :
|
||||
m_DecodedReport( 0 )
|
||||
@@ -31,7 +40,7 @@ static int DecodeDirChars( char* c )
|
||||
if ( c[1] == 'E' ) r = 45;
|
||||
else if ( c[1] == 'W' ) r = 315;
|
||||
}
|
||||
else if ( r = 180 )
|
||||
else if ( r == 180 )
|
||||
{
|
||||
if ( c[1] == 'E' ) r = 135;
|
||||
else if ( c[1] == 'W' ) r = 225;
|
||||
@@ -45,6 +54,21 @@ char *CMetarReport::StationID()
|
||||
return ((Decoded_METAR *)m_DecodedReport)->stnid;
|
||||
}
|
||||
|
||||
int CMetarReport::Day()
|
||||
{
|
||||
return ((Decoded_METAR*)m_DecodedReport)->ob_date;
|
||||
}
|
||||
|
||||
int CMetarReport::Hour()
|
||||
{
|
||||
return ((Decoded_METAR*)m_DecodedReport)->ob_hour;
|
||||
}
|
||||
|
||||
int CMetarReport::Minutes()
|
||||
{
|
||||
return ((Decoded_METAR*)m_DecodedReport)->ob_minute;
|
||||
}
|
||||
|
||||
int CMetarReport::WindDirection()
|
||||
{
|
||||
return ((Decoded_METAR *)m_DecodedReport)->winData.windDir;
|
||||
@@ -192,17 +216,22 @@ int CMetarReport::VerticalVisibility() // Meters
|
||||
|
||||
int CMetarReport::Ceiling()
|
||||
{
|
||||
return FEET_TO_METER * ((Decoded_METAR *)m_DecodedReport)->Ceiling;
|
||||
return
|
||||
(int)(SG_FEET_TO_METER*((Decoded_METAR *)m_DecodedReport)->Ceiling);
|
||||
}
|
||||
|
||||
int CMetarReport::EstimatedCeiling()
|
||||
{
|
||||
return FEET_TO_METER * ((Decoded_METAR *)m_DecodedReport)->Estimated_Ceiling;
|
||||
return
|
||||
(int)(SG_FEET_TO_METER
|
||||
* ((Decoded_METAR *)m_DecodedReport)->Estimated_Ceiling);
|
||||
}
|
||||
|
||||
int CMetarReport::VariableSkyLayerHeight()
|
||||
{
|
||||
return FEET_TO_METER * ((Decoded_METAR *)m_DecodedReport)->VrbSkyLayerHgt;
|
||||
return
|
||||
(int)(SG_FEET_TO_METER
|
||||
* ((Decoded_METAR *)m_DecodedReport)->VrbSkyLayerHgt);
|
||||
}
|
||||
|
||||
int CMetarReport::SnowDepthInches()
|
||||
@@ -211,49 +240,72 @@ int CMetarReport::SnowDepthInches()
|
||||
}
|
||||
|
||||
|
||||
std::ostream&
|
||||
ostream&
|
||||
operator << ( ostream& out, CMetarReport& p )
|
||||
{
|
||||
return out
|
||||
<< "StationID " << p.StationID()
|
||||
<< " WindDirection " << p.WindDirection()
|
||||
<< " WindSpeed " << p.WindSpeed()
|
||||
<< " WindGustSpeed " << p.WindGustSpeed() << std::endl
|
||||
<< " WindGustSpeed " << p.WindGustSpeed() << endl
|
||||
<< "CloudLow " << p.CloudLow()
|
||||
<< " CloudMedium " << p.CloudMedium()
|
||||
<< " CloudHigh " << p.CloudHigh() << std::endl
|
||||
<< " CloudHigh " << p.CloudHigh() << endl
|
||||
<< "TornadicDirection " << p.TornadicDirection()
|
||||
<< " TornadicMovementDirection " << p.TornadicMovementDirection() << std::endl
|
||||
<< " TornadicMovementDirection " << p.TornadicMovementDirection() << endl
|
||||
<< "ThunderStormDirection " << p.ThunderStormDirection()
|
||||
<< " ThunderStormMovementDirection " << p.ThunderStormMovementDirection() << std::endl
|
||||
<< " ThunderStormMovementDirection " << p.ThunderStormMovementDirection() << endl
|
||||
<< "Virga " << p.Virga()
|
||||
<< " VirgaDirection " << p.VirgaDirection() << std::endl
|
||||
<< "VolcanicAsh " << p.VolcanicAsh() << std::endl
|
||||
<< "Hail " << p.Hail() << std::endl
|
||||
<< " VirgaDirection " << p.VirgaDirection() << endl
|
||||
<< "VolcanicAsh " << p.VolcanicAsh() << endl
|
||||
<< "Hail " << p.Hail() << endl
|
||||
<< "LightningDirection " << p.LightningDirection()
|
||||
<< " OccationalLightning " << p.OccationalLightning()
|
||||
<< " FrequentLightning " << p.FrequentLightning()
|
||||
<< " ContinuousLightning " << p.ContinuousLightning() << std::endl
|
||||
<< " ContinuousLightning " << p.ContinuousLightning() << endl
|
||||
<< "CloudToGroundLightning " << p.CloudToGroundLightning()
|
||||
<< " InterCloudLightning " << p.InterCloudLightning()
|
||||
<< " CloudToCloudLightning " << p.CloudToCloudLightning()
|
||||
<< " CloudToAirLightning " << p.CloudToAirLightning() << std::endl
|
||||
<< " CloudToAirLightning " << p.CloudToAirLightning() << endl
|
||||
<< "DistantLightning " << p.DistantLightning()
|
||||
<< " AirportLightning " << p.AirportLightning()
|
||||
<< " VicinityLightning " << p.VicinityLightning()
|
||||
<< " OverheadLightning " << p.OverheadLightning() << std::endl
|
||||
<< "VerticalVisibility " << p.VerticalVisibility() << std::endl // Meters
|
||||
<< " OverheadLightning " << p.OverheadLightning() << endl
|
||||
<< "VerticalVisibility " << p.VerticalVisibility() << endl // Meters
|
||||
<< "Temperature " << p.Temperature()
|
||||
<< " DewpointTemperature " << p.DewpointTemperature() << std::endl
|
||||
<< " DewpointTemperature " << p.DewpointTemperature() << endl
|
||||
<< "Ceiling " << p.Ceiling()
|
||||
<< " EstimatedCeiling " << p.EstimatedCeiling()
|
||||
<< " VariableSkyLayerHeight " << p.VariableSkyLayerHeight() << std::endl
|
||||
<< "SnowDepthInches " << p.SnowDepthInches() << std::endl
|
||||
<< " VariableSkyLayerHeight " << p.VariableSkyLayerHeight() << endl
|
||||
<< "SnowDepthInches " << p.SnowDepthInches() << endl
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
double CMetarReport::AirPressure()
|
||||
{
|
||||
return ((Decoded_METAR *)m_DecodedReport)->inches_altstng;
|
||||
}
|
||||
|
||||
void CMetarReport::dump()
|
||||
{
|
||||
prtDMETR( (Decoded_METAR *)m_DecodedReport );
|
||||
}
|
||||
|
||||
double CMetarReport::PrevailVisibility()
|
||||
{
|
||||
//Values from each visibility field converted to meters.
|
||||
double smiles;
|
||||
double km;
|
||||
double meters;
|
||||
smiles = ((Decoded_METAR*) m_DecodedReport)->prevail_vsbySM * 1609.34;
|
||||
km = ((Decoded_METAR*) m_DecodedReport)->prevail_vsbyKM * 1000;
|
||||
meters = ((Decoded_METAR*) m_DecodedReport)->prevail_vsbyM;
|
||||
|
||||
/* Return the smallest one. If the field is specified it should have been
|
||||
set to MAX_INT */
|
||||
if(smiles < km && smiles < meters)
|
||||
return smiles;
|
||||
else
|
||||
return km < meters ? km : meters;
|
||||
}
|
||||
|
||||
@@ -7,12 +7,17 @@
|
||||
#ifndef _MetarReport_
|
||||
#define _MetarReport_
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include STL_IOSTREAM
|
||||
#include STL_STRING
|
||||
#include <vector>
|
||||
|
||||
#include <simgear/math/point3d.hxx>
|
||||
#include <simgear/math/polar3d.hxx>
|
||||
|
||||
SG_USING_STD(string);
|
||||
|
||||
class CMetarReport
|
||||
{
|
||||
// Typedefs, enumerations
|
||||
@@ -38,6 +43,10 @@ public:
|
||||
|
||||
char *StationID();
|
||||
|
||||
int Day(); // The day of month on which the report was issued.
|
||||
int Hour(); // The hour of the day the report was issued.
|
||||
int Minutes(); //Minutes past the hour of the report issue time.
|
||||
|
||||
// Directions in degrees
|
||||
// Speed in knots
|
||||
// Altitude in meters
|
||||
@@ -93,7 +102,9 @@ public:
|
||||
int VariableSkyLayerHeight();
|
||||
|
||||
int SnowDepthInches();
|
||||
|
||||
|
||||
double AirPressure(); //Return the air pressure in InchesHg.
|
||||
double PrevailVisibility(); // Prevailing Visibility in meters.
|
||||
void dump();
|
||||
|
||||
private:
|
||||
@@ -106,6 +117,6 @@ private:
|
||||
// Assignment operator. Not implemented.
|
||||
};
|
||||
|
||||
std::ostream& operator << ( std::ostream&, CMetarReport& );
|
||||
ostream& operator << ( ostream&, CMetarReport& );
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,22 +1,18 @@
|
||||
// Metar station implementation code
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include STL_IOSTREAM
|
||||
#include <stdio.h>
|
||||
|
||||
#include "MetarStation.h"
|
||||
#include <algorithm>
|
||||
#define TESTPROG
|
||||
#ifndef TESTPROG
|
||||
// options is too tightly integrated into FlightGear to use in a test program
|
||||
#include <Main/options.hxx>
|
||||
|
||||
#if !defined (SG_HAVE_NATIVE_SGI_COMPILERS)
|
||||
SG_USING_STD(ostream);
|
||||
SG_USING_STD(cout);
|
||||
SG_USING_STD(endl);
|
||||
#endif
|
||||
#include <simgear/misc/fgpath.hxx>
|
||||
|
||||
|
||||
std::vector< CMetarStation *> METAR_Stations;
|
||||
|
||||
int CMetarStation::initialized( CMetarStation::initialize() );
|
||||
|
||||
std::string CMetarStation::tempName;
|
||||
|
||||
|
||||
double CMetarStation::decodeDMS( char *b )
|
||||
@@ -50,9 +46,12 @@ double CMetarStation::decodeDMS( char *b )
|
||||
// Direction (E W N S)
|
||||
if ( *b == 'W' || *b == 'S' ) r = -r;
|
||||
}
|
||||
return r * DEG_TO_RAD;
|
||||
return r * SGD_DEGREES_TO_RADIANS;
|
||||
}
|
||||
|
||||
// Constructor
|
||||
// Decodes METAR station string of this format:
|
||||
// KPUB;72;464;Pueblo, Pueblo Memorial Airport;CO;United States;4;38-17-24N;104-29-54W;38-17-03N;104-29-43W;1440;1420;P
|
||||
|
||||
CMetarStation::CMetarStation(
|
||||
char *s )
|
||||
@@ -81,149 +80,139 @@ CMetarStation::CMetarStation(
|
||||
s = t; t = strchr( s, ';' ); *t = 0; t++;
|
||||
double ulongitude = decodeDMS( s );
|
||||
s = t; t = strchr( s, ';' ); *t = 0; t++;
|
||||
double altitude = atoi( s ) * FEET_TO_METER;
|
||||
double altitude = atoi( s ) * SG_FEET_TO_METER;
|
||||
m_altitude = (int)altitude;
|
||||
s = t; t = strchr( s, ';' ); *t = 0; t++;
|
||||
double ualtitude = atoi( s ) * FEET_TO_METER;
|
||||
Point3D p( longitude, latitude, altitude+EQUATORIAL_RADIUS_M );
|
||||
double ualtitude = atoi( s ) * SG_FEET_TO_METER;
|
||||
Point3D p( longitude, latitude, altitude+SG_EQUATORIAL_RADIUS_M );
|
||||
m_locationPolar = p;
|
||||
m_locationCart = sgPolarToCart3d( p );
|
||||
Point3D up( ulongitude, ulatitude, ualtitude+EQUATORIAL_RADIUS_M );
|
||||
Point3D up( ulongitude, ulatitude, ualtitude+SG_EQUATORIAL_RADIUS_M );
|
||||
m_upperLocationPolar = up;
|
||||
m_upperLocationCart = sgPolarToCart3d( up );
|
||||
s = t;
|
||||
m_pFlag = s[0];
|
||||
}
|
||||
// Constructor
|
||||
// Decodes METAR station string of this format:
|
||||
// KPUB;72;464;Pueblo, Pueblo Memorial Airport;CO;United States;4;38-17-24N;104-29-54W;38-17-03N;104-29-43W;1440;1420;P
|
||||
|
||||
|
||||
|
||||
int CMetarStation::initialize()
|
||||
void CMetarStation::dump()
|
||||
{
|
||||
cout << "ID:" << ID();
|
||||
cout << endl;
|
||||
cout << "number:" << number();
|
||||
cout << endl;
|
||||
cout << "name:" << name();
|
||||
cout << endl;
|
||||
cout << "state:" << state();
|
||||
cout << endl;
|
||||
cout << "country:" << country();
|
||||
cout << endl;
|
||||
cout << "region:" << region();
|
||||
cout << endl;
|
||||
cout << "Location (cart):" << locationCart();
|
||||
cout << endl;
|
||||
cout << "Location (polar):" << locationPolar();
|
||||
cout << endl;
|
||||
cout << "Upper Location (cart):" << upperLocationCart();
|
||||
cout << endl;
|
||||
cout << "Upper Location (polar):" << upperLocationPolar();
|
||||
cout << endl;
|
||||
cout << "P flag:" << pFlag();
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CMetarStationDB::CMetarStationDB(const char * dbPath)
|
||||
{
|
||||
// Read the list of metar stations, decoding and adding to global list.
|
||||
|
||||
CMetarStation *m;
|
||||
char buf[256];
|
||||
|
||||
// Goto the Flight Gear installation directory
|
||||
#ifdef TESTPROG
|
||||
//FGPath weatherPath( "/mkv/Build/FlightGear" );
|
||||
FGPath weatherPath( ":Data" );
|
||||
#else
|
||||
FGPath weatherPath( current_options.get_fg_root() );
|
||||
#endif
|
||||
|
||||
weatherPath.append( "Weather" );
|
||||
weatherPath.append( "MetarStations" );
|
||||
// Open the metar station list
|
||||
FILE *f = fopen( weatherPath.c_str(), "r" );
|
||||
FILE *f = fopen( dbPath, "r" );
|
||||
|
||||
|
||||
if ( f != NULL ) {
|
||||
// Read each line, create an instance of a station, and add it to the vector
|
||||
while ( fgets( buf, 256, f) != NULL && feof( f ) == 0 ) {
|
||||
//std::cout << buf << std::endl;
|
||||
// cout << buf << endl;
|
||||
m = new CMetarStation( buf );
|
||||
//m->dump();
|
||||
METAR_Stations.push_back( m );
|
||||
METAR_Stations[m->ID()]=( m );
|
||||
}
|
||||
|
||||
// Close the list
|
||||
fclose( f );
|
||||
// std::cout << METAR_Stations.size() << " Metar stations" << std::endl;
|
||||
return 1;
|
||||
// cout << METAR_Stations.size() << " Metar stations" << endl;
|
||||
|
||||
} else {
|
||||
// std::cout << "Could not open MetarStations file " << std::endl;
|
||||
return 0;
|
||||
// cout << "Could not open MetarStations file " << endl;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int CMetarStation::sameName( CMetarStation *m )
|
||||
|
||||
CMetarStation * CMetarStationDB::find( std::string stationID )
|
||||
{
|
||||
return m->m_ID == tempName;
|
||||
std::map<std::string,CMetarStation*>::iterator target;
|
||||
target = METAR_Stations.find(stationID);
|
||||
if(target!= METAR_Stations.end() )
|
||||
return target->second;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
CMetarStation *CMetarStation::find( std::string stationID )
|
||||
{
|
||||
tempName = stationID;
|
||||
CMetarStation **m = std::find_if( METAR_Stations.begin(), METAR_Stations.end(), sameName );
|
||||
if ( m != METAR_Stations.end() ) return *m;
|
||||
return 0;
|
||||
}
|
||||
|
||||
double bestDist;
|
||||
CMetarStation *bestStation;
|
||||
Point3D curLocation;
|
||||
|
||||
void findHelper( CMetarStation *s )
|
||||
CMetarStation * CMetarStationDB::find( Point3D locationCart )
|
||||
{
|
||||
double dist = s->locationCart().distance3Dsquared( curLocation );
|
||||
std::map<std::string,CMetarStation*>::iterator itr;
|
||||
double bestDist = 99999999;
|
||||
CMetarStation *bestStation = NULL;
|
||||
Point3D curLocation = locationCart;
|
||||
itr = METAR_Stations.begin();
|
||||
while(itr != METAR_Stations.end())
|
||||
{
|
||||
double dist = itr->second->locationCart().distance3Dsquared( curLocation );
|
||||
if (dist < bestDist )
|
||||
{
|
||||
bestDist = dist;
|
||||
bestStation = s;
|
||||
}
|
||||
}
|
||||
|
||||
CMetarStation *CMetarStation::find( Point3D locationCart )
|
||||
{
|
||||
bestDist = 99999999;
|
||||
bestStation = 0;
|
||||
curLocation = locationCart;
|
||||
|
||||
for_each( findHelper );
|
||||
return bestStation;
|
||||
{
|
||||
bestDist = dist;
|
||||
bestStation = itr->second;
|
||||
}
|
||||
itr++;
|
||||
}
|
||||
|
||||
return bestStation;
|
||||
}
|
||||
|
||||
|
||||
void CMetarStation::for_each( void f( CMetarStation *s ) )
|
||||
{
|
||||
std::for_each( METAR_Stations.begin(), METAR_Stations.end(), f );
|
||||
CMetarStationDB::~CMetarStationDB() {
|
||||
std::map<std::string,CMetarStation*>::iterator itr;
|
||||
for(itr = METAR_Stations.begin(); itr != METAR_Stations.end(); itr++)
|
||||
{
|
||||
delete itr->second;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CMetarStation::dump()
|
||||
{
|
||||
std::cout << "ID:" << ID();
|
||||
std::cout << std::endl;
|
||||
std::cout << "number:" << number();
|
||||
std::cout << std::endl;
|
||||
std::cout << "name:" << name();
|
||||
std::cout << std::endl;
|
||||
std::cout << "state:" << state();
|
||||
std::cout << std::endl;
|
||||
std::cout << "country:" << country();
|
||||
std::cout << std::endl;
|
||||
std::cout << "region:" << region();
|
||||
std::cout << std::endl;
|
||||
std::cout << "Location (cart):" << locationCart();
|
||||
std::cout << std::endl;
|
||||
std::cout << "Location (polar):" << locationPolar();
|
||||
std::cout << std::endl;
|
||||
std::cout << "Upper Location (cart):" << upperLocationCart();
|
||||
std::cout << std::endl;
|
||||
std::cout << "Upper Location (polar):" << upperLocationPolar();
|
||||
std::cout << std::endl;
|
||||
std::cout << "P flag:" << pFlag();
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
ostream&
|
||||
operator << ( ostream& out, const CMetarStation& p )
|
||||
{
|
||||
return out
|
||||
<< "ID:" << p.m_ID << std::endl
|
||||
<< "number:" << p.m_number << std::endl
|
||||
<< "name:" << p.m_name << std::endl
|
||||
<< "state:" << p.m_state << std::endl
|
||||
<< "country:" << p.m_country << std::endl
|
||||
<< "region:" << p.m_region << std::endl
|
||||
<< "Location (cart):" << p.m_locationCart << std::endl
|
||||
<< "Location (polar):" << p.m_locationCart << std::endl
|
||||
<< "Upper Location (cart):" << p.m_upperLocationCart << std::endl
|
||||
<< "Upper Location (polar):" << p.m_upperLocationPolar << std::endl
|
||||
<< "P flag:" << p.m_pFlag << std::endl;
|
||||
<< "ID:" << p.m_ID << endl
|
||||
<< "number:" << p.m_number << endl
|
||||
<< "name:" << p.m_name << endl
|
||||
<< "state:" << p.m_state << endl
|
||||
<< "country:" << p.m_country << endl
|
||||
<< "region:" << p.m_region << endl
|
||||
<< "Location (cart):" << p.m_locationCart << endl
|
||||
<< "Location (polar):" << p.m_locationCart << endl
|
||||
<< "Upper Location (cart):" << p.m_upperLocationCart << endl
|
||||
<< "Upper Location (polar):" << p.m_upperLocationPolar << endl
|
||||
<< "P flag:" << p.m_pFlag << endl;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,17 +3,26 @@
|
||||
// METAR station information is kept in this file:
|
||||
// http://www.nws.noaa.gov/pub/stninfo/nsd_cccc.gz
|
||||
// http://www.nws.noaa.gov/pub/stninfo/nsd_cccc.txt
|
||||
// This class looks for the file FG_ROOT/Weather/MetarStations instread of nsd_cccc.
|
||||
|
||||
|
||||
#ifndef _MetarStation_
|
||||
#define _MetarStation_
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include STL_IOSTREAM
|
||||
#include STL_STRING
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include <simgear/math/point3d.hxx>
|
||||
#include <simgear/math/polar3d.hxx>
|
||||
//using namespace std;
|
||||
|
||||
SG_USING_STD(string);
|
||||
SG_USING_STD(vector);
|
||||
SG_USING_STD(map);
|
||||
|
||||
class CMetarStationDB;
|
||||
|
||||
class CMetarStation
|
||||
{
|
||||
@@ -32,14 +41,12 @@ private:
|
||||
int m_altitude;
|
||||
int m_upperAltitude;
|
||||
char m_pFlag;
|
||||
|
||||
static int initialized;
|
||||
static std::string tempName;
|
||||
|
||||
|
||||
// Operations
|
||||
private:
|
||||
double decodeDMS( char *b );
|
||||
static int sameName( CMetarStation *m );
|
||||
|
||||
|
||||
|
||||
CMetarStation(
|
||||
char *s );
|
||||
@@ -57,6 +64,8 @@ public:
|
||||
std::string &state() { return m_state; }
|
||||
std::string &country() { return m_country; }
|
||||
int region() { return m_region; }
|
||||
unsigned int Altitude() { //Returns the stations height above MSL in M.
|
||||
return m_altitude;}
|
||||
Point3D &locationPolar() { return m_locationPolar; }
|
||||
Point3D &upperLocationPolar() { return m_upperLocationPolar; }
|
||||
Point3D &locationCart() { return m_locationCart; }
|
||||
@@ -64,12 +73,11 @@ public:
|
||||
char pFlag() { return m_pFlag; }
|
||||
// Get attributes
|
||||
|
||||
friend std::ostream& operator << ( std::ostream&, const CMetarStation& );
|
||||
friend ostream& operator << ( ostream&, const CMetarStation& );
|
||||
void dump();
|
||||
|
||||
static CMetarStation *find( std::string stationID );
|
||||
static CMetarStation *find( Point3D locationCart );
|
||||
static void for_each( void f( CMetarStation *s ) );
|
||||
|
||||
|
||||
|
||||
private:
|
||||
CMetarStation(
|
||||
@@ -80,8 +88,23 @@ private:
|
||||
const CMetarStation &rObj );
|
||||
// Assignment operator. Not implemented.
|
||||
|
||||
static int initialize();
|
||||
friend class CMetarStationDB;
|
||||
};
|
||||
|
||||
|
||||
class CMetarStationDB
|
||||
{
|
||||
|
||||
private:
|
||||
std::string databasePath; //The path of the database file.
|
||||
std::map<std::string , CMetarStation *> METAR_Stations;
|
||||
CMetarStation * bestStation;
|
||||
|
||||
public:
|
||||
CMetarStation *find( std::string stationID );
|
||||
CMetarStation * find( Point3D locationCart );
|
||||
CMetarStationDB(const char * dbFile);
|
||||
~CMetarStationDB();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -468,7 +468,7 @@ display(void)
|
||||
CMetarStation::for_each( dispMetarStation );
|
||||
glEnd();
|
||||
glColor3d(0.0, 0.0, 1.0);
|
||||
glutWireSphere(EARTH_RAD,32,16);
|
||||
glutWireSphere(SG_EARTH_RAD,32,16);
|
||||
glutSwapBuffers();
|
||||
ii++;
|
||||
glPopMatrix();
|
||||
|
||||
@@ -9,21 +9,28 @@ endif
|
||||
lib_LIBRARIES = libsgmisc.a
|
||||
|
||||
include_HEADERS = \
|
||||
fgpath.hxx \
|
||||
fgstream.hxx \
|
||||
commands.hxx \
|
||||
props.hxx \
|
||||
sg_path.hxx \
|
||||
sgstream.hxx \
|
||||
stopwatch.hxx \
|
||||
strutils.hxx \
|
||||
texcoord.hxx \
|
||||
zfstream.hxx
|
||||
|
||||
libsgmisc_a_SOURCES = \
|
||||
fgpath.cxx \
|
||||
fgstream.cxx \
|
||||
commands.cxx \
|
||||
props.cxx \
|
||||
props_io.cxx \
|
||||
sg_path.cxx \
|
||||
sgstream.cxx \
|
||||
strutils.cxx \
|
||||
texcoord.cxx \
|
||||
zfstream.cxx
|
||||
|
||||
noinst_PROGRAMS = props_test
|
||||
|
||||
props_test_SOURCES = props_test.cxx
|
||||
props_test_LDADD = libsgmisc.a ../xml/libsgxml.a ../debug/libsgdebug.a
|
||||
|
||||
INCLUDES += -I$(top_srcdir) $(ZLIB_INCL)
|
||||
|
||||
163
simgear/misc/commands.cxx
Normal file
163
simgear/misc/commands.cxx
Normal file
@@ -0,0 +1,163 @@
|
||||
// commands.cxx - encapsulated commands.
|
||||
// Started Spring 2001 by David Megginson, david@megginson.com
|
||||
// This code is released into the Public Domain.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
#include "commands.hxx"
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of SGCommandState class.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SGCommandState::SGCommandState ()
|
||||
: _args(0)
|
||||
{
|
||||
}
|
||||
|
||||
SGCommandState::SGCommandState (const SGPropertyNode * args)
|
||||
: _args(0)
|
||||
{
|
||||
setArgs(args);
|
||||
}
|
||||
|
||||
SGCommandState::~SGCommandState ()
|
||||
{
|
||||
delete _args;
|
||||
}
|
||||
|
||||
void
|
||||
SGCommandState::setArgs (const SGPropertyNode * args)
|
||||
{
|
||||
delete _args;
|
||||
_args = new SGPropertyNode();
|
||||
copyProperties(args, _args);
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of SGCommandMgr class.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
SGCommandMgr::SGCommandMgr ()
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
|
||||
SGCommandMgr::~SGCommandMgr ()
|
||||
{
|
||||
// no-op
|
||||
}
|
||||
|
||||
void
|
||||
SGCommandMgr::addCommand (const string &name, command_t command)
|
||||
{
|
||||
_commands[name] = command;
|
||||
}
|
||||
|
||||
SGCommandMgr::command_t
|
||||
SGCommandMgr::getCommand (const string &name) const
|
||||
{
|
||||
const command_map::const_iterator it = _commands.find(name);
|
||||
return (it != _commands.end() ? it->second : 0);
|
||||
}
|
||||
|
||||
vector<string>
|
||||
SGCommandMgr::getCommandNames () const
|
||||
{
|
||||
vector<string> names;
|
||||
command_map::const_iterator it = _commands.begin();
|
||||
command_map::const_iterator last = _commands.end();
|
||||
while (it != last) {
|
||||
names.push_back(it->first);
|
||||
it++;
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
bool
|
||||
SGCommandMgr::execute (const string &name, const SGPropertyNode * arg,
|
||||
SGCommandState ** state) const
|
||||
{
|
||||
command_t command = getCommand(name);
|
||||
if (command == 0)
|
||||
return false;
|
||||
else
|
||||
return (*command)(arg, state);
|
||||
}
|
||||
|
||||
|
||||
// bool
|
||||
// SGCommandMgr::execute (const string &name) const
|
||||
// {
|
||||
// // FIXME
|
||||
// SGPropertyNode node;
|
||||
// return execute(name, &node);
|
||||
// }
|
||||
|
||||
|
||||
// bool
|
||||
// SGCommandMgr::execute (const string &name, bool value) const
|
||||
// {
|
||||
// // FIXME
|
||||
// SGPropertyNode node;
|
||||
// node.setBoolValue(value);
|
||||
// return execute(name, &node);
|
||||
// }
|
||||
|
||||
|
||||
// bool
|
||||
// SGCommandMgr::execute (const string &name, int value) const
|
||||
// {
|
||||
// // FIXME
|
||||
// SGPropertyNode node;
|
||||
// node.setIntValue(value);
|
||||
// return execute(name, &node);
|
||||
// }
|
||||
|
||||
|
||||
// bool
|
||||
// SGCommandMgr::execute (const string &name, long value) const
|
||||
// {
|
||||
// // FIXME
|
||||
// SGPropertyNode node;
|
||||
// node.setLongValue(value);
|
||||
// return execute(name, &node);
|
||||
// }
|
||||
|
||||
|
||||
// bool
|
||||
// SGCommandMgr::execute (const string &name, float value) const
|
||||
// {
|
||||
// // FIXME
|
||||
// SGPropertyNode node;
|
||||
// node.setFloatValue(value);
|
||||
// return execute(name, &node);
|
||||
// }
|
||||
|
||||
|
||||
// bool
|
||||
// SGCommandMgr::execute (const string &name, double value) const
|
||||
// {
|
||||
// // FIXME
|
||||
// SGPropertyNode node;
|
||||
// node.setDoubleValue(value);
|
||||
// return execute(name, &node);
|
||||
// }
|
||||
|
||||
|
||||
// bool
|
||||
// SGCommandMgr::execute (const string &name, string value) const
|
||||
// {
|
||||
// // FIXME
|
||||
// SGPropertyNode node;
|
||||
// node.setStringValue(value);
|
||||
// return execute(name, &node);
|
||||
// }
|
||||
|
||||
|
||||
// end of commands.cxx
|
||||
260
simgear/misc/commands.hxx
Normal file
260
simgear/misc/commands.hxx
Normal file
@@ -0,0 +1,260 @@
|
||||
/**
|
||||
* \file commands.hxx
|
||||
* Interface definition for encapsulated commands.
|
||||
* Started Spring 2001 by David Megginson, david@megginson.com
|
||||
* This code is released into the Public Domain.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef __COMMANDS_HXX
|
||||
#define __COMMANDS_HXX
|
||||
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include STL_STRING
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "props.hxx"
|
||||
|
||||
SG_USING_STD(string);
|
||||
SG_USING_STD(map);
|
||||
SG_USING_STD(vector);
|
||||
|
||||
|
||||
/**
|
||||
* Stored state for a command.
|
||||
*
|
||||
* <p>This class allows a command to cache parts of its state between
|
||||
* invocations with the same parameters. Nearly every command that
|
||||
* actually uses this will subclass it in some way. The command
|
||||
* allocates the structure, but it is up to the caller to delete it
|
||||
* when it is no longer necessary, unless the command deletes it
|
||||
* and replaces the value with 0 or another command-state object
|
||||
* first.</p>
|
||||
*
|
||||
* <p>Note that this class is for caching only; all of the information
|
||||
* in it must be recoverable by other means, since the state could
|
||||
* arbitrarily disappear between invocations if the caller decides to
|
||||
* delete it.</p>
|
||||
*
|
||||
* <p>By default, the command state includes a place to keep a copy of
|
||||
* the parameters.</p>
|
||||
*
|
||||
* @author David Megginson, david@megginson.com
|
||||
*/
|
||||
class SGCommandState
|
||||
{
|
||||
public:
|
||||
SGCommandState ();
|
||||
SGCommandState (const SGPropertyNode * args);
|
||||
virtual ~SGCommandState ();
|
||||
virtual void setArgs (const SGPropertyNode * args);
|
||||
virtual const SGPropertyNode * getArgs () const { return _args; }
|
||||
private:
|
||||
SGPropertyNode * _args;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Manage commands.
|
||||
*
|
||||
* <p>This class allows the application to register and unregister
|
||||
* commands, and provides shortcuts for executing them. Commands are
|
||||
* simple functions that take a const pointer to an SGPropertyNode and
|
||||
* a pointer to a pointer variable (which should be 0 initially) where
|
||||
* the function can store compiled copies of its arguments, etc. to
|
||||
* avoid expensive recalculations. If the command deletes the
|
||||
* SGCommandState, it must replace it with a new pointer or 0;
|
||||
* otherwise, the caller is free to delete and zero the pointer at any
|
||||
* time and the command will start fresh with the next invocation.
|
||||
* The command must return a bool value indicating success or failure.
|
||||
* The property node may be ignored, or it may contain values that the
|
||||
* command uses as parameters.</p>
|
||||
*
|
||||
* <p>There are convenience methods for invoking a command function
|
||||
* with no arguments or with a single, primitive argument.</p>
|
||||
*
|
||||
* @author David Megginson, david@megginson.com
|
||||
*/
|
||||
class SGCommandMgr
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Type for a command function.
|
||||
*/
|
||||
typedef bool (*command_t) (const SGPropertyNode * arg,
|
||||
SGCommandState ** state);
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
SGCommandMgr ();
|
||||
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
virtual ~SGCommandMgr ();
|
||||
|
||||
|
||||
/**
|
||||
* Register a new command with the manager.
|
||||
*
|
||||
* @param name The command name. Any existing command with
|
||||
* the same name will silently be overwritten.
|
||||
* @param command A pointer to a one-arg function returning
|
||||
* a bool result. The argument is always a const pointer to
|
||||
* an SGPropertyNode (which may contain multiple values).
|
||||
*/
|
||||
virtual void addCommand (const string &name, command_t command);
|
||||
|
||||
|
||||
/**
|
||||
* Look up an existing command.
|
||||
*
|
||||
* @param name The command name.
|
||||
* @return A pointer to the command, or 0 if there is no registered
|
||||
* command with the name specified.
|
||||
*/
|
||||
virtual command_t getCommand (const string &name) const;
|
||||
|
||||
|
||||
/**
|
||||
* Get a list of all existing command names.
|
||||
*
|
||||
* @return A (possibly empty) vector of the names of all registered
|
||||
* commands.
|
||||
*/
|
||||
virtual vector<string> getCommandNames () const;
|
||||
|
||||
|
||||
/**
|
||||
* Execute a command.
|
||||
*
|
||||
* This is the primary method for invoking a command; the others
|
||||
* are convenience methods that invoke this one indirectly.
|
||||
*
|
||||
* @param name The name of the command.
|
||||
* @param arg A const pointer to an SGPropertyNode. The node
|
||||
* may have a value and/or children, etc., so that it is possible
|
||||
* to pass an arbitrarily complex data structure to a command.
|
||||
* @return true if the command is present and executes successfully,
|
||||
* false otherwise.
|
||||
*/
|
||||
virtual bool execute (const string &name,
|
||||
const SGPropertyNode * arg,
|
||||
SGCommandState ** state) const;
|
||||
|
||||
|
||||
// /**
|
||||
// * Execute a command with no argument.
|
||||
// *
|
||||
// * The command function will receive a pointer to a property node
|
||||
// * with no value and no children.
|
||||
// *
|
||||
// * @param name The name of the command.
|
||||
// * @return true if the command is present and executes successfully,
|
||||
// * false otherwise.
|
||||
// */
|
||||
// virtual bool execute (const string &name) const;
|
||||
|
||||
|
||||
// /**
|
||||
// * Execute a command with a single bool argument.
|
||||
// *
|
||||
// * The command function will receive a pointer to a property node
|
||||
// * with a bool value and no children.
|
||||
// *
|
||||
// * @param name The name of the command.
|
||||
// * @param arg The bool argument to the command.
|
||||
// * @return true if the command is present and executes successfully,
|
||||
// * false otherwise.
|
||||
// */
|
||||
// virtual bool execute (const string &name, bool arg) const;
|
||||
|
||||
|
||||
// /**
|
||||
// * Execute a command with a single int argument.
|
||||
// *
|
||||
// * The command function will receive a pointer to a property node
|
||||
// * with a int value and no children.
|
||||
// *
|
||||
// * @param name The name of the command.
|
||||
// * @param arg The int argument to the command.
|
||||
// * @return true if the command is present and executes successfully,
|
||||
// * false otherwise.
|
||||
// */
|
||||
// virtual bool execute (const string &name, int arg) const;
|
||||
|
||||
|
||||
// /**
|
||||
// * Execute a command with a single long argument.
|
||||
// *
|
||||
// * The command function will receive a pointer to a property node
|
||||
// * with a long value and no children.
|
||||
// *
|
||||
// * @param name The name of the command.
|
||||
// * @param arg The long argument to the command.
|
||||
// * @return true if the command is present and executes successfully,
|
||||
// * false otherwise.
|
||||
// */
|
||||
// virtual bool execute (const string &name, long arg) const;
|
||||
|
||||
|
||||
// /**
|
||||
// * Execute a command with a single float argument.
|
||||
// *
|
||||
// * The command function will receive a pointer to a property node
|
||||
// * with a float value and no children.
|
||||
// *
|
||||
// * @param name The name of the command.
|
||||
// * @param arg The float argument to the command.
|
||||
// * @return true if the command is present and executes successfully,
|
||||
// * false otherwise.
|
||||
// */
|
||||
// virtual bool execute (const string &name, float arg) const;
|
||||
|
||||
|
||||
// /**
|
||||
// * Execute a command with a single double argument.
|
||||
// *
|
||||
// * The command function will receive a pointer to a property node
|
||||
// * with a double value and no children.
|
||||
// *
|
||||
// * @param name The name of the command.
|
||||
// * @param arg The double argument to the command.
|
||||
// * @return true if the command is present and executes successfully,
|
||||
// * false otherwise.
|
||||
// */
|
||||
// virtual bool execute (const string &name, double arg) const;
|
||||
|
||||
|
||||
// /**
|
||||
// * Execute a command with a single string argument.
|
||||
// *
|
||||
// * The command function will receive a pointer to a property node
|
||||
// * with a string value and no children.
|
||||
// *
|
||||
// * @param name The name of the command.
|
||||
// * @param arg The string argument to the command.
|
||||
// * @return true if the command is present and executes successfully,
|
||||
// * false otherwise.
|
||||
// */
|
||||
// virtual bool execute (const string &name, string arg) const;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
typedef map<string,command_t> command_map;
|
||||
command_map _commands;
|
||||
|
||||
};
|
||||
|
||||
#endif // __COMMANDS_HXX
|
||||
|
||||
// end of commands.hxx
|
||||
@@ -1,86 +0,0 @@
|
||||
//
|
||||
// fgpath.hxx -- routines to abstract out path separator differences
|
||||
// between MacOS and the rest of the world
|
||||
//
|
||||
// Written by Curtis L. Olson, started April 1999.
|
||||
//
|
||||
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this library; if not, write to the
|
||||
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
// Boston, MA 02111-1307, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#ifndef _FGPATH_HXX
|
||||
#define _FGPATH_HXX
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include STL_STRING
|
||||
|
||||
FG_USING_STD(string);
|
||||
|
||||
|
||||
#ifdef macintosh
|
||||
# define FG_PATH_SEP ':'
|
||||
# define FG_BAD_PATH_SEP '/'
|
||||
#else
|
||||
# define FG_PATH_SEP '/'
|
||||
# define FG_BAD_PATH_SEP ':'
|
||||
#endif
|
||||
|
||||
|
||||
class FGPath {
|
||||
|
||||
private:
|
||||
|
||||
string path;
|
||||
|
||||
public:
|
||||
|
||||
// default constructor
|
||||
FGPath();
|
||||
|
||||
// create a path based on "path"
|
||||
FGPath( const string p );
|
||||
|
||||
// destructor
|
||||
~FGPath();
|
||||
|
||||
// set path
|
||||
void set( const string p );
|
||||
|
||||
// append another piece to the existing path
|
||||
void append( const string p );
|
||||
|
||||
// concatenate a string to the end of the path without inserting a
|
||||
// path separator
|
||||
void concat( const string p );
|
||||
|
||||
// get the path string
|
||||
inline string str() const { return path; }
|
||||
inline const char *c_str() { return path.c_str(); }
|
||||
};
|
||||
|
||||
|
||||
#endif // _FGPATH_HXX
|
||||
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
// zlib input file stream wrapper.
|
||||
//
|
||||
// Written by Bernie Bright, 1998
|
||||
//
|
||||
// Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this library; if not, write to the
|
||||
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
// Boston, MA 02111-1307, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
#ifndef _FGSTREAM_HXX
|
||||
#define _FGSTREAM_HXX
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#if defined( FG_HAVE_STD_INCLUDES )
|
||||
# include <istream>
|
||||
#elif defined ( FG_HAVE_NATIVE_SGI_COMPILERS )
|
||||
# include <CC/stream.h>
|
||||
#elif defined ( __BORLANDC__ )
|
||||
# include <iostream>
|
||||
#else
|
||||
# include <istream.h>
|
||||
#endif
|
||||
|
||||
#include STL_STRING
|
||||
|
||||
#include <simgear/misc/zfstream.hxx>
|
||||
|
||||
FG_USING_STD(string);
|
||||
|
||||
#ifndef FG_HAVE_NATIVE_SGI_COMPILERS
|
||||
FG_USING_STD(istream);
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Envelope class for gzifstream.
|
||||
//
|
||||
class fg_gzifstream : private gzifstream_base, public istream
|
||||
{
|
||||
public:
|
||||
//
|
||||
fg_gzifstream();
|
||||
|
||||
// Attempt to open a file with and without ".gz" extension.
|
||||
fg_gzifstream( const string& name,
|
||||
ios_openmode io_mode = ios_in | ios_binary );
|
||||
|
||||
//
|
||||
fg_gzifstream( int fd, ios_openmode io_mode = ios_in|ios_binary );
|
||||
|
||||
// Attempt to open a file with and without ".gz" extension.
|
||||
void open( const string& name,
|
||||
ios_openmode io_mode = ios_in|ios_binary );
|
||||
|
||||
void attach( int fd, ios_openmode io_mode = ios_in|ios_binary );
|
||||
|
||||
void close() { gzbuf.close(); }
|
||||
|
||||
bool is_open() { return gzbuf.is_open(); }
|
||||
|
||||
private:
|
||||
// Not defined!
|
||||
fg_gzifstream( const fg_gzifstream& );
|
||||
void operator= ( const fg_gzifstream& );
|
||||
};
|
||||
|
||||
// istream manipulator that skips to end of line.
|
||||
istream& skipeol( istream& in );
|
||||
|
||||
// istream manipulator that skips over white space.
|
||||
istream& skipws( istream& in );
|
||||
|
||||
// istream manipulator that skips comments and white space.
|
||||
// A comment starts with '#'.
|
||||
istream& skipcomment( istream& in );
|
||||
|
||||
|
||||
#endif /* _FGSTREAM_HXX */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,215 +1,266 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <string.h> // strcmp()
|
||||
#include <stdlib.h> // atof() atoi()
|
||||
|
||||
#include <simgear/sg_inlines.h>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/xml/easyxml.hxx>
|
||||
|
||||
#include "sg_path.hxx"
|
||||
#include "props.hxx"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include STL_IOSTREAM
|
||||
#if !defined(SG_HAVE_NATIVE_SGI_COMPILERS)
|
||||
# include <fstream>
|
||||
#else
|
||||
# include <fstream.h>
|
||||
#endif
|
||||
#include STL_STRING
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
FG_USING_STD(ofstream);
|
||||
FG_USING_STD(ifstream);
|
||||
FG_USING_STD(string);
|
||||
FG_USING_STD(vector);
|
||||
#if !defined(SG_HAVE_NATIVE_SGI_COMPILERS)
|
||||
SG_USING_STD(istream);
|
||||
SG_USING_STD(ifstream);
|
||||
SG_USING_STD(ostream);
|
||||
SG_USING_STD(ofstream);
|
||||
#endif
|
||||
SG_USING_STD(string);
|
||||
SG_USING_STD(vector);
|
||||
SG_USING_STD(map);
|
||||
|
||||
#define DEFAULT_MODE (SGPropertyNode::READ|SGPropertyNode::WRITE)
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Visitor class for building the property list.
|
||||
// Property list visitor, for XML parsing.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class PropVisitor : public XMLVisitor
|
||||
class PropsVisitor : public XMLVisitor
|
||||
{
|
||||
public:
|
||||
PropVisitor (SGPropertyList * props) : _props(props), _level(0), _ok(true) {}
|
||||
void startDocument ();
|
||||
|
||||
PropsVisitor (SGPropertyNode * root, const string &base)
|
||||
: _ok(true), _root(root), _level(0), _base(base) {}
|
||||
|
||||
void startXML ();
|
||||
void endXML ();
|
||||
void startElement (const char * name, const XMLAttributes &atts);
|
||||
void endElement (const char * name);
|
||||
void data (const char * s, int length);
|
||||
void warning (const char * message, int line, int col);
|
||||
void error (const char * message, int line, int col);
|
||||
void warning (const char * message, int line, int column);
|
||||
void error (const char * message, int line, int column);
|
||||
|
||||
bool isOK () const { return _ok; }
|
||||
|
||||
private:
|
||||
|
||||
void pushState (const char * name) {
|
||||
_states.push_back(_state);
|
||||
struct State
|
||||
{
|
||||
State () : node(0), type(""), mode(DEFAULT_MODE) {}
|
||||
State (SGPropertyNode * _node, const char * _type, int _mode)
|
||||
: node(_node), type(_type), mode(_mode) {}
|
||||
SGPropertyNode * node;
|
||||
string type;
|
||||
int mode;
|
||||
map<string,int> counters;
|
||||
};
|
||||
|
||||
State &state () { return _state_stack[_state_stack.size() - 1]; }
|
||||
|
||||
void push_state (SGPropertyNode * node, const char * type, int mode) {
|
||||
if (type == 0)
|
||||
_state_stack.push_back(State(node, "unspecified", mode));
|
||||
else
|
||||
_state_stack.push_back(State(node, type, mode));
|
||||
_level++;
|
||||
_state.name = name;
|
||||
_state.type = SGValue::UNKNOWN;
|
||||
_state.data = "";
|
||||
_state.hasChildren = false;
|
||||
_state.hasData = false;
|
||||
_data = "";
|
||||
}
|
||||
|
||||
void popState () {
|
||||
_state = _states.back();
|
||||
_states.pop_back();
|
||||
void pop_state () {
|
||||
_state_stack.pop_back();
|
||||
_level--;
|
||||
}
|
||||
|
||||
struct State
|
||||
{
|
||||
State () : hasChildren(false), hasData(false) {}
|
||||
string name;
|
||||
SGValue::Type type;
|
||||
string data;
|
||||
bool hasChildren;
|
||||
bool hasData;
|
||||
};
|
||||
|
||||
SGPropertyList * _props;
|
||||
State _state;
|
||||
vector<State> _states;
|
||||
int _level;
|
||||
bool _ok;
|
||||
string _data;
|
||||
SGPropertyNode * _root;
|
||||
int _level;
|
||||
vector<State> _state_stack;
|
||||
string _base;
|
||||
};
|
||||
|
||||
void
|
||||
PropVisitor::startDocument ()
|
||||
PropsVisitor::startXML ()
|
||||
{
|
||||
_level = 0;
|
||||
_ok = true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PropVisitor::startElement (const char * name, const XMLAttributes &atts)
|
||||
{
|
||||
if (!_ok)
|
||||
return;
|
||||
|
||||
if (_level == 0 && strcmp(name, "PropertyList")) {
|
||||
_ok = false;
|
||||
FG_LOG(FG_INPUT, FG_ALERT, "XML document has root element \""
|
||||
<< name << "\" instead of \"PropertyList\"");
|
||||
return;
|
||||
}
|
||||
|
||||
// Mixed content?
|
||||
_state.hasChildren = true;
|
||||
if (_state.hasData) {
|
||||
FG_LOG(FG_INPUT, FG_ALERT,
|
||||
"XML element has mixed elements and data in element "
|
||||
<< _state.name);
|
||||
_ok = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Start a new state.
|
||||
pushState(name);
|
||||
|
||||
// See if there's a type specified.
|
||||
const char * type = atts.getValue("type");
|
||||
if (type == 0 || !strcmp("unknown", type))
|
||||
_state.type = SGValue::UNKNOWN;
|
||||
else if (!strcmp("bool", type))
|
||||
_state.type = SGValue::BOOL;
|
||||
else if (!strcmp("int", type))
|
||||
_state.type = SGValue::INT;
|
||||
else if (!strcmp("float", type))
|
||||
_state.type = SGValue::FLOAT;
|
||||
else if (!strcmp("double", type))
|
||||
_state.type = SGValue::DOUBLE;
|
||||
else if (!strcmp("string", type))
|
||||
_state.type = SGValue::STRING;
|
||||
else
|
||||
FG_LOG(FG_INPUT, FG_ALERT, "Unrecognized type " << type
|
||||
<< ", using UNKNOWN");
|
||||
_state_stack.resize(0);
|
||||
}
|
||||
|
||||
void
|
||||
PropVisitor::endElement (const char * name)
|
||||
PropsVisitor::endXML ()
|
||||
{
|
||||
if (!_ok)
|
||||
return;
|
||||
_level = 0;
|
||||
_state_stack.resize(0);
|
||||
}
|
||||
|
||||
// See if there's a property to add.
|
||||
if (_state.hasData) {
|
||||
bool status = false;
|
||||
|
||||
// Figure out the path name.
|
||||
string path = "";
|
||||
for (int i = 2; i < _level; i++) {
|
||||
path += '/';
|
||||
path += _states[i].name;
|
||||
/**
|
||||
* Check a yes/no flag, with default.
|
||||
*/
|
||||
static bool
|
||||
checkFlag (const char * flag, bool defaultState = true)
|
||||
{
|
||||
if (flag == 0)
|
||||
return defaultState;
|
||||
else if (string(flag) == "y")
|
||||
return true;
|
||||
else if (string(flag) == "n")
|
||||
return false;
|
||||
else {
|
||||
SG_LOG(SG_INPUT, SG_ALERT, "Unrecognized flag value '" << flag
|
||||
<< "', assuming yes");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PropsVisitor::startElement (const char * name, const XMLAttributes &atts)
|
||||
{
|
||||
State &st = state();
|
||||
|
||||
if (_level == 0) {
|
||||
if (string(name) != (string)"PropertyList") {
|
||||
SG_LOG(SG_INPUT, SG_ALERT, "Root element name is " <<
|
||||
name << "; expected PropertyList");
|
||||
_ok = false;
|
||||
}
|
||||
path += '/';
|
||||
path += _state.name;
|
||||
push_state(_root, "", DEFAULT_MODE);
|
||||
}
|
||||
|
||||
// Set the value
|
||||
switch (_state.type) {
|
||||
case SGValue::BOOL:
|
||||
if (_state.data == "true" || _state.data == "TRUE") {
|
||||
status = _props->setBoolValue(path, true);
|
||||
} else if (atof(_state.data.c_str()) != 0.0) {
|
||||
status = _props->setBoolValue(path, true);
|
||||
} else {
|
||||
status =_props->setBoolValue(path, false);
|
||||
else {
|
||||
|
||||
const char * attval;
|
||||
// Get the index.
|
||||
attval = atts.getValue("n");
|
||||
int index = 0;
|
||||
if (attval != 0) {
|
||||
index = atoi(attval);
|
||||
st.counters[name] = SG_MAX2(st.counters[name], index+1);
|
||||
} else {
|
||||
index = st.counters[name];
|
||||
st.counters[name]++;
|
||||
}
|
||||
|
||||
// Got the index, so grab the node.
|
||||
SGPropertyNode * node = st.node->getChild(name, index, true);
|
||||
|
||||
// Get the access-mode attributes,
|
||||
// but don't set yet (in case they
|
||||
// prevent us from recording the value).
|
||||
int mode = 0;
|
||||
|
||||
attval = atts.getValue("read");
|
||||
if (checkFlag(attval, true))
|
||||
mode |= SGPropertyNode::READ;
|
||||
attval = atts.getValue("write");
|
||||
if (checkFlag(attval, true))
|
||||
mode |= SGPropertyNode::WRITE;
|
||||
attval = atts.getValue("archive");
|
||||
if (checkFlag(attval, false))
|
||||
mode |= SGPropertyNode::ARCHIVE;
|
||||
|
||||
// Check for an alias.
|
||||
attval = atts.getValue("alias");
|
||||
if (attval != 0) {
|
||||
if (!node->alias(attval))
|
||||
SG_LOG(SG_INPUT, SG_ALERT, "Failed to set alias to " << attval);
|
||||
}
|
||||
|
||||
// Check for an include.
|
||||
attval = atts.getValue("include");
|
||||
if (attval != 0) {
|
||||
SGPath path(SGPath(_base).dir());
|
||||
cerr << "Base is " << _base << endl;
|
||||
cerr << "Dir is " << SGPath(_base).dir() << endl;
|
||||
path.append(attval);
|
||||
if (!readProperties(path.str(), node)) {
|
||||
SG_LOG(SG_INPUT, SG_ALERT, "Failed to read include file "
|
||||
<< attval);
|
||||
_ok = false;
|
||||
}
|
||||
break;
|
||||
case SGValue::INT :
|
||||
status = _props->setIntValue(path, atoi(_state.data.c_str()));
|
||||
break;
|
||||
case SGValue::FLOAT:
|
||||
status = _props->setFloatValue(path, atof(_state.data.c_str()));
|
||||
break;
|
||||
case SGValue::DOUBLE:
|
||||
status = _props->setDoubleValue(path, atof(_state.data.c_str()));
|
||||
break;
|
||||
case SGValue::STRING:
|
||||
status = _props->setStringValue(path, _state.data);
|
||||
break;
|
||||
default:
|
||||
status = _props->setUnknownValue(path, _state.data);
|
||||
break;
|
||||
}
|
||||
if (!status)
|
||||
FG_LOG(FG_INPUT, FG_ALERT, "Failed to set property "
|
||||
<< path << " to " << _state.data);
|
||||
|
||||
push_state(node, atts.getValue("type"), mode);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PropsVisitor::endElement (const char * name)
|
||||
{
|
||||
State &st = state();
|
||||
bool ret;
|
||||
|
||||
// If there are no children and it's
|
||||
// not an alias, then it's a leaf value.
|
||||
if (st.node->nChildren() == 0 && !st.node->isAlias()) {
|
||||
if (st.type == "bool") {
|
||||
if (_data == "true" || atoi(_data.c_str()) != 0)
|
||||
ret = st.node->setBoolValue(true);
|
||||
else
|
||||
ret = st.node->setBoolValue(false);
|
||||
} else if (st.type == "int") {
|
||||
ret = st.node->setIntValue(atoi(_data.c_str()));
|
||||
} else if (st.type == "long") {
|
||||
ret = st.node->setLongValue(strtol(_data.c_str(), 0, 0));
|
||||
} else if (st.type == "float") {
|
||||
ret = st.node->setFloatValue(atof(_data.c_str()));
|
||||
} else if (st.type == "double") {
|
||||
ret = st.node->setDoubleValue(strtod(_data.c_str(), 0));
|
||||
} else if (st.type == "string") {
|
||||
ret = st.node->setStringValue(_data);
|
||||
} else if (st.type == "unspecified") {
|
||||
ret = st.node->setUnspecifiedValue(_data);
|
||||
} else {
|
||||
SG_LOG(SG_INPUT, SG_ALERT, "Unrecognized data type " << st.type
|
||||
<< " assuming 'unspecified'");
|
||||
ret = st.node->setUnspecifiedValue(_data);
|
||||
}
|
||||
if (!ret)
|
||||
SG_LOG(SG_INPUT, SG_ALERT, "readProperties: Failed to set "
|
||||
<< st.node->getPath() << " to value \""
|
||||
<< _data << "\" with type " << st.type);
|
||||
}
|
||||
|
||||
// Pop the stack.
|
||||
popState();
|
||||
// Set the access-mode attributes now,
|
||||
// once the value has already been
|
||||
// assigned.
|
||||
st.node->setAttributes(st.mode);
|
||||
|
||||
pop_state();
|
||||
}
|
||||
|
||||
void
|
||||
PropVisitor::data (const char * s, int length)
|
||||
PropsVisitor::data (const char * s, int length)
|
||||
{
|
||||
if (!_ok)
|
||||
return;
|
||||
|
||||
// Check if there is any non-whitespace
|
||||
if (!_state.hasData)
|
||||
for (int i = 0; i < length; i++)
|
||||
if (s[i] != ' ' && s[i] != '\t' && s[i] != '\n' && s[i] != '\r')
|
||||
_state.hasData = true;
|
||||
|
||||
_state.data += string(s, length); // FIXME: inefficient
|
||||
if (state().node->nChildren() == 0)
|
||||
_data.append(string(s, length));
|
||||
}
|
||||
|
||||
void
|
||||
PropVisitor::warning (const char * message, int line, int col)
|
||||
PropsVisitor::warning (const char * message, int line, int column)
|
||||
{
|
||||
FG_LOG(FG_INPUT, FG_ALERT, "Warning importing property list: "
|
||||
<< message << " (" << line << ',' << col << ')');
|
||||
SG_LOG(SG_INPUT, SG_ALERT, "readProperties: warning: "
|
||||
<< message << " at line " << line << ", column " << column);
|
||||
}
|
||||
|
||||
void
|
||||
PropVisitor::error (const char * message, int line, int col)
|
||||
PropsVisitor::error (const char * message, int line, int column)
|
||||
{
|
||||
FG_LOG(FG_INPUT, FG_ALERT, "Error importing property list: "
|
||||
<< message << " (" << line << ',' << col << ')');
|
||||
SG_LOG(SG_INPUT, SG_ALERT, "readProperties: FATAL: " <<
|
||||
message << " at line " << line << ", column " << column);
|
||||
_ok = false;
|
||||
}
|
||||
|
||||
@@ -219,21 +270,40 @@ PropVisitor::error (const char * message, int line, int col)
|
||||
// Property list reader.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
* Read properties from an input stream.
|
||||
*
|
||||
* @param input The input stream containing an XML property file.
|
||||
* @param start_node The root node for reading properties.
|
||||
* @param base A base path for resolving external include references.
|
||||
* @return true if the read succeeded, false otherwise.
|
||||
*/
|
||||
bool
|
||||
readPropertyList (istream &input, SGPropertyList * props)
|
||||
readProperties (istream &input, SGPropertyNode * start_node,
|
||||
const string &base)
|
||||
{
|
||||
PropVisitor visitor(props);
|
||||
PropsVisitor visitor(start_node, base);
|
||||
return readXML(input, visitor) && visitor.isOK();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read properties from a file.
|
||||
*
|
||||
* @param file A string containing the file path.
|
||||
* @param start_node The root node for reading properties.
|
||||
* @return true if the read succeeded, false otherwise.
|
||||
*/
|
||||
bool
|
||||
readPropertyList (const string &file, SGPropertyList * props)
|
||||
readProperties (const string &file, SGPropertyNode * start_node)
|
||||
{
|
||||
cerr << "Reading properties from " << file << endl;
|
||||
ifstream input(file.c_str());
|
||||
if (input.good()) {
|
||||
return readPropertyList(input, props);
|
||||
return readProperties(input, start_node, file);
|
||||
} else {
|
||||
FG_LOG(FG_INPUT, FG_ALERT, "Error reading property list from file "
|
||||
SG_LOG(SG_INPUT, SG_ALERT, "Error reading property list from file "
|
||||
<< file);
|
||||
return false;
|
||||
}
|
||||
@@ -251,24 +321,27 @@ readPropertyList (const string &file, SGPropertyList * props)
|
||||
* Return the type name.
|
||||
*/
|
||||
static const char *
|
||||
getTypeName (SGValue::Type type)
|
||||
getTypeName (SGPropertyNode::Type type)
|
||||
{
|
||||
switch (type) {
|
||||
case SGValue::UNKNOWN:
|
||||
return "unknown";
|
||||
case SGValue::BOOL:
|
||||
case SGPropertyNode::UNSPECIFIED:
|
||||
return "unspecified";
|
||||
case SGPropertyNode::BOOL:
|
||||
return "bool";
|
||||
case SGValue::INT:
|
||||
case SGPropertyNode::INT:
|
||||
return "int";
|
||||
case SGValue::FLOAT:
|
||||
case SGPropertyNode::LONG:
|
||||
return "long";
|
||||
case SGPropertyNode::FLOAT:
|
||||
return "float";
|
||||
case SGValue::DOUBLE:
|
||||
case SGPropertyNode::DOUBLE:
|
||||
return "double";
|
||||
case SGValue::STRING:
|
||||
case SGPropertyNode::STRING:
|
||||
return "string";
|
||||
}
|
||||
|
||||
return "unknown"; // avoid a compiler warning
|
||||
// keep the compiler from squawking
|
||||
return "unspecified";
|
||||
}
|
||||
|
||||
|
||||
@@ -305,32 +378,87 @@ doIndent (ostream &output, int indent)
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
writeNode (ostream &output, SGPropertyNode node, int indent)
|
||||
static void
|
||||
writeAtts (ostream &output, const SGPropertyNode * node)
|
||||
{
|
||||
const string &name = node.getName();
|
||||
int size = node.size();
|
||||
int index = node->getIndex();
|
||||
|
||||
// Write out the literal value, if any.
|
||||
SGValue * value = node.getValue();
|
||||
if (value != 0) {
|
||||
SGValue::Type type = value->getType();
|
||||
if (index != 0)
|
||||
output << " n=\"" << index << '"';
|
||||
|
||||
#if 0
|
||||
if (!node->getAttribute(SGPropertyNode::READ))
|
||||
output << " read=\"n\"";
|
||||
|
||||
if (!node->getAttribute(SGPropertyNode::WRITE))
|
||||
output << " write=\"n\"";
|
||||
|
||||
if (node->getAttribute(SGPropertyNode::ARCHIVE))
|
||||
output << " archive=\"y\"";
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test whether a node is archivable or has archivable descendants.
|
||||
*/
|
||||
static bool
|
||||
isArchivable (const SGPropertyNode * node)
|
||||
{
|
||||
// FIXME: it's inefficient to do this all the time
|
||||
if (node->getAttribute(SGPropertyNode::ARCHIVE))
|
||||
return true;
|
||||
else {
|
||||
int nChildren = node->nChildren();
|
||||
for (int i = 0; i < nChildren; i++)
|
||||
if (isArchivable(node->getChild(i)))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
writeNode (ostream &output, const SGPropertyNode * node, int indent)
|
||||
{
|
||||
// Don't write the node or any of
|
||||
// its descendants unless it is
|
||||
// allowed to be archived.
|
||||
if (!isArchivable(node))
|
||||
return true; // Everything's OK, but we won't write.
|
||||
|
||||
const string &name = node->getName();
|
||||
int index = node->getIndex();
|
||||
int nChildren = node->nChildren();
|
||||
|
||||
// If there is a literal value,
|
||||
// write it first.
|
||||
if (node->hasValue() && node->getAttribute(SGPropertyNode::ARCHIVE)) {
|
||||
doIndent(output, indent);
|
||||
output << '<' << name;
|
||||
if (type != SGValue::UNKNOWN)
|
||||
output << " type=\"" << getTypeName(type) << '"';
|
||||
output << '>';
|
||||
writeData(output, value->getStringValue());
|
||||
output << "</" << name << '>' << endl;
|
||||
writeAtts(output, node);
|
||||
if (node->isAlias() && node->getAliasTarget() != 0) {
|
||||
output << " alias=\"" << node->getAliasTarget()->getPath()
|
||||
<< "\"/>" << endl;
|
||||
} else {
|
||||
if (node->getType() != SGPropertyNode::UNSPECIFIED)
|
||||
output << " type=\"" << getTypeName(node->getType()) << '"';
|
||||
output << '>';
|
||||
writeData(output, node->getStringValue());
|
||||
output << "</" << name << '>' << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Write out the children, if any.
|
||||
if (size > 0) {
|
||||
// If there are children, write them
|
||||
// next.
|
||||
if (nChildren > 0 || node->isAlias()) {
|
||||
doIndent(output, indent);
|
||||
output << '<' << name << '>' << endl;;
|
||||
for (int i = 0; i < size; i++) {
|
||||
writeNode(output, node.getChild(i), indent + INDENT_STEP);
|
||||
}
|
||||
output << '<' << name;
|
||||
writeAtts(output, node);
|
||||
output << '>' << endl;
|
||||
for (int i = 0; i < nChildren; i++)
|
||||
writeNode(output, node->getChild(i), indent + INDENT_STEP);
|
||||
doIndent(output, indent);
|
||||
output << "</" << name << '>' << endl;
|
||||
}
|
||||
@@ -338,16 +466,24 @@ writeNode (ostream &output, SGPropertyNode node, int indent)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write a property tree to an output stream in XML format.
|
||||
*
|
||||
* @param output The output stream.
|
||||
* @param start_node The root node to write.
|
||||
* @return true if the write succeeded, false otherwise.
|
||||
*/
|
||||
bool
|
||||
writePropertyList (ostream &output, const SGPropertyList * props)
|
||||
writeProperties (ostream &output, const SGPropertyNode * start_node)
|
||||
{
|
||||
SGPropertyNode root ("/", (SGPropertyList *)props); // FIXME
|
||||
int nChildren = start_node->nChildren();
|
||||
|
||||
output << "<?xml version=\"1.0\"?>" << endl << endl;
|
||||
output << "<PropertyList>" << endl;
|
||||
|
||||
for (int i = 0; i < root.size(); i++) {
|
||||
writeNode(output, root.getChild(i), INDENT_STEP);
|
||||
for (int i = 0; i < nChildren; i++) {
|
||||
writeNode(output, start_node->getChild(i), INDENT_STEP);
|
||||
}
|
||||
|
||||
output << "</PropertyList>" << endl;
|
||||
@@ -355,15 +491,96 @@ writePropertyList (ostream &output, const SGPropertyList * props)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write a property tree to a file in XML format.
|
||||
*
|
||||
* @param file The destination file.
|
||||
* @param start_node The root node to write.
|
||||
* @return true if the write succeeded, false otherwise.
|
||||
*/
|
||||
bool
|
||||
writePropertyList (const string &file, const SGPropertyList * props)
|
||||
writeProperties (const string &file, const SGPropertyNode * start_node)
|
||||
{
|
||||
ofstream output(file.c_str());
|
||||
if (output.good()) {
|
||||
return writePropertyList(output, props);
|
||||
return writeProperties(output, start_node);
|
||||
} else {
|
||||
FG_LOG(FG_INPUT, FG_ALERT, "Cannot write property list to file "
|
||||
SG_LOG(SG_INPUT, SG_ALERT, "Cannot write properties to file "
|
||||
<< file);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Copy properties from one tree to another.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
* Copy one property tree to another.
|
||||
*
|
||||
* @param in The source property tree.
|
||||
* @param out The destination property tree.
|
||||
* @return true if all properties were copied, false if some failed
|
||||
* (for example, if the property's value is tied read-only).
|
||||
*/
|
||||
bool
|
||||
copyProperties (const SGPropertyNode *in, SGPropertyNode *out)
|
||||
{
|
||||
bool retval = true;
|
||||
|
||||
// First, copy the actual value,
|
||||
// if any.
|
||||
if (in->hasValue()) {
|
||||
switch (in->getType()) {
|
||||
case SGPropertyNode::BOOL:
|
||||
if (!out->setBoolValue(in->getBoolValue()))
|
||||
retval = false;
|
||||
break;
|
||||
case SGPropertyNode::INT:
|
||||
if (!out->setIntValue(in->getIntValue()))
|
||||
retval = false;
|
||||
break;
|
||||
case SGPropertyNode::LONG:
|
||||
if (!out->setLongValue(in->getLongValue()))
|
||||
retval = false;
|
||||
break;
|
||||
case SGPropertyNode::FLOAT:
|
||||
if (!out->setFloatValue(in->getFloatValue()))
|
||||
retval = false;
|
||||
break;
|
||||
case SGPropertyNode::DOUBLE:
|
||||
if (!out->setDoubleValue(in->getDoubleValue()))
|
||||
retval = false;
|
||||
break;
|
||||
case SGPropertyNode::STRING:
|
||||
if (!out->setStringValue(in->getStringValue()))
|
||||
retval = false;
|
||||
break;
|
||||
case SGPropertyNode::UNSPECIFIED:
|
||||
if (!out->setUnspecifiedValue(in->getStringValue()))
|
||||
retval = false;
|
||||
break;
|
||||
default:
|
||||
throw string("Unrecognized SGPropertyNode type");
|
||||
}
|
||||
}
|
||||
|
||||
// Next, copy the children.
|
||||
int nChildren = in->nChildren();
|
||||
for (int i = 0; i < nChildren; i++) {
|
||||
const SGPropertyNode * in_child = in->getChild(i);
|
||||
SGPropertyNode * out_child = out->getChild(in_child->getName(),
|
||||
in_child->getIndex(),
|
||||
true);
|
||||
if (!copyProperties(in_child, out_child))
|
||||
retval = false;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
// end of props_io.cxx
|
||||
|
||||
345
simgear/misc/props_test.cxx
Normal file
345
simgear/misc/props_test.cxx
Normal file
@@ -0,0 +1,345 @@
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Test harness.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include STL_IOSTREAM
|
||||
#include "props.hxx"
|
||||
|
||||
#if !defined(SG_HAVE_NATIVE_SGI_COMPILERS)
|
||||
SG_USING_STD(cout);
|
||||
SG_USING_STD(cerr);
|
||||
SG_USING_STD(endl);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Sample object.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Stuff {
|
||||
public:
|
||||
Stuff () : _stuff(199.0) {}
|
||||
virtual float getStuff () const { return _stuff; }
|
||||
virtual void setStuff (float stuff) { _stuff = stuff; }
|
||||
virtual float getStuff (int index) const { return _stuff * index; }
|
||||
virtual void setStuff (int index, float val) {
|
||||
_stuff = val / index;
|
||||
}
|
||||
private:
|
||||
float _stuff;
|
||||
};
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Sample function.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int get100 () { return 100; }
|
||||
|
||||
static double getNum (int index) { return 1.0 / index; }
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Show a value.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void
|
||||
show_values (const SGPropertyNode * node)
|
||||
{
|
||||
cout << "Bool: " << node->getBoolValue() << endl;
|
||||
cout << "Int: " << node->getIntValue() << endl;
|
||||
cout << "Float: " << node->getFloatValue() << endl;
|
||||
cout << "Double: " << node->getDoubleValue() << endl;
|
||||
cout << "String: " << node->getStringValue() << endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Test individual values.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void
|
||||
test_value ()
|
||||
{
|
||||
SGPropertyNode * node;
|
||||
|
||||
cout << endl << "Value" << endl << endl;
|
||||
|
||||
//
|
||||
// Test coercion for getters.
|
||||
//
|
||||
|
||||
cout << "Testing coercion from bool (expect true)" << endl;
|
||||
node = new SGPropertyNode;
|
||||
node->setBoolValue(true);
|
||||
show_values(node);
|
||||
delete node;
|
||||
cout << endl;
|
||||
|
||||
cout << "Testing coercion from int (expect 128)" << endl;
|
||||
node = new SGPropertyNode;
|
||||
node->setIntValue(128);
|
||||
show_values(node);
|
||||
delete node;
|
||||
cout << endl;
|
||||
|
||||
cout << "Testing coercion from float (expect 1.0/3.0)" << endl;
|
||||
node = new SGPropertyNode;
|
||||
node->setFloatValue(1.0/3.0);
|
||||
show_values(node);
|
||||
delete node;
|
||||
cout << endl;
|
||||
|
||||
cout << "Testing coercion from double (expect 1.0/3.0)" << endl;
|
||||
node = new SGPropertyNode;
|
||||
node->setDoubleValue(1.0/3.0);
|
||||
show_values(node);
|
||||
delete node;
|
||||
cout << endl;
|
||||
|
||||
cout << "Testing coercion from string (expect 10e4)" << endl;
|
||||
node = new SGPropertyNode;
|
||||
node->setStringValue("10e4");
|
||||
show_values(node);
|
||||
delete node;
|
||||
cout << endl;
|
||||
|
||||
cout << "Testing coercion from unspecified (expect -10e-4)" << endl;
|
||||
node = new SGPropertyNode;
|
||||
node->setUnspecifiedValue("-10e-4");
|
||||
show_values(node);
|
||||
delete node;
|
||||
cout << endl;
|
||||
|
||||
//
|
||||
// Test coercion for setters.
|
||||
//
|
||||
|
||||
node = new SGPropertyNode;
|
||||
|
||||
cout << "Testing coercion to bool from bool (expect false)" << endl;
|
||||
node->setBoolValue(false);
|
||||
show_values(node);
|
||||
cout << endl;
|
||||
|
||||
cout << "Testing coercion to bool from int (expect 1)" << endl;
|
||||
node->setIntValue(1);
|
||||
show_values(node);
|
||||
cout << endl;
|
||||
|
||||
cout << "Testing coercion to bool from float (expect 1.1)" << endl;
|
||||
node->setFloatValue(1.1);
|
||||
show_values(node);
|
||||
cout << endl;
|
||||
|
||||
cout << "Testing coercion to bool from double (expect 1.1)" << endl;
|
||||
node->setDoubleValue(1.1);
|
||||
show_values(node);
|
||||
cout << endl;
|
||||
|
||||
cout << "Testing coercion to bool from string (expect 1e10)" << endl;
|
||||
node->setStringValue("1e10");
|
||||
show_values(node);
|
||||
cout << endl;
|
||||
|
||||
cout << "Testing coercion to bool from unspecified (expect 1e10)" << endl;
|
||||
node->setUnspecifiedValue("1e10");
|
||||
show_values(node);
|
||||
cout << endl;
|
||||
|
||||
// Test tying to a pointer.
|
||||
|
||||
static int myValue = 10;
|
||||
|
||||
cout << "Testing tying to a pointer (expect 10)" << endl;
|
||||
if (!node->tie(SGRawValuePointer<int>(&myValue), false))
|
||||
cout << "*** FAILED TO TIE VALUE!!!" << endl;
|
||||
show_values(node);
|
||||
cout << endl;
|
||||
|
||||
cout << "Changing base variable (expect -5)" << endl;
|
||||
myValue = -5;
|
||||
show_values(node);
|
||||
if (!node->untie())
|
||||
cout << "*** FAILED TO UNTIE VALUE!!!" << endl;
|
||||
cout << endl;
|
||||
|
||||
|
||||
// Test tying to static functions.
|
||||
|
||||
cout << "Create a new int value (expect 10)" << endl;
|
||||
node->setIntValue(10);
|
||||
show_values(node);
|
||||
cout << endl;
|
||||
|
||||
cout << "Testing tying to static getter (expect 100)" << endl;
|
||||
if (!node->tie(SGRawValueFunctions<int>(get100)))
|
||||
cout << "*** FAILED TO TIE VALUE!!!" << endl;
|
||||
show_values(node);
|
||||
cout << endl;
|
||||
|
||||
cout << "Try changing value with no setter (expect 100)" << endl;
|
||||
if (node->setIntValue(200))
|
||||
cout << "*** setIntValue did not return false!!!" << endl;
|
||||
show_values(node);
|
||||
cout << endl;
|
||||
|
||||
cout << "Untie value (expect 100)" << endl;
|
||||
if (!node->untie())
|
||||
cout << "*** FAILED TO UNTIE VALUE!!!" << endl;
|
||||
show_values(node);
|
||||
cout << endl;
|
||||
|
||||
cout << "Try changing value (expect 200)" << endl;
|
||||
if (!node->setIntValue(200))
|
||||
cout << "*** setIntValue RETURNED FALSE!!!" << endl;
|
||||
show_values(node);
|
||||
cout << endl;
|
||||
|
||||
// Test tying to indexed static functions.
|
||||
|
||||
cout << "Create a new int value (expect 10)" << endl;
|
||||
node->setIntValue(10);
|
||||
show_values(node);
|
||||
cout << endl;
|
||||
|
||||
cout << "Testing tying to indexed static getter (0.3333...)" << endl;
|
||||
if (!node->tie(SGRawValueFunctionsIndexed<double>(3, getNum)))
|
||||
cout << "*** FAILED TO TIE VALUE!!!" << endl;
|
||||
show_values(node);
|
||||
cout << endl;
|
||||
|
||||
cout << "Untie value (expect 0.3333...)" << endl;
|
||||
if (!node->untie())
|
||||
cout << "*** FAILED TO UNTIE VALUE!!!" << endl;
|
||||
show_values(node);
|
||||
cout << endl;
|
||||
|
||||
|
||||
// Test methods.
|
||||
|
||||
cout << "Try tying to an object without defaults (expect 199)" << endl;
|
||||
Stuff stuff;
|
||||
SGRawValueMethods<class Stuff,float> tiedstuff(stuff,
|
||||
&Stuff::getStuff,
|
||||
&Stuff::setStuff);
|
||||
if (!node->tie(tiedstuff, false))
|
||||
cout << "*** FAILED TO TIE VALUE!!!" << endl;
|
||||
show_values(node);
|
||||
cout << endl;
|
||||
|
||||
cout << "Try untying from object (expect 199)" << endl;
|
||||
if (!node->untie())
|
||||
cout << "*** FAILED TO UNTIE VALUE!!!" << endl;
|
||||
show_values(node);
|
||||
cout << endl;
|
||||
|
||||
cout << "Try tying to an indexed method (expect 199)" << endl;
|
||||
if (!node->tie(SGRawValueMethodsIndexed<class Stuff, float>
|
||||
(stuff, 2, &Stuff::getStuff, &Stuff::setStuff)))
|
||||
cout << "*** FAILED TO TIE VALUE!!!" << endl;
|
||||
show_values(node);
|
||||
cout << endl;
|
||||
|
||||
node->untie();
|
||||
|
||||
cout << "Change value (expect 50)" << endl;
|
||||
if (!node->setIntValue(50))
|
||||
cout << "*** FAILED TO SET VALUE!!!" << endl;
|
||||
show_values(node);
|
||||
cout << endl;
|
||||
|
||||
cout << "Try tying to an object with defaults (expect 50)" << endl;
|
||||
if (!node->tie(tiedstuff, true))
|
||||
cout << "*** FAILED TO TIE VALUE!!!" << endl;
|
||||
show_values(node);
|
||||
cout << endl;
|
||||
|
||||
delete node;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Check property nodes.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void
|
||||
dump_node (const SGPropertyNode * node)
|
||||
{
|
||||
writeProperties(cout, node);
|
||||
}
|
||||
|
||||
static void
|
||||
test_property_nodes ()
|
||||
{
|
||||
SGPropertyNode root;
|
||||
cout << "Created root node " << root.getPath() << endl;
|
||||
|
||||
SGPropertyNode * child = root.getChild("foo", 0, true);
|
||||
|
||||
SGPropertyNode *grandchild = child->getChild("bar", 0, true);
|
||||
grandchild->setDoubleValue(100);
|
||||
grandchild = child->getChild("bar", 1, true);
|
||||
grandchild->setDoubleValue(200);
|
||||
grandchild = child->getChild("bar", 2, true);
|
||||
grandchild->setDoubleValue(300);
|
||||
grandchild = child->getChild("bar", 3, true);
|
||||
grandchild->setDoubleValue(400);
|
||||
|
||||
child = root.getChild("hack", 0, true);
|
||||
|
||||
grandchild = child->getChild("bar", 0, true);
|
||||
grandchild->setDoubleValue(100);
|
||||
grandchild = child->getChild("bar", 3, true);
|
||||
grandchild->setDoubleValue(200);
|
||||
grandchild = child->getChild("bar", 1, true);
|
||||
grandchild->setDoubleValue(300);
|
||||
grandchild = child->getChild("bar", 2, true);
|
||||
grandchild->setDoubleValue(400);
|
||||
dump_node(&root);
|
||||
|
||||
cout << "Trying path (expect /foo[0]/bar[0])" << endl;
|
||||
grandchild = root.getNode("/hack/../foo/./bar[0]");
|
||||
cout << "Path is " << grandchild->getPath() << endl;
|
||||
cout << endl;
|
||||
|
||||
cout << "Looking for all /hack[0]/bar children" << endl;
|
||||
vector<SGPropertyNode *> bar = child->getChildren("bar");
|
||||
cout << "There are " << bar.size() << " matches" << endl;
|
||||
for (int i = 0; i < (int)bar.size(); i++)
|
||||
cout << bar[i]->getName() << '[' << bar[i]->getIndex() << ']' << endl;
|
||||
cout << endl;
|
||||
|
||||
cout << "Testing addition of a totally empty node" << endl;
|
||||
if (root.getNode("/a/b/c", true) == 0)
|
||||
cerr << "** failed to create /a/b/c" << endl;
|
||||
dump_node(&root);
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
|
||||
int main (int ac, char ** av)
|
||||
{
|
||||
test_value();
|
||||
test_property_nodes();
|
||||
|
||||
for (int i = 1; i < ac; i++) {
|
||||
cout << "Reading " << av[i] << endl;
|
||||
SGPropertyNode root;
|
||||
if (!readProperties(av[i], &root))
|
||||
cerr << "Failed to read properties from " << av[i] << endl;
|
||||
else
|
||||
writeProperties(cout, &root);
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
//
|
||||
// fgpath.cxx -- routines to abstract out path separator differences
|
||||
// sg_path.cxx -- routines to abstract out path separator differences
|
||||
// between MacOS and the rest of the world
|
||||
//
|
||||
// Written by Curtis L. Olson, started April 1999.
|
||||
@@ -24,7 +23,9 @@
|
||||
// $Id$
|
||||
|
||||
|
||||
#include "fgpath.hxx"
|
||||
#include <simgear_config.h>
|
||||
|
||||
#include "sg_path.hxx"
|
||||
|
||||
|
||||
// If Unix, replace all ":" with "/". If MacOS, replace all "/" with
|
||||
@@ -42,8 +43,8 @@ static string fix_path( const string path ) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if ( result[i] == FG_BAD_PATH_SEP ) {
|
||||
result[i] = FG_PATH_SEP;
|
||||
if ( result[i] == SG_BAD_PATH_SEP ) {
|
||||
result[i] = SG_PATH_SEP;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,37 +53,37 @@ static string fix_path( const string path ) {
|
||||
|
||||
|
||||
// default constructor
|
||||
FGPath::FGPath() {
|
||||
SGPath::SGPath() {
|
||||
path = "";
|
||||
}
|
||||
|
||||
|
||||
// create a path based on "path"
|
||||
FGPath::FGPath( const string p ) {
|
||||
SGPath::SGPath( const string p ) {
|
||||
set( p );
|
||||
}
|
||||
|
||||
|
||||
// destructor
|
||||
FGPath::~FGPath() {
|
||||
SGPath::~SGPath() {
|
||||
}
|
||||
|
||||
|
||||
// set path
|
||||
void FGPath::set( const string p ) {
|
||||
void SGPath::set( const string p ) {
|
||||
path = fix_path( p );
|
||||
}
|
||||
|
||||
|
||||
// append another piece to the existing path
|
||||
void FGPath::append( const string p ) {
|
||||
void SGPath::append( const string p ) {
|
||||
string part = fix_path( p );
|
||||
|
||||
if ( path.size() == 0 ) {
|
||||
path = part;
|
||||
} else {
|
||||
if ( part[0] != FG_PATH_SEP ) {
|
||||
path += FG_PATH_SEP;
|
||||
if ( part[0] != SG_PATH_SEP ) {
|
||||
path += SG_PATH_SEP;
|
||||
}
|
||||
path += part;
|
||||
}
|
||||
@@ -91,7 +92,7 @@ void FGPath::append( const string p ) {
|
||||
|
||||
// concatenate a string to the end of the path without inserting a
|
||||
// path separator
|
||||
void FGPath::concat( const string p ) {
|
||||
void SGPath::concat( const string p ) {
|
||||
string part = fix_path( p );
|
||||
|
||||
if ( path.size() == 0 ) {
|
||||
@@ -100,3 +101,14 @@ void FGPath::concat( const string p ) {
|
||||
path += part;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// get the directory part of the path.
|
||||
string SGPath::dir() {
|
||||
int index = path.rfind(SG_PATH_SEP);
|
||||
if (index >= 0) {
|
||||
return path.substr(0, index);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
116
simgear/misc/sg_path.hxx
Normal file
116
simgear/misc/sg_path.hxx
Normal file
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
* \file sg_path.hxx
|
||||
* Routines to abstract out path separator differences between MacOS
|
||||
* and the rest of the world.
|
||||
*/
|
||||
|
||||
// Written by Curtis L. Olson, started April 1999.
|
||||
//
|
||||
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this library; if not, write to the
|
||||
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
// Boston, MA 02111-1307, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#ifndef _SG_PATH_HXX
|
||||
#define _SG_PATH_HXX
|
||||
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include STL_STRING
|
||||
|
||||
SG_USING_STD(string);
|
||||
|
||||
|
||||
#ifdef macintosh
|
||||
# define SG_PATH_SEP ':'
|
||||
# define SG_BAD_PATH_SEP '/'
|
||||
#else
|
||||
# define SG_PATH_SEP '/'
|
||||
# define SG_BAD_PATH_SEP ':'
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* A class to hide path separator difference across platforms and assist
|
||||
* in managing file system path names.
|
||||
*
|
||||
* Paths can be input in any platform format and will be converted
|
||||
* automatically to the proper format.
|
||||
*/
|
||||
|
||||
class SGPath {
|
||||
|
||||
private:
|
||||
|
||||
string path;
|
||||
|
||||
public:
|
||||
|
||||
/** Default constructor */
|
||||
SGPath();
|
||||
|
||||
/**
|
||||
* Construct a path based on the starting path provided.
|
||||
* @param p initial path
|
||||
*/
|
||||
SGPath( const string p );
|
||||
|
||||
/** Destructor */
|
||||
~SGPath();
|
||||
|
||||
/**
|
||||
* Set path to a new value
|
||||
* @param p new path
|
||||
*/
|
||||
void set( const string p );
|
||||
|
||||
/**
|
||||
* Append another piece to the existing path. Inserts a path
|
||||
* separator between the existing component and the new component.
|
||||
* @param p additional path component */
|
||||
void append( const string p );
|
||||
|
||||
/**
|
||||
* Concatenate a string to the end of the path without inserting a
|
||||
* path separator.
|
||||
* @param p addtional path suffix
|
||||
*/
|
||||
void concat( const string p );
|
||||
|
||||
/**
|
||||
* Get the directory part of the path.
|
||||
* @return directory string
|
||||
*/
|
||||
string dir();
|
||||
|
||||
/** Get the path string
|
||||
* @return path string
|
||||
*/
|
||||
inline string str() const { return path; }
|
||||
|
||||
/** Get the path string
|
||||
* @return path in "C" string (ptr to char array) form.
|
||||
*/
|
||||
inline const char *c_str() { return path.c_str(); }
|
||||
};
|
||||
|
||||
|
||||
#endif // _SG_PATH_HXX
|
||||
|
||||
|
||||
@@ -23,9 +23,15 @@
|
||||
|
||||
#include <ctype.h> // isspace()
|
||||
|
||||
#include "fgstream.hxx"
|
||||
#ifdef SG_HAVE_STD_INCLUDES
|
||||
# include <cerrno>
|
||||
#else
|
||||
# include <errno.h>
|
||||
#endif
|
||||
|
||||
fg_gzifstream::fg_gzifstream()
|
||||
#include "sgstream.hxx"
|
||||
|
||||
sg_gzifstream::sg_gzifstream()
|
||||
: istream(&gzbuf)
|
||||
{
|
||||
}
|
||||
@@ -34,7 +40,7 @@ fg_gzifstream::fg_gzifstream()
|
||||
//
|
||||
// Open a possibly gzipped file for reading.
|
||||
//
|
||||
fg_gzifstream::fg_gzifstream( const string& name, ios_openmode io_mode )
|
||||
sg_gzifstream::sg_gzifstream( const string& name, ios_openmode io_mode )
|
||||
: istream(&gzbuf)
|
||||
{
|
||||
this->open( name, io_mode );
|
||||
@@ -44,7 +50,7 @@ fg_gzifstream::fg_gzifstream( const string& name, ios_openmode io_mode )
|
||||
//
|
||||
// Attach a stream to an already opened file descriptor.
|
||||
//
|
||||
fg_gzifstream::fg_gzifstream( int fd, ios_openmode io_mode )
|
||||
sg_gzifstream::sg_gzifstream( int fd, ios_openmode io_mode )
|
||||
: istream(&gzbuf)
|
||||
{
|
||||
gzbuf.attach( fd, io_mode );
|
||||
@@ -59,7 +65,7 @@ fg_gzifstream::fg_gzifstream( int fd, ios_openmode io_mode )
|
||||
// then append ".gz" and try again.
|
||||
//
|
||||
void
|
||||
fg_gzifstream::open( const string& name, ios_openmode io_mode )
|
||||
sg_gzifstream::open( const string& name, ios_openmode io_mode )
|
||||
{
|
||||
gzbuf.open( name.c_str(), io_mode );
|
||||
if ( ! gzbuf.is_open() )
|
||||
@@ -83,7 +89,7 @@ fg_gzifstream::open( const string& name, ios_openmode io_mode )
|
||||
}
|
||||
|
||||
void
|
||||
fg_gzifstream::attach( int fd, ios_openmode io_mode )
|
||||
sg_gzifstream::attach( int fd, ios_openmode io_mode )
|
||||
{
|
||||
gzbuf.attach( fd, io_mode );
|
||||
}
|
||||
136
simgear/misc/sgstream.hxx
Normal file
136
simgear/misc/sgstream.hxx
Normal file
@@ -0,0 +1,136 @@
|
||||
/**
|
||||
* \file sgstream.hxx
|
||||
* zlib input file stream wrapper.
|
||||
*/
|
||||
|
||||
// Written by Bernie Bright, 1998
|
||||
//
|
||||
// Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this library; if not, write to the
|
||||
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
// Boston, MA 02111-1307, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#ifndef _SGSTREAM_HXX
|
||||
#define _SGSTREAM_HXX
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#if defined( SG_HAVE_STD_INCLUDES )
|
||||
# include <istream>
|
||||
#elif defined ( SG_HAVE_NATIVE_SGI_COMPILERS )
|
||||
# include <CC/stream.h>
|
||||
#elif defined ( __BORLANDC__ )
|
||||
# include <iostream>
|
||||
#else
|
||||
# include <istream.h>
|
||||
#endif
|
||||
|
||||
#include STL_STRING
|
||||
|
||||
#include <simgear/misc/zfstream.hxx>
|
||||
|
||||
SG_USING_STD(string);
|
||||
|
||||
#ifndef SG_HAVE_NATIVE_SGI_COMPILERS
|
||||
SG_USING_STD(istream);
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* An envelope class for gzifstream.
|
||||
*/
|
||||
class sg_gzifstream : private gzifstream_base, public istream
|
||||
{
|
||||
public:
|
||||
/** Default constructor */
|
||||
sg_gzifstream();
|
||||
|
||||
/**
|
||||
* Constructor that attempt to open a file with and without
|
||||
* ".gz" extension.
|
||||
* @param name name of file
|
||||
* @param io_mode file open mode(s) "or'd" together
|
||||
*/
|
||||
sg_gzifstream( const string& name,
|
||||
ios_openmode io_mode = ios_in | ios_binary );
|
||||
|
||||
/**
|
||||
* Constructor that attaches itself to an existing file descriptor.
|
||||
* @param fd file descriptor
|
||||
* @param io_mode file open mode(s) "or'd" together
|
||||
*/
|
||||
sg_gzifstream( int fd, ios_openmode io_mode = ios_in|ios_binary );
|
||||
|
||||
/**
|
||||
* Attempt to open a file with and without ".gz" extension.
|
||||
* @param name name of file
|
||||
* @param io_mode file open mode(s) "or'd" together
|
||||
*/
|
||||
void open( const string& name,
|
||||
ios_openmode io_mode = ios_in|ios_binary );
|
||||
|
||||
/**
|
||||
* Attach to an existing file descriptor.
|
||||
* @param fd file descriptor
|
||||
* @param io_mode file open mode(s) "or'd" together
|
||||
*/
|
||||
void attach( int fd, ios_openmode io_mode = ios_in|ios_binary );
|
||||
|
||||
/**
|
||||
* Close the stream.
|
||||
*/
|
||||
void close() { gzbuf.close(); }
|
||||
|
||||
/** @return true if the file is successfully opened, false otherwise. */
|
||||
bool is_open() { return gzbuf.is_open(); }
|
||||
|
||||
private:
|
||||
// Not defined!
|
||||
sg_gzifstream( const sg_gzifstream& );
|
||||
void operator= ( const sg_gzifstream& );
|
||||
};
|
||||
|
||||
/**
|
||||
* \relates sg_gzifstream
|
||||
* An istream manipulator that skips to end of line.
|
||||
* @param in input stream
|
||||
*/
|
||||
istream& skipeol( istream& in );
|
||||
|
||||
/**
|
||||
* \relates sg_gzifstream
|
||||
* An istream manipulator that skips over white space.
|
||||
* @param in input stream
|
||||
*/
|
||||
istream& skipws( istream& in );
|
||||
|
||||
/**
|
||||
* \relates sg_gzifstream
|
||||
* An istream manipulator that skips comments and white space.
|
||||
* Ignores comments that start with '#'.
|
||||
* @param in input stream
|
||||
*/
|
||||
istream& skipcomment( istream& in );
|
||||
|
||||
|
||||
#endif /* _SGSTREAM_HXX */
|
||||
|
||||
@@ -1,12 +1,20 @@
|
||||
/***************************************************************************
|
||||
* stopwatch.hxx Timer class, for use in benchmarking
|
||||
*
|
||||
/**
|
||||
* \file stopwatch.hxx
|
||||
* Timer class, for use in benchmarking
|
||||
* Based on blitz/Timer.h
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 1997,1998 Todd Veldhuizen <tveldhui@seurat.uwaterloo.ca>
|
||||
*
|
||||
* Suggestions: blitz-suggest@cybervision.com
|
||||
* Bugs: blitz-bugs@cybervision.com
|
||||
*
|
||||
* For more information, please see the Blitz++ Home Page:
|
||||
* http://seurat.uwaterloo.ca/blitz/
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
@@ -22,12 +30,6 @@
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* Suggestions: blitz-suggest@cybervision.com
|
||||
* Bugs: blitz-bugs@cybervision.com
|
||||
*
|
||||
* For more information, please see the Blitz++ Home Page:
|
||||
* http://seurat.uwaterloo.ca/blitz/
|
||||
*
|
||||
*/
|
||||
|
||||
// This class is not portable to non System V platforms.
|
||||
@@ -66,30 +68,34 @@
|
||||
# include <time.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* A high resolutions timing class
|
||||
*/
|
||||
class StopWatch {
|
||||
|
||||
public:
|
||||
StopWatch()
|
||||
{
|
||||
// state_ = uninitialized;
|
||||
/** Constructor */
|
||||
StopWatch() {
|
||||
// state_ = uninitialized;
|
||||
}
|
||||
|
||||
void start()
|
||||
{
|
||||
// state_ = running;
|
||||
/** Start counting time */
|
||||
void start() {
|
||||
// state_ = running;
|
||||
t1_ = systemTime();
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
/** Stop counting time */
|
||||
void stop() {
|
||||
t2_ = systemTime();
|
||||
// BZPRECONDITION(state_ == running);
|
||||
// state_ = stopped;
|
||||
// BZPRECONDITION(state_ == running);
|
||||
// state_ = stopped;
|
||||
}
|
||||
|
||||
/** @return the elapsed time between start and stop */
|
||||
double elapsedSeconds()
|
||||
{
|
||||
// BZPRECONDITION(state_ == stopped);
|
||||
// BZPRECONDITION(state_ == stopped);
|
||||
return t2_ - t1_;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,10 +21,6 @@
|
||||
//
|
||||
// $Id$
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "strutils.hxx"
|
||||
|
||||
const string whitespace = " \n\r\t";
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
// String utilities.
|
||||
//
|
||||
/**
|
||||
* \file strutils.hxx
|
||||
* String utilities.
|
||||
*/
|
||||
|
||||
// Written by Bernie Bright, 1998
|
||||
//
|
||||
// Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au
|
||||
@@ -21,6 +24,7 @@
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#ifndef STRUTILS_H
|
||||
#define STRUTILS_H
|
||||
|
||||
@@ -28,34 +32,35 @@
|
||||
|
||||
#include STL_STRING
|
||||
|
||||
#ifdef FG_HAVE_STD_INCLUDES
|
||||
#ifdef SG_HAVE_STD_INCLUDES
|
||||
# include <cstdlib>
|
||||
#else
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
FG_USING_STD(string);
|
||||
SG_USING_STD(string);
|
||||
|
||||
// Default characters to remove.
|
||||
|
||||
/** Default characters to remove. */
|
||||
extern const string whitespace;
|
||||
|
||||
// Returns a string with trailing characters removed.
|
||||
/** Returns a string with trailing characters removed. */
|
||||
string trimleft( const string& s, const string& trimmings = whitespace );
|
||||
|
||||
// Returns a string with leading characters removed.
|
||||
/** Returns a string with leading characters removed. */
|
||||
string trimright( const string& s, const string& trimmings = whitespace );
|
||||
|
||||
// Returns a string with leading and trailing characters removed.
|
||||
/** Returns a string with leading and trailing characters removed. */
|
||||
string trim( const string& s, const string& trimmings = whitespace );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/** atof() wrapper for "string" type */
|
||||
inline double
|
||||
atof( const string& str )
|
||||
{
|
||||
return ::atof( str.c_str() );
|
||||
}
|
||||
|
||||
/** atoi() wrapper for "string" type */
|
||||
inline int
|
||||
atoi( const string& str )
|
||||
{
|
||||
|
||||
@@ -178,10 +178,10 @@ point_list calc_tex_coords( const SGBucket& b, const point_list& geod_nodes,
|
||||
clat = (int)clat - 0.5;
|
||||
}
|
||||
|
||||
double clat_rad = clat * DEG_TO_RAD;
|
||||
double clat_rad = clat * SGD_DEGREES_TO_RADIANS;
|
||||
double cos_lat = cos( clat_rad );
|
||||
double local_radius = cos_lat * EQUATORIAL_RADIUS_M;
|
||||
double local_perimeter = 2.0 * local_radius * FG_PI;
|
||||
double local_radius = cos_lat * SG_EQUATORIAL_RADIUS_M;
|
||||
double local_perimeter = 2.0 * local_radius * SGD_PI;
|
||||
double degree_width = local_perimeter / 360.0;
|
||||
|
||||
// cout << "clat = " << clat << endl;
|
||||
@@ -191,7 +191,7 @@ point_list calc_tex_coords( const SGBucket& b, const point_list& geod_nodes,
|
||||
// cout << "local_perimeter = " << local_perimeter << endl;
|
||||
// cout << "degree_width = " << degree_width << endl;
|
||||
|
||||
double perimeter = 2.0 * EQUATORIAL_RADIUS_M * FG_PI;
|
||||
double perimeter = 2.0 * SG_EQUATORIAL_RADIUS_M * SGD_PI;
|
||||
double degree_height = perimeter / 360.0;
|
||||
// cout << "degree_height = " << degree_height << endl;
|
||||
|
||||
@@ -323,10 +323,10 @@ point_list calc_tex_coords( const SGBucket& b, const point_list& geod_nodes,
|
||||
// cout << "adjusted_t " << adjusted_t << endl;
|
||||
}
|
||||
#endif
|
||||
if ( adjusted_t.x() < FG_EPSILON ) {
|
||||
if ( adjusted_t.x() < SG_EPSILON ) {
|
||||
adjusted_t.setx( 0.0 );
|
||||
}
|
||||
if ( adjusted_t.y() < FG_EPSILON ) {
|
||||
if ( adjusted_t.y() < SG_EPSILON ) {
|
||||
adjusted_t.sety( 0.0 );
|
||||
}
|
||||
adjusted_t.setz( 0.0 );
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
// texcoord.hxx -- routine(s) to handle texture coordinate generation
|
||||
//
|
||||
/**
|
||||
* \file texcoord.hxx
|
||||
* Routine to handle texture coordinate generation.
|
||||
*/
|
||||
|
||||
// Written by Curtis Olson, started March 1999.
|
||||
//
|
||||
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
|
||||
@@ -35,8 +38,15 @@
|
||||
#include <simgear/math/sg_types.hxx>
|
||||
|
||||
|
||||
// traverse the specified fan/strip/list of vertices and attempt to
|
||||
// calculate "none stretching" texture coordinates
|
||||
/**
|
||||
* Traverse the specified fan/strip/list of vertices and attempt to
|
||||
* calculate "none stretching" texture coordinates.
|
||||
* @param b the bucket containing the structure
|
||||
* @param geod_nodes vertices in geodetic coordinates
|
||||
* @param fan integer list of indices pointing into the vertex list
|
||||
* @param scale (default = 1.0) scaling factor
|
||||
* @return list of texture coordinates
|
||||
*/
|
||||
point_list calc_tex_coords( const SGBucket& b, const point_list& geod_nodes,
|
||||
const int_list& fan, double scale = 1.0 );
|
||||
|
||||
|
||||
@@ -22,7 +22,16 @@
|
||||
//
|
||||
// $Id$
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#ifdef SG_HAVE_STD_INCLUDES
|
||||
# include <cerrno>
|
||||
#else
|
||||
# include <errno.h>
|
||||
#endif
|
||||
#include <memory.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "zfstream.hxx"
|
||||
|
||||
//
|
||||
@@ -32,7 +41,7 @@
|
||||
gzfilebuf::gzfilebuf()
|
||||
: streambuf(),
|
||||
file(NULL),
|
||||
#if defined( __MWERKS__ )
|
||||
#if defined( __MWERKS__ ) || __GNUC__ > 2
|
||||
mode(ios_openmode(0)),
|
||||
#else
|
||||
mode(0),
|
||||
@@ -106,8 +115,11 @@ gzfilebuf::open( const char *name, ios_openmode io_mode )
|
||||
|
||||
char char_mode[10];
|
||||
cvt_iomode( char_mode, io_mode );
|
||||
if ( (file = gzopen(name, char_mode)) == NULL )
|
||||
if ( (file = gzopen(name, char_mode)) == NULL ) {
|
||||
// perror( "gzfilebuf::open(): " );
|
||||
errno = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
own_file_descriptor = true;
|
||||
|
||||
@@ -122,8 +134,11 @@ gzfilebuf::attach( int file_descriptor, ios_openmode io_mode )
|
||||
|
||||
char char_mode[10];
|
||||
cvt_iomode( char_mode, io_mode );
|
||||
if ( (file = gzdopen(file_descriptor, char_mode)) == NULL )
|
||||
if ( (file = gzdopen(file_descriptor, char_mode)) == NULL ) {
|
||||
perror( "gzfilebuf::attach(): " );
|
||||
errno = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
own_file_descriptor = false;
|
||||
|
||||
@@ -133,11 +148,15 @@ gzfilebuf::attach( int file_descriptor, ios_openmode io_mode )
|
||||
gzfilebuf*
|
||||
gzfilebuf::close()
|
||||
{
|
||||
// cout << "closing ..." ;
|
||||
if ( is_open() )
|
||||
{
|
||||
sync();
|
||||
gzclose( file );
|
||||
file = NULL;
|
||||
// cout << "done" << endl;
|
||||
} else {
|
||||
// cout << "error" << endl;
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
// A C++ I/O streams interface to the zlib gz* functions
|
||||
//
|
||||
/**
|
||||
* \file zfstream.hxx
|
||||
* A C++ I/O streams interface to the zlib gz* functions.
|
||||
*/
|
||||
|
||||
// Written by Bernie Bright, 1998
|
||||
// Based on zlib/contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
|
||||
//
|
||||
@@ -25,10 +28,6 @@
|
||||
#ifndef _zfstream_hxx
|
||||
#define _zfstream_hxx
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
@@ -37,7 +36,13 @@
|
||||
# include <simgear/zlib/zlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef FG_HAVE_STD_INCLUDES
|
||||
// At least Irix needs this
|
||||
#ifdef SG_HAVE_NATIVE_SGI_COMPILERS
|
||||
#include <char_traits.h>
|
||||
SG_USING_STD(char_traits);
|
||||
#endif
|
||||
|
||||
#ifdef SG_HAVE_STD_INCLUDES
|
||||
|
||||
# include <streambuf>
|
||||
# include <istream>
|
||||
@@ -53,14 +58,14 @@
|
||||
# define ios_badbit ios_base::badbit
|
||||
# define ios_failbit ios_base::failbit
|
||||
|
||||
FG_USING_STD(streambuf);
|
||||
FG_USING_STD(ios_base);
|
||||
FG_USING_STD(streampos);
|
||||
FG_USING_STD(streamoff);
|
||||
SG_USING_STD(streambuf);
|
||||
SG_USING_STD(ios_base);
|
||||
SG_USING_STD(streampos);
|
||||
SG_USING_STD(streamoff);
|
||||
|
||||
#else
|
||||
|
||||
# ifdef FG_HAVE_STREAMBUF
|
||||
# ifdef SG_HAVE_STREAMBUF
|
||||
# include <streambuf.h>
|
||||
# include <istream.h>
|
||||
# else
|
||||
@@ -75,7 +80,7 @@ FG_USING_STD(streamoff);
|
||||
|
||||
#if defined(__GNUC__) && __GNUC_MINOR__ < 8
|
||||
# define ios_binary ios::bin
|
||||
#elif defined( FG_HAVE_NATIVE_SGI_COMPILERS )
|
||||
#elif defined( SG_HAVE_NATIVE_SGI_COMPILERS )
|
||||
# define ios_binary 0
|
||||
#else
|
||||
# define ios_binary ios::binary
|
||||
@@ -86,36 +91,59 @@ FG_USING_STD(streamoff);
|
||||
# define ios_badbit ios::badbit
|
||||
# define ios_failbit ios::failbit
|
||||
|
||||
# include <simgear/fg_traits.hxx>
|
||||
# include <simgear/sg_traits.hxx>
|
||||
|
||||
#endif // FG_HAVE_STD_INCLUDES
|
||||
#endif // SG_HAVE_STD_INCLUDES
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
/**
|
||||
* A C++ I/O streams interface to the zlib gz* functions.
|
||||
*/
|
||||
class gzfilebuf : public streambuf
|
||||
{
|
||||
public:
|
||||
|
||||
#ifndef FG_HAVE_STD_INCLUDES
|
||||
#ifndef SG_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;
|
||||
// typedef char_traits<char>::pos_type pos_type;
|
||||
// typedef char_traits<char>::off_type off_type;
|
||||
#endif
|
||||
|
||||
/** Constructor */
|
||||
gzfilebuf();
|
||||
|
||||
/** Destructor */
|
||||
virtual ~gzfilebuf();
|
||||
|
||||
/**
|
||||
* Open a stream
|
||||
* @param name file name
|
||||
* @param io_mode mdoe flags
|
||||
* @return file stream
|
||||
*/
|
||||
gzfilebuf* open( const char* name, ios_openmode io_mode );
|
||||
|
||||
/**
|
||||
* Attach to an existing file descriptor
|
||||
* @param file_descriptor file descriptor
|
||||
* @param io_mode mode flags
|
||||
* @return file stream
|
||||
*/
|
||||
gzfilebuf* attach( int file_descriptor, ios_openmode io_mode );
|
||||
|
||||
/** Close stream */
|
||||
gzfilebuf* close();
|
||||
|
||||
// int setcompressionlevel( int comp_level );
|
||||
// int setcompressionstrategy( int comp_strategy );
|
||||
// int setcompressionlevel( int comp_level );
|
||||
// int setcompressionstrategy( int comp_strategy );
|
||||
|
||||
/** @return true if open, false otherwise */
|
||||
bool is_open() const { return (file != NULL); }
|
||||
|
||||
/** @return stream position */
|
||||
virtual streampos seekoff( streamoff off, ios_seekdir way, int which );
|
||||
|
||||
/** sync the stream */
|
||||
virtual int sync();
|
||||
|
||||
protected:
|
||||
@@ -149,10 +177,9 @@ private:
|
||||
void operator= ( const gzfilebuf& );
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
/**
|
||||
* document me
|
||||
*/
|
||||
struct gzifstream_base
|
||||
{
|
||||
gzifstream_base() {}
|
||||
|
||||
@@ -17,11 +17,14 @@ waytest_SOURCES = waytest.cxx
|
||||
waytest_LDADD = \
|
||||
$(top_builddir)/simgear/route/libsgroute.a \
|
||||
$(top_builddir)/simgear/math/libsgmath.a \
|
||||
$(top_builddir)/simgear/debug/libsgdebug.a
|
||||
$(top_builddir)/simgear/debug/libsgdebug.a \
|
||||
$(top_builddir)/simgear/misc/libsgmisc.a \
|
||||
$(top_builddir)/simgear/xml/libsgxml.a \
|
||||
-lz
|
||||
|
||||
routetest_SOURCES = routetest.cxx
|
||||
|
||||
routetest_LDADD = \
|
||||
$(top_builddir)/simgear/route/libsgroute.a \
|
||||
$(top_builddir)/simgear/math/libsgmath.a \
|
||||
$(top_builddir)/simgear/debug/libsgdebug.a
|
||||
$(top_builddir)/simgear/debug/libsgdebug.a
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
// route.hxx -- Class to manage a list of waypoints (route)
|
||||
//
|
||||
/**
|
||||
* \file route.hxx
|
||||
* Provides a class to manage a list of waypoints (i.e. a route).
|
||||
*/
|
||||
|
||||
// Written by Curtis Olson, started October 2000.
|
||||
//
|
||||
// Copyright (C) 2000 Curtis L. Olson - curt@hfrl.umn.edu
|
||||
@@ -30,20 +33,19 @@
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include STL_STRING
|
||||
#include <vector>
|
||||
|
||||
FG_USING_STD(string);
|
||||
FG_USING_STD(vector);
|
||||
SG_USING_STD(string);
|
||||
SG_USING_STD(vector);
|
||||
|
||||
#include <simgear/route/waypoint.hxx>
|
||||
|
||||
/**
|
||||
* A class to manage a list of waypoints (i.e. a route).
|
||||
*/
|
||||
|
||||
class SGRoute {
|
||||
|
||||
@@ -55,16 +57,22 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
/** Constructor */
|
||||
SGRoute();
|
||||
|
||||
/** Destructor */
|
||||
~SGRoute();
|
||||
|
||||
// clear the entire route
|
||||
/** Clear the entire route */
|
||||
inline void clear() {
|
||||
route.clear();
|
||||
current_wp = 0;
|
||||
}
|
||||
|
||||
// add a waypoint
|
||||
/**
|
||||
* Add a waypoint.
|
||||
* @param wp a waypoint
|
||||
*/
|
||||
inline void add_waypoint( const SGWayPoint &wp ) {
|
||||
route.push_back( wp );
|
||||
|
||||
@@ -77,10 +85,16 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// get the number of waypoints
|
||||
/**
|
||||
* Get the number of waypoints (i.e. route length )
|
||||
* @return route length
|
||||
*/
|
||||
inline int size() const { return route.size(); }
|
||||
|
||||
// get the front waypoint
|
||||
/**
|
||||
* Get the front waypoint.
|
||||
* @return the first waypoint.
|
||||
*/
|
||||
inline SGWayPoint get_first() const {
|
||||
if ( route.size() ) {
|
||||
return route[0];
|
||||
@@ -89,7 +103,10 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// get the current waypoint
|
||||
/**
|
||||
* Get the current waypoint
|
||||
* @return the current waypoint
|
||||
*/
|
||||
inline SGWayPoint get_current() const {
|
||||
if ( current_wp < (int)route.size() ) {
|
||||
return route[current_wp];
|
||||
@@ -98,21 +115,28 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// set the current waypoint
|
||||
/**
|
||||
* Set the current waypoint
|
||||
* @param number of waypoint to make current.
|
||||
*/
|
||||
inline void set_current( int n ) {
|
||||
if ( n >= 0 && n < (int)route.size() ) {
|
||||
current_wp = n;
|
||||
}
|
||||
}
|
||||
|
||||
// increment the current waypoint
|
||||
/** Increment the current waypoint pointer. */
|
||||
inline void increment_current() {
|
||||
if ( current_wp < (int)route.size() - 1 ) {
|
||||
++current_wp;
|
||||
}
|
||||
}
|
||||
|
||||
// get the nth waypoint
|
||||
/**
|
||||
* Get the nth waypoint
|
||||
* @param n waypoint number
|
||||
* @return the nth waypoint
|
||||
*/
|
||||
inline SGWayPoint get_waypoint( const int n ) const {
|
||||
if ( n < (int)route.size() ) {
|
||||
return route[n];
|
||||
@@ -121,17 +145,19 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// delete the front waypoint
|
||||
/** Delete the front waypoint */
|
||||
inline void delete_first() {
|
||||
if ( route.size() ) {
|
||||
route.erase( route.begin() );
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate perpendicular distance from the current route segment
|
||||
// This routine assumes all points are laying on a flat plane and
|
||||
// ignores the altitude (or Z) dimension. For best results, use
|
||||
// with CARTESIAN way points.
|
||||
/**
|
||||
* Calculate perpendicular distance from the current route segment
|
||||
* This routine assumes all points are laying on a flat plane and
|
||||
* ignores the altitude (or Z) dimension. For most accurate
|
||||
* results, use with CARTESIAN way points.
|
||||
*/
|
||||
double distance_off_route( double x, double y ) const;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
#include <simgear/compiler.h>
|
||||
#include <simgear/constants.h>
|
||||
|
||||
#include STL_IOSTREAM
|
||||
|
||||
#include "route.hxx"
|
||||
#include "waypoint.hxx"
|
||||
|
||||
#if !defined(SG_HAVE_NATIVE_SGI_COMPILERS)
|
||||
SG_USING_STD(cout);
|
||||
SG_USING_STD(endl);
|
||||
#endif
|
||||
|
||||
int main() {
|
||||
SGRoute route;
|
||||
|
||||
|
||||
@@ -61,14 +61,14 @@ void SGWayPoint::CourseAndDistance( const double cur_lon,
|
||||
geo_inverse_wgs_84( cur_alt, cur_lat, cur_lon, target_lat, target_lon,
|
||||
course, &reverse, distance );
|
||||
} else if ( mode == SPHERICAL ) {
|
||||
Point3D current( cur_lon * DEG_TO_RAD, cur_lat * DEG_TO_RAD, 0.0 );
|
||||
Point3D target( target_lon * DEG_TO_RAD, target_lat * DEG_TO_RAD, 0.0 );
|
||||
Point3D current( cur_lon * SGD_DEGREES_TO_RADIANS, cur_lat * SGD_DEGREES_TO_RADIANS, 0.0 );
|
||||
Point3D target( target_lon * SGD_DEGREES_TO_RADIANS, target_lat * SGD_DEGREES_TO_RADIANS, 0.0 );
|
||||
calc_gc_course_dist( current, target, course, distance );
|
||||
*course = 360.0 - *course * RAD_TO_DEG;
|
||||
*course = 360.0 - *course * SGD_RADIANS_TO_DEGREES;
|
||||
} else if ( mode == CARTESIAN ) {
|
||||
double dx = target_lon - cur_lon;
|
||||
double dy = target_lat - cur_lat;
|
||||
*course = -atan2( dy, dx ) * RAD_TO_DEG - 90;
|
||||
*course = -atan2( dy, dx ) * SGD_RADIANS_TO_DEGREES - 90;
|
||||
while ( *course < 0 ) {
|
||||
*course += 360.0;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
// waypoint.hxx -- Class to hold data and return info relating to a waypoint
|
||||
//
|
||||
/**
|
||||
* \file waypoint.hxx
|
||||
* Provides a class to manage waypoints
|
||||
*/
|
||||
|
||||
// Written by Curtis Olson, started September 2000.
|
||||
//
|
||||
// Copyright (C) 2000 Curtis L. Olson - curt@hfrl.umn.edu
|
||||
@@ -30,21 +33,33 @@
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include STL_STRING
|
||||
|
||||
FG_USING_STD(string);
|
||||
SG_USING_STD(string);
|
||||
|
||||
|
||||
/**
|
||||
* A class to manage waypoints.
|
||||
*/
|
||||
|
||||
class SGWayPoint {
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Waypoint mode.
|
||||
* <li> WGS84 requests all bearing and distance math be done assuming a
|
||||
* WGS84 ellipsoid world. This is the most expensive computationally,
|
||||
* but also the most accurate.
|
||||
* <li> SPHERICAL requests all bearing and distance math be done assuming
|
||||
* the world is a perfect sphere. This is less compuntationally
|
||||
* expensive than using wgs84 math and still a fairly good
|
||||
* approximation of the real world, especially over shorter distances.
|
||||
* <li> CARTESIAN requests all math be done assuming the coordinates specify
|
||||
* position in a Z = up world.
|
||||
*/
|
||||
enum modetype {
|
||||
WGS84 = 0,
|
||||
SPHERICAL = 1,
|
||||
@@ -64,32 +79,82 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
/** Default constructor */
|
||||
SGWayPoint();
|
||||
|
||||
/**
|
||||
* Construct a waypoint
|
||||
* @param lon destination longitude
|
||||
* @param lat destination latitude
|
||||
* @param alt target altitude
|
||||
* @param mode type of coordinates/math to use
|
||||
* @param s waypoint identifier
|
||||
*/
|
||||
SGWayPoint( const double lon, const double lat, const double alt,
|
||||
const modetype m = WGS84, const string s = "" );
|
||||
|
||||
/** Destructor */
|
||||
~SGWayPoint();
|
||||
|
||||
// Calculate course and distances. For WGS84 and SPHERICAL
|
||||
// coordinates lat, lon, and course are in degrees, alt and
|
||||
// distance are in meters. For CARTESIAN coordinates x = lon, y =
|
||||
// lat. Course is in degrees and distance is in what ever units x
|
||||
// and y are in.
|
||||
/**
|
||||
* Calculate course and distances. For WGS84 and SPHERICAL
|
||||
* coordinates lat, lon, and course are in degrees, alt and
|
||||
* distance are in meters. For CARTESIAN coordinates x = lon, y =
|
||||
* lat. Course is in degrees and distance is in what ever units x
|
||||
* and y are in.
|
||||
* @param cur_lon (in) current longitude
|
||||
* @param cur_lat (in) current latitude
|
||||
* @param cur_alt (in) current altitude
|
||||
* @param course (out) heading from current location to this waypoint
|
||||
* @param distance (out) distance from current location to this waypoint
|
||||
*/
|
||||
void CourseAndDistance( const double cur_lon, const double cur_lat,
|
||||
const double cur_alt,
|
||||
double *course, double *distance ) const;
|
||||
|
||||
// Calculate course and distances between two waypoints
|
||||
/**
|
||||
* Calculate course and distances between a specified starting waypoint
|
||||
* and this waypoint.
|
||||
* @param wp (in) original waypoint
|
||||
* @param course (out) heading from current location to this waypoint
|
||||
* @param distance (out) distance from current location to this waypoint
|
||||
*/
|
||||
void CourseAndDistance( const SGWayPoint &wp,
|
||||
double *course, double *distance ) const;
|
||||
|
||||
/** @return waypoint mode */
|
||||
inline modetype get_mode() const { return mode; }
|
||||
|
||||
/** @return waypoint longitude */
|
||||
inline double get_target_lon() const { return target_lon; }
|
||||
|
||||
/** @return waypoint latitude */
|
||||
inline double get_target_lat() const { return target_lat; }
|
||||
|
||||
/** @return waypoint altitude */
|
||||
inline double get_target_alt() const { return target_alt; }
|
||||
|
||||
/**
|
||||
* This value is not calculated by this class. It is simply a
|
||||
* placeholder for the user to stash a distance value. This is useful
|
||||
* when you stack waypoints together into a route. You can calculate the
|
||||
* distance from the previous waypoint once and save it here. Adding up
|
||||
* all the distances here plus the distance to the first waypoint gives you
|
||||
* the total route length. Note, you must update this value yourself, this
|
||||
* is for your convenience only.
|
||||
* @return waypoint distance holder (what ever the user has stashed here)
|
||||
*/
|
||||
inline double get_distance() const { return distance; }
|
||||
|
||||
/**
|
||||
* Set the waypoint distance value to a value of our choice.
|
||||
* @param d distance
|
||||
*/
|
||||
inline void set_distance( double d ) { distance = d; }
|
||||
|
||||
/** @return waypoint id */
|
||||
inline string get_id() const { return id; }
|
||||
|
||||
inline void set_distance( double d ) { distance = d; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
#include <simgear/compiler.h>
|
||||
#include <simgear/constants.h>
|
||||
|
||||
#include STL_IOSTREAM
|
||||
|
||||
#include "waypoint.hxx"
|
||||
|
||||
#if !defined(SG_HAVE_NATIVE_SGI_COMPILERS)
|
||||
SG_USING_STD(cout);
|
||||
SG_USING_STD(endl);
|
||||
#endif
|
||||
|
||||
|
||||
int main() {
|
||||
SGWayPoint a1(-93.216923, 44.880547, 0.0, SGWayPoint::WGS84, "KMSP");
|
||||
SGWayPoint a2(-93.216923, 44.880547, 0.0, SGWayPoint::SPHERICAL, "KMSP");
|
||||
@@ -14,12 +24,12 @@ int main() {
|
||||
|
||||
a1.CourseAndDistance( cur_lon, cur_lat, cur_alt, &course, &distance );
|
||||
cout << "Course to " << a1.get_id() << " is " << course << endl;
|
||||
cout << "Distance to " << a1.get_id() << " is " << distance * METER_TO_NM
|
||||
cout << "Distance to " << a1.get_id() << " is " << distance * SG_METER_TO_NM
|
||||
<< endl;
|
||||
|
||||
a2.CourseAndDistance( cur_lon, cur_lat, cur_alt, &course, &distance );
|
||||
cout << "Course to " << a2.get_id() << " is " << course << endl;
|
||||
cout << "Distance to " << a2.get_id() << " is " << distance * METER_TO_NM
|
||||
cout << "Distance to " << a2.get_id() << " is " << distance * SG_METER_TO_NM
|
||||
<< endl;
|
||||
cout << endl;
|
||||
|
||||
@@ -28,12 +38,12 @@ int main() {
|
||||
|
||||
b1.CourseAndDistance( cur_lon, cur_lat, cur_alt, &course, &distance );
|
||||
cout << "Course to " << b1.get_id() << " is " << course << endl;
|
||||
cout << "Distance to " << b1.get_id() << " is " << distance * METER_TO_NM
|
||||
cout << "Distance to " << b1.get_id() << " is " << distance * SG_METER_TO_NM
|
||||
<< endl;
|
||||
|
||||
b2.CourseAndDistance( cur_lon, cur_lat, cur_alt, &course, &distance );
|
||||
cout << "Course to " << b2.get_id() << " is " << course << endl;
|
||||
cout << "Distance to " << b2.get_id() << " is " << distance * METER_TO_NM
|
||||
cout << "Distance to " << b2.get_id() << " is " << distance * SG_METER_TO_NM
|
||||
<< endl;
|
||||
cout << endl;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
|
||||
@@ -2,11 +2,12 @@ includedir = @includedir@/screen
|
||||
|
||||
lib_LIBRARIES = libsgscreen.a
|
||||
|
||||
include_HEADERS = screen-dump.hxx
|
||||
include_HEADERS = screen-dump.hxx tr.h
|
||||
|
||||
libsgscreen_a_SOURCES = \
|
||||
GLBitmaps.cxx GLBitmaps.h \
|
||||
screen-dump.cxx \
|
||||
tr.cxx \
|
||||
win32-printer.h
|
||||
|
||||
INCLUDES += -I$(top_srcdir)
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
@@ -38,21 +38,21 @@
|
||||
#include "screen-dump.hxx"
|
||||
|
||||
|
||||
#define RGB 3 // 3 bytes of color info per pixel
|
||||
#define RGB3 3 // 3 bytes of color info per pixel
|
||||
#define RGBA 4 // 4 bytes of color+alpha info
|
||||
|
||||
void my_glWritePPMFile(const char *filename, GLubyte *buffer, int win_width, int win_height, int mode)
|
||||
bool sg_glWritePPMFile(const char *filename, GLubyte *buffer, int win_width, int win_height, int mode)
|
||||
{
|
||||
int i, j, k, q;
|
||||
unsigned char *ibuffer;
|
||||
FILE *fp;
|
||||
int pixelSize = mode==GL_RGBA?4:3;
|
||||
|
||||
ibuffer = (unsigned char *) malloc(win_width*win_height*RGB);
|
||||
ibuffer = (unsigned char *) malloc(win_width*win_height*RGB3);
|
||||
|
||||
if ( (fp = fopen(filename, "wb")) == NULL ) {
|
||||
printf("Warning: cannot open %s\n", filename);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
fprintf(fp, "P6\n# CREATOR: glReadPixel()\n%d %d\n%d\n",
|
||||
@@ -60,21 +60,23 @@ void my_glWritePPMFile(const char *filename, GLubyte *buffer, int win_width, int
|
||||
q = 0;
|
||||
for (i = 0; i < win_height; i++)
|
||||
for (j = 0; j < win_width; j++)
|
||||
for (k = 0; k < RGB; k++)
|
||||
for (k = 0; k < RGB3; k++)
|
||||
ibuffer[q++] = (unsigned char)
|
||||
*(buffer + (pixelSize*((win_height-1-i)*win_width+j)+k));
|
||||
fwrite(ibuffer, sizeof(unsigned char), RGB*win_width*win_height, fp);
|
||||
fwrite(ibuffer, sizeof(unsigned char), RGB3*win_width*win_height, fp);
|
||||
fclose(fp);
|
||||
free(ibuffer);
|
||||
|
||||
printf("wrote file (%d x %d pixels, %d bytes)\n",
|
||||
win_width, win_height, RGB*win_width*win_height);
|
||||
win_width, win_height, RGB3*win_width*win_height);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// dump the screen buffer to a ppm file
|
||||
void my_glDumpWindow(const char *filename, int win_width, int win_height) {
|
||||
bool sg_glDumpWindow(const char *filename, int win_width, int win_height) {
|
||||
GLubyte *buffer;
|
||||
bool result;
|
||||
|
||||
buffer = (GLubyte *) malloc(win_width*win_height*RGBA);
|
||||
|
||||
@@ -82,7 +84,10 @@ void my_glDumpWindow(const char *filename, int win_width, int win_height) {
|
||||
glFinish();
|
||||
glReadPixels(0, 0, win_width, win_height,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, buffer);
|
||||
my_glWritePPMFile( filename, buffer, win_width, win_height, GL_RGBA );
|
||||
result = sg_glWritePPMFile( filename, buffer, win_width, win_height,
|
||||
GL_RGBA );
|
||||
free(buffer);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
// screen-dump.hxx -- dump a copy of the opengl screen buffer to a file
|
||||
//
|
||||
/**
|
||||
* \file screen-dump.hxx
|
||||
* Dump a copy of the opengl screen buffer to a file.
|
||||
*/
|
||||
|
||||
// Contributed by Richard Kaszeta <bofh@me.umn.edu>, started October 1999.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
@@ -20,8 +23,22 @@
|
||||
// $Id$
|
||||
|
||||
|
||||
// dump the screen buffer to a ppm file
|
||||
void my_glDumpWindow( const char *filename, int win_width, int win_height );
|
||||
/**
|
||||
* Dump the screen buffer to a ppm file.
|
||||
* @param filename name of file
|
||||
* @param win_width width of our opengl window
|
||||
* @param win_height height of our opengl window
|
||||
*/
|
||||
bool sg_glDumpWindow( const char *filename, int win_width, int win_height );
|
||||
|
||||
void my_glWritePPMFile( const char *filename, GLubyte *buffer, int win_width,
|
||||
|
||||
/**
|
||||
* Given a GLubyte *buffer, write it out to a ppm file.
|
||||
* @param filename name of file
|
||||
* @param buffer pointer to opengl buffer
|
||||
* @param win_width width of buffer
|
||||
* @param win_height height of buffer
|
||||
* @param mode one of GL_RGBA, GL_RGB, etc.
|
||||
*/
|
||||
bool sg_glWritePPMFile( const char *filename, GLubyte *buffer, int win_width,
|
||||
int win_height, int mode);
|
||||
|
||||
509
simgear/screen/tr.cxx
Normal file
509
simgear/screen/tr.cxx
Normal file
@@ -0,0 +1,509 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* $Log$
|
||||
* Revision 1.2 2001/06/27 02:48:01 curt
|
||||
* Fixed a type conversion bug that could trip up some of the pickier compilers
|
||||
* out there.
|
||||
*
|
||||
* Revision 1.1 2001/06/26 15:19:39 curt
|
||||
* Added tr.cxx / tr.h, Brian Paul's LGPL'd tiled rendering support libs for
|
||||
* rendering ultra high res "tiled" screen shots.
|
||||
*
|
||||
* Revision 1.9 1998/01/29 16:56:54 brianp
|
||||
* allow trOrtho() and trFrustum() to be called at any time, minor clean-up
|
||||
*
|
||||
* Revision 1.8 1998/01/28 19:47:39 brianp
|
||||
* minor clean-up for C++
|
||||
*
|
||||
* Revision 1.7 1997/07/21 17:34:38 brianp
|
||||
* added tile borders
|
||||
*
|
||||
* Revision 1.6 1997/07/21 15:47:35 brianp
|
||||
* renamed all "near" and "far" variables
|
||||
*
|
||||
* Revision 1.5 1997/04/26 21:23:25 brianp
|
||||
* added trRasterPos3f function
|
||||
*
|
||||
* Revision 1.4 1997/04/26 19:59:36 brianp
|
||||
* set CurrentTile to -1 before first tile and after last tile
|
||||
*
|
||||
* Revision 1.3 1997/04/22 23:51:15 brianp
|
||||
* added WIN32 header stuff, removed tabs
|
||||
*
|
||||
* Revision 1.2 1997/04/19 23:26:10 brianp
|
||||
* many API changes
|
||||
*
|
||||
* Revision 1.1 1997/04/18 21:53:05 brianp
|
||||
* Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Tiled Rendering library
|
||||
* Version 1.1
|
||||
* Copyright (C) Brian Paul
|
||||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include <plib/ssg.h>
|
||||
#include "tr.h"
|
||||
|
||||
|
||||
#define DEFAULT_TILE_WIDTH 256
|
||||
#define DEFAULT_TILE_HEIGHT 256
|
||||
#define DEFAULT_TILE_BORDER 0
|
||||
|
||||
|
||||
struct _TRctx {
|
||||
/* Final image parameters */
|
||||
GLint ImageWidth, ImageHeight;
|
||||
GLenum ImageFormat, ImageType;
|
||||
GLvoid *ImageBuffer;
|
||||
|
||||
/* Tile parameters */
|
||||
GLint TileWidth, TileHeight;
|
||||
GLint TileWidthNB, TileHeightNB;
|
||||
GLint TileBorder;
|
||||
GLenum TileFormat, TileType;
|
||||
GLvoid *TileBuffer;
|
||||
|
||||
/* Projection parameters */
|
||||
GLboolean Perspective;
|
||||
GLdouble Left;
|
||||
GLdouble Right;
|
||||
GLdouble Bottom;
|
||||
GLdouble Top;
|
||||
GLdouble Near;
|
||||
GLdouble Far;
|
||||
|
||||
/* Misc */
|
||||
TRenum RowOrder;
|
||||
GLint Rows, Columns;
|
||||
GLint CurrentTile;
|
||||
GLint CurrentTileWidth, CurrentTileHeight;
|
||||
GLint CurrentRow, CurrentColumn;
|
||||
|
||||
GLint ViewportSave[4];
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Misc setup including computing number of tiles (rows and columns).
|
||||
*/
|
||||
static void Setup(TRcontext *tr)
|
||||
{
|
||||
if (!tr)
|
||||
return;
|
||||
|
||||
tr->Columns = (tr->ImageWidth + tr->TileWidthNB - 1) / tr->TileWidthNB;
|
||||
tr->Rows = (tr->ImageHeight + tr->TileHeightNB - 1) / tr->TileHeightNB;
|
||||
tr->CurrentTile = 0;
|
||||
|
||||
assert(tr->Columns >= 0);
|
||||
assert(tr->Rows >= 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
TRcontext *trNew(void)
|
||||
{
|
||||
TRcontext *tr = (TRcontext *) calloc(1, sizeof(TRcontext));
|
||||
if (tr) {
|
||||
tr->TileWidth = DEFAULT_TILE_WIDTH;
|
||||
tr->TileHeight = DEFAULT_TILE_HEIGHT;
|
||||
tr->TileBorder = DEFAULT_TILE_BORDER;
|
||||
tr->RowOrder = TR_BOTTOM_TO_TOP;
|
||||
tr->CurrentTile = -1;
|
||||
}
|
||||
return (TRcontext *) tr;
|
||||
}
|
||||
|
||||
|
||||
void trDelete(TRcontext *tr)
|
||||
{
|
||||
if (tr)
|
||||
free(tr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void trTileSize(TRcontext *tr, GLint width, GLint height, GLint border)
|
||||
{
|
||||
if (!tr)
|
||||
return;
|
||||
|
||||
assert(border >= 0);
|
||||
assert(width >= 1);
|
||||
assert(height >= 1);
|
||||
assert(width >= 2*border);
|
||||
assert(height >= 2*border);
|
||||
|
||||
tr->TileBorder = border;
|
||||
tr->TileWidth = width;
|
||||
tr->TileHeight = height;
|
||||
tr->TileWidthNB = width - 2 * border;
|
||||
tr->TileHeightNB = height - 2 * border;
|
||||
Setup(tr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void trTileBuffer(TRcontext *tr, GLenum format, GLenum type, GLvoid *image)
|
||||
{
|
||||
if (!tr)
|
||||
return;
|
||||
|
||||
tr->TileFormat = format;
|
||||
tr->TileType = type;
|
||||
tr->TileBuffer = image;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void trImageSize(TRcontext *tr, GLint width, GLint height)
|
||||
{
|
||||
if (!tr)
|
||||
return;
|
||||
|
||||
tr->ImageWidth = width;
|
||||
tr->ImageHeight = height;
|
||||
Setup(tr);
|
||||
}
|
||||
|
||||
|
||||
void trImageBuffer(TRcontext *tr, GLenum format, GLenum type, GLvoid *image)
|
||||
{
|
||||
if (!tr)
|
||||
return;
|
||||
|
||||
tr->ImageFormat = format;
|
||||
tr->ImageType = type;
|
||||
tr->ImageBuffer = image;
|
||||
}
|
||||
|
||||
|
||||
GLint trGet(TRcontext *tr, TRenum param)
|
||||
{
|
||||
if (!tr)
|
||||
return 0;
|
||||
switch (param) {
|
||||
case TR_TILE_WIDTH:
|
||||
return tr->TileWidth;
|
||||
case TR_TILE_HEIGHT:
|
||||
return tr->TileHeight;
|
||||
case TR_TILE_BORDER:
|
||||
return tr->TileBorder;
|
||||
case TR_IMAGE_WIDTH:
|
||||
return tr->ImageWidth;
|
||||
case TR_IMAGE_HEIGHT:
|
||||
return tr->ImageHeight;
|
||||
case TR_ROWS:
|
||||
return tr->Rows;
|
||||
case TR_COLUMNS:
|
||||
return tr->Columns;
|
||||
case TR_CURRENT_ROW:
|
||||
if (tr->CurrentTile<0)
|
||||
return -1;
|
||||
else
|
||||
return tr->CurrentRow;
|
||||
case TR_CURRENT_COLUMN:
|
||||
if (tr->CurrentTile<0)
|
||||
return -1;
|
||||
else
|
||||
return tr->CurrentColumn;
|
||||
case TR_CURRENT_TILE_WIDTH:
|
||||
return tr->CurrentTileWidth;
|
||||
case TR_CURRENT_TILE_HEIGHT:
|
||||
return tr->CurrentTileHeight;
|
||||
case TR_ROW_ORDER:
|
||||
return (GLint) tr->RowOrder;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
GLdouble trGetD(TRcontext *tr, TRenum param)
|
||||
{
|
||||
if (!tr)
|
||||
return 0.0;
|
||||
switch (param) {
|
||||
case TR_LEFT:
|
||||
return tr->Left;
|
||||
case TR_RIGHT:
|
||||
return tr->Right;
|
||||
case TR_BOTTOM:
|
||||
return tr->Bottom;
|
||||
case TR_TOP:
|
||||
return tr->Top;
|
||||
case TR_NEAR:
|
||||
return tr->Near;
|
||||
case TR_FAR:
|
||||
return tr->Far;
|
||||
default:
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
void trRowOrder(TRcontext *tr, TRenum order)
|
||||
{
|
||||
if (!tr)
|
||||
return;
|
||||
|
||||
if (order==TR_TOP_TO_BOTTOM || order==TR_BOTTOM_TO_TOP)
|
||||
tr->RowOrder = order;
|
||||
}
|
||||
|
||||
|
||||
void trOrtho(TRcontext *tr,
|
||||
GLdouble left, GLdouble right,
|
||||
GLdouble bottom, GLdouble top,
|
||||
GLdouble zNear, GLdouble zFar)
|
||||
{
|
||||
if (!tr)
|
||||
return;
|
||||
|
||||
tr->Perspective = GL_FALSE;
|
||||
tr->Left = left;
|
||||
tr->Right = right;
|
||||
tr->Bottom = bottom;
|
||||
tr->Top = top;
|
||||
tr->Near = zNear;
|
||||
tr->Far = zFar;
|
||||
}
|
||||
|
||||
|
||||
void trFrustum(TRcontext *tr,
|
||||
GLdouble left, GLdouble right,
|
||||
GLdouble bottom, GLdouble top,
|
||||
GLdouble zNear, GLdouble zFar)
|
||||
{
|
||||
if (!tr)
|
||||
return;
|
||||
|
||||
tr->Perspective = GL_TRUE;
|
||||
tr->Left = left;
|
||||
tr->Right = right;
|
||||
tr->Bottom = bottom;
|
||||
tr->Top = top;
|
||||
tr->Near = zNear;
|
||||
tr->Far = zFar;
|
||||
}
|
||||
|
||||
|
||||
void trPerspective(TRcontext *tr,
|
||||
GLdouble fovy, GLdouble aspect,
|
||||
GLdouble zNear, GLdouble zFar )
|
||||
{
|
||||
GLdouble xmin, xmax, ymin, ymax;
|
||||
ymax = zNear * tan(fovy * 3.14159265 / 360.0);
|
||||
ymin = -ymax;
|
||||
xmin = ymin * aspect;
|
||||
xmax = ymax * aspect;
|
||||
trFrustum(tr, xmin, xmax, ymin, ymax, zNear, zFar);
|
||||
}
|
||||
|
||||
|
||||
void trBeginTile(TRcontext *tr)
|
||||
{
|
||||
GLint matrixMode;
|
||||
GLint tileWidth, tileHeight, border;
|
||||
GLdouble left, right, bottom, top;
|
||||
|
||||
if (!tr)
|
||||
return;
|
||||
|
||||
if (tr->CurrentTile <= 0) {
|
||||
Setup(tr);
|
||||
/* Save user's viewport, will be restored after last tile rendered */
|
||||
glGetIntegerv(GL_VIEWPORT, tr->ViewportSave);
|
||||
}
|
||||
|
||||
/* which tile (by row and column) we're about to render */
|
||||
if (tr->RowOrder==TR_BOTTOM_TO_TOP) {
|
||||
tr->CurrentRow = tr->CurrentTile / tr->Columns;
|
||||
tr->CurrentColumn = tr->CurrentTile % tr->Columns;
|
||||
}
|
||||
else if (tr->RowOrder==TR_TOP_TO_BOTTOM) {
|
||||
tr->CurrentRow = tr->Rows - (tr->CurrentTile / tr->Columns) - 1;
|
||||
tr->CurrentColumn = tr->CurrentTile % tr->Columns;
|
||||
}
|
||||
else {
|
||||
/* This should never happen */
|
||||
abort();
|
||||
}
|
||||
assert(tr->CurrentRow < tr->Rows);
|
||||
assert(tr->CurrentColumn < tr->Columns);
|
||||
|
||||
border = tr->TileBorder;
|
||||
|
||||
/* Compute actual size of this tile with border */
|
||||
if (tr->CurrentRow < tr->Rows-1)
|
||||
tileHeight = tr->TileHeight;
|
||||
else
|
||||
tileHeight = tr->ImageHeight - (tr->Rows-1) * (tr->TileHeightNB) + 2 * border;
|
||||
|
||||
if (tr->CurrentColumn < tr->Columns-1)
|
||||
tileWidth = tr->TileWidth;
|
||||
else
|
||||
tileWidth = tr->ImageWidth - (tr->Columns-1) * (tr->TileWidthNB) + 2 * border;
|
||||
|
||||
/* Save tile size, with border */
|
||||
tr->CurrentTileWidth = tileWidth;
|
||||
tr->CurrentTileHeight = tileHeight;
|
||||
|
||||
glViewport(0, 0, tileWidth, tileHeight); /* tile size including border */
|
||||
|
||||
/* save current matrix mode */
|
||||
glGetIntegerv(GL_MATRIX_MODE, &matrixMode);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
|
||||
/* compute projection parameters */
|
||||
left = tr->Left + (tr->Right - tr->Left)
|
||||
* (tr->CurrentColumn * tr->TileWidthNB - border) / tr->ImageWidth;
|
||||
right = left + (tr->Right - tr->Left) * tileWidth / tr->ImageWidth;
|
||||
bottom = tr->Bottom + (tr->Top - tr->Bottom)
|
||||
* (tr->CurrentRow * tr->TileHeightNB - border) / tr->ImageHeight;
|
||||
top = bottom + (tr->Top - tr->Bottom) * tileHeight / tr->ImageHeight;
|
||||
|
||||
ssgSetFrustum ( left, right, bottom, top, tr->Near, tr->Far );
|
||||
|
||||
/* restore user's matrix mode */
|
||||
glMatrixMode( (GLenum)matrixMode );
|
||||
}
|
||||
|
||||
|
||||
|
||||
int trEndTile(TRcontext *tr)
|
||||
{
|
||||
GLint prevRowLength, prevSkipRows, prevSkipPixels /*, prevAlignment */;
|
||||
|
||||
if (!tr)
|
||||
return 0;
|
||||
|
||||
assert(tr->CurrentTile>=0);
|
||||
|
||||
/* be sure OpenGL rendering is finished */
|
||||
glFlush();
|
||||
|
||||
/* save current glPixelStore values */
|
||||
glGetIntegerv(GL_PACK_ROW_LENGTH, &prevRowLength);
|
||||
glGetIntegerv(GL_PACK_SKIP_ROWS, &prevSkipRows);
|
||||
glGetIntegerv(GL_PACK_SKIP_PIXELS, &prevSkipPixels);
|
||||
/*glGetIntegerv(GL_PACK_ALIGNMENT, &prevAlignment);*/
|
||||
|
||||
if (tr->TileBuffer) {
|
||||
GLint srcX = tr->TileBorder;
|
||||
GLint srcY = tr->TileBorder;
|
||||
GLint srcWidth = tr->TileWidthNB;
|
||||
GLint srcHeight = tr->TileHeightNB;
|
||||
glReadPixels(srcX, srcY, srcWidth, srcHeight,
|
||||
tr->TileFormat, tr->TileType, tr->TileBuffer);
|
||||
}
|
||||
|
||||
if (tr->ImageBuffer) {
|
||||
GLint srcX = tr->TileBorder;
|
||||
GLint srcY = tr->TileBorder;
|
||||
GLint srcWidth = tr->CurrentTileWidth - 2 * tr->TileBorder;
|
||||
GLint srcHeight = tr->CurrentTileHeight - 2 * tr->TileBorder;
|
||||
GLint destX = tr->TileWidthNB * tr->CurrentColumn;
|
||||
GLint destY = tr->TileHeightNB * tr->CurrentRow;
|
||||
|
||||
/* setup pixel store for glReadPixels */
|
||||
glPixelStorei(GL_PACK_ROW_LENGTH, tr->ImageWidth);
|
||||
glPixelStorei(GL_PACK_SKIP_ROWS, destY);
|
||||
glPixelStorei(GL_PACK_SKIP_PIXELS, destX);
|
||||
/*glPixelStorei(GL_PACK_ALIGNMENT, 1);*/
|
||||
|
||||
/* read the tile into the final image */
|
||||
glReadPixels(srcX, srcY, srcWidth, srcHeight,
|
||||
tr->ImageFormat, tr->ImageType, tr->ImageBuffer);
|
||||
}
|
||||
|
||||
/* restore previous glPixelStore values */
|
||||
glPixelStorei(GL_PACK_ROW_LENGTH, prevRowLength);
|
||||
glPixelStorei(GL_PACK_SKIP_ROWS, prevSkipRows);
|
||||
glPixelStorei(GL_PACK_SKIP_PIXELS, prevSkipPixels);
|
||||
/*glPixelStorei(GL_PACK_ALIGNMENT, prevAlignment);*/
|
||||
|
||||
/* increment tile counter, return 1 if more tiles left to render */
|
||||
tr->CurrentTile++;
|
||||
if (tr->CurrentTile >= tr->Rows * tr->Columns) {
|
||||
/* restore user's viewport */
|
||||
glViewport(tr->ViewportSave[0], tr->ViewportSave[1],
|
||||
tr->ViewportSave[2], tr->ViewportSave[3]);
|
||||
tr->CurrentTile = -1; /* all done */
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Replacement for glRastePos3f() which avoids the problem with invalid
|
||||
* raster pos.
|
||||
*/
|
||||
void trRasterPos3f(TRcontext *tr, GLfloat x, GLfloat y, GLfloat z)
|
||||
{
|
||||
if (tr->CurrentTile<0) {
|
||||
/* not doing tile rendering right now. Let OpenGL do this. */
|
||||
glRasterPos3f(x, y, z);
|
||||
}
|
||||
else {
|
||||
GLdouble modelview[16], proj[16];
|
||||
GLint viewport[4];
|
||||
GLdouble winX, winY, winZ;
|
||||
|
||||
/* Get modelview, projection and viewport */
|
||||
glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
|
||||
glGetDoublev(GL_PROJECTION_MATRIX, proj);
|
||||
viewport[0] = 0;
|
||||
viewport[1] = 0;
|
||||
viewport[2] = tr->CurrentTileWidth;
|
||||
viewport[3] = tr->CurrentTileHeight;
|
||||
|
||||
/* Project object coord to window coordinate */
|
||||
if (gluProject(x, y, z, modelview, proj, viewport, &winX, &winY, &winZ)){
|
||||
|
||||
/* set raster pos to window coord (0,0) */
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glOrtho(0.0, tr->CurrentTileWidth,
|
||||
0.0, tr->CurrentTileHeight, 0.0, 1.0);
|
||||
glRasterPos3f(0.0, 0.0, -winZ);
|
||||
|
||||
/* Now use empty bitmap to adjust raster position to (winX,winY) */
|
||||
{
|
||||
GLubyte bitmap[1] = {0};
|
||||
glBitmap(1, 1, 0.0, 0.0, winX, winY, bitmap);
|
||||
}
|
||||
|
||||
/* restore original matrices */
|
||||
glPopMatrix(); /*proj*/
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (glGetError())
|
||||
printf("GL error!\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
170
simgear/screen/tr.h
Normal file
170
simgear/screen/tr.h
Normal file
@@ -0,0 +1,170 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* $Log$
|
||||
* Revision 1.1 2001/06/26 15:19:39 curt
|
||||
* Added tr.cxx / tr.h, Brian Paul's LGPL'd tiled rendering support libs for
|
||||
* rendering ultra high res "tiled" screen shots.
|
||||
*
|
||||
* Revision 1.5 1997/07/21 17:34:07 brianp
|
||||
* added tile borders, incremented version to 1.1
|
||||
*
|
||||
* Revision 1.4 1997/07/21 15:47:35 brianp
|
||||
* renamed all "near" and "far" variables
|
||||
*
|
||||
* Revision 1.3 1997/04/26 21:23:25 brianp
|
||||
* added trRasterPos3f function
|
||||
*
|
||||
* Revision 1.2 1997/04/19 23:26:10 brianp
|
||||
* many API changes
|
||||
*
|
||||
* Revision 1.1 1997/04/18 21:53:05 brianp
|
||||
* Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Tiled Rendering library
|
||||
* Version 1.1
|
||||
* Copyright (C) Brian Paul
|
||||
*
|
||||
*
|
||||
* This library allows one to render arbitrarily large images with OpenGL.
|
||||
* The basic idea is to break the image into tiles which are rendered one
|
||||
* at a time. The tiles are assembled together to form the final, large
|
||||
* image. Tiles and images can be of any size.
|
||||
*
|
||||
* Basic usage:
|
||||
*
|
||||
* 1. Allocate a tile rendering context:
|
||||
* TRcontext t = trNew();
|
||||
*
|
||||
* 2. Specify the final image buffer and tile size:
|
||||
* GLubyte image[W][H][4]
|
||||
* trImageSize(t, W, H);
|
||||
* trImageBuffer(t, GL_RGBA, GL_UNSIGNED_BYTE, (GLubyte *) image);
|
||||
*
|
||||
* 3. Setup your projection:
|
||||
* trFrustum(t, left, right, bottom top, near, far);
|
||||
* or
|
||||
* trOrtho(t, left, right, bottom top, near, far);
|
||||
* or
|
||||
* trPerspective(t, fovy, aspect, near, far);
|
||||
*
|
||||
* 4. Render the tiles:
|
||||
* do {
|
||||
* trBeginTile(t);
|
||||
* DrawMyScene();
|
||||
* } while (trEndTile(t));
|
||||
*
|
||||
* You provide the DrawMyScene() function which calls glClear() and
|
||||
* draws all your stuff.
|
||||
*
|
||||
* 5. The image array is now complete. Display it, write it to a file, etc.
|
||||
*
|
||||
* 6. Delete the tile rendering context when finished:
|
||||
* trDelete(t);
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TR_H
|
||||
#define TR_H
|
||||
|
||||
|
||||
#include <GL/gl.h>
|
||||
|
||||
|
||||
//#ifdef __cplusplus
|
||||
//extern "C" {
|
||||
//#endif
|
||||
|
||||
|
||||
#define TR_VERSION "1.1"
|
||||
#define TR_MAJOR_VERSION 1
|
||||
#define TR_MINOR_VERSION 1
|
||||
|
||||
|
||||
typedef struct _TRctx TRcontext;
|
||||
|
||||
|
||||
typedef enum {
|
||||
TR_TILE_WIDTH = 100,
|
||||
TR_TILE_HEIGHT,
|
||||
TR_TILE_BORDER,
|
||||
TR_IMAGE_WIDTH,
|
||||
TR_IMAGE_HEIGHT,
|
||||
TR_ROWS,
|
||||
TR_COLUMNS,
|
||||
TR_CURRENT_ROW,
|
||||
TR_CURRENT_COLUMN,
|
||||
TR_CURRENT_TILE_WIDTH,
|
||||
TR_CURRENT_TILE_HEIGHT,
|
||||
TR_ROW_ORDER,
|
||||
TR_TOP_TO_BOTTOM,
|
||||
TR_BOTTOM_TO_TOP,
|
||||
TR_LEFT,
|
||||
TR_RIGHT,
|
||||
TR_BOTTOM,
|
||||
TR_TOP,
|
||||
TR_NEAR,
|
||||
TR_FAR
|
||||
} TRenum;
|
||||
|
||||
|
||||
|
||||
extern TRcontext *trNew(void);
|
||||
|
||||
extern void trDelete(TRcontext *tr);
|
||||
|
||||
|
||||
extern void trTileSize(TRcontext *tr, GLint width, GLint height, GLint border);
|
||||
|
||||
extern void trTileBuffer(TRcontext *tr, GLenum format, GLenum type,
|
||||
GLvoid *image);
|
||||
|
||||
|
||||
extern void trImageSize(TRcontext *tr, GLint width, GLint height);
|
||||
|
||||
extern void trImageBuffer(TRcontext *tr, GLenum format, GLenum type,
|
||||
GLvoid *image);
|
||||
|
||||
|
||||
extern void trRowOrder(TRcontext *tr, TRenum order);
|
||||
|
||||
|
||||
extern GLint trGet(TRcontext *tr, TRenum param);
|
||||
extern GLdouble trGetD(TRcontext *tr, TRenum param);
|
||||
|
||||
|
||||
extern void trOrtho(TRcontext *tr,
|
||||
GLdouble left, GLdouble right,
|
||||
GLdouble bottom, GLdouble top,
|
||||
GLdouble zNear, GLdouble zFar);
|
||||
|
||||
extern void trFrustum(TRcontext *tr,
|
||||
GLdouble left, GLdouble right,
|
||||
GLdouble bottom, GLdouble top,
|
||||
GLdouble zNear, GLdouble zFar);
|
||||
|
||||
extern void trPerspective(TRcontext *tr,
|
||||
GLdouble fovy, GLdouble aspect,
|
||||
GLdouble zNear, GLdouble zFar );
|
||||
|
||||
|
||||
extern void trBeginTile(TRcontext *tr);
|
||||
|
||||
extern int trEndTile(TRcontext *tr);
|
||||
|
||||
|
||||
extern void trRasterPos3f(TRcontext *tr, GLfloat x, GLfloat y, GLfloat z);
|
||||
|
||||
|
||||
|
||||
//#ifdef __cplusplus
|
||||
//}
|
||||
//#endif
|
||||
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user