Compare commits
220 Commits
RELEASE_0_
...
RELEASE_0_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9fefaef31e | ||
|
|
689a942f19 | ||
|
|
cb9654f1f4 | ||
|
|
a8f8cef484 | ||
|
|
6cf51c3222 | ||
|
|
0d8ae0cabe | ||
|
|
49d6f93d8b | ||
|
|
5173d709e0 | ||
|
|
778c3ab25c | ||
|
|
aa17d9ac9a | ||
|
|
ffe1d9485e | ||
|
|
71abebe837 | ||
|
|
ca07b64af0 | ||
|
|
2fde2ce581 | ||
|
|
cb0da2ca5e | ||
|
|
c0422839b9 | ||
|
|
862b884f02 | ||
|
|
708e745cfd | ||
|
|
bb882a1239 | ||
|
|
6b2bf2fa8e | ||
|
|
2640b43355 | ||
|
|
d201e9b5c5 | ||
|
|
8f0f79506c | ||
|
|
121d2f92cb | ||
|
|
87e641aeda | ||
|
|
27403e2fef | ||
|
|
b5ceef5e68 | ||
|
|
5d68470c95 | ||
|
|
e176b4d8b6 | ||
|
|
218821f694 | ||
|
|
a8f4a61dc2 | ||
|
|
9221604424 | ||
|
|
5bddbd0ca9 | ||
|
|
f8dde93e05 | ||
|
|
489b562232 | ||
|
|
294a0dde63 | ||
|
|
53fbb98d4f | ||
|
|
8a2c08a0c1 | ||
|
|
b15b40ea10 | ||
|
|
0c865f540f | ||
|
|
ef4a92859c | ||
|
|
2a7b06f648 | ||
|
|
6c2ca22b3f | ||
|
|
592690f8f2 | ||
|
|
1eb87e7c73 | ||
|
|
a0e40c1fc1 | ||
|
|
2c920ae1df | ||
|
|
bbde3b36bf | ||
|
|
88a016c516 | ||
|
|
22d4058564 | ||
|
|
79e6c529ea | ||
|
|
7b22b8cd92 | ||
|
|
bc2ae82e81 | ||
|
|
764f4037b0 | ||
|
|
a60454a786 | ||
|
|
d136ad3e57 | ||
|
|
739588f9c3 | ||
|
|
505de4703b | ||
|
|
236a1f2a2d | ||
|
|
91efc5ad87 | ||
|
|
123c816048 | ||
|
|
fab6d05157 | ||
|
|
3240464c7c | ||
|
|
a2ffd27b7c | ||
|
|
af6c921757 | ||
|
|
180e2188ba | ||
|
|
23fbd5919f | ||
|
|
8aec98017a | ||
|
|
9b4fe7d92d | ||
|
|
99f11a01fc | ||
|
|
b3eacb19f6 | ||
|
|
f12840a72e | ||
|
|
f472bc563d | ||
|
|
3e05a5780d | ||
|
|
2454f8d269 | ||
|
|
b4a913e339 | ||
|
|
b82aef65e5 | ||
|
|
3730ce404f | ||
|
|
d7748704d7 | ||
|
|
1690f5475d | ||
|
|
a644bd2b03 | ||
|
|
62ca2e0227 | ||
|
|
d56289f897 | ||
|
|
aa02e72829 | ||
|
|
a878570a8d | ||
|
|
54352225f1 | ||
|
|
0b7d4c8c1e | ||
|
|
2091bf2144 | ||
|
|
0fec7b2599 | ||
|
|
74d314558c | ||
|
|
4fb45c4783 | ||
|
|
6816ecb3ea | ||
|
|
6766825159 | ||
|
|
3e63d6ca5d | ||
|
|
6ca9596807 | ||
|
|
5695fc84e1 | ||
|
|
2aea6362db | ||
|
|
bb70329c25 | ||
|
|
75bc07dc42 | ||
|
|
bac27f1ce3 | ||
|
|
787591dd79 | ||
|
|
c7c353df05 | ||
|
|
8470a9eda6 | ||
|
|
c5adb85741 | ||
|
|
2f9619f02a | ||
|
|
11cab90ce2 | ||
|
|
9ae48c2d7d | ||
|
|
00fc8205da | ||
|
|
62e85640da | ||
|
|
1b99b2a25d | ||
|
|
605ad52197 | ||
|
|
af80c5e018 | ||
|
|
18ac42b2e4 | ||
|
|
9ea57fcc30 | ||
|
|
7c27474164 | ||
|
|
afdee14332 | ||
|
|
7f5f12d37a | ||
|
|
cea0df71f8 | ||
|
|
aef484d5fc | ||
|
|
dacc051a57 | ||
|
|
e111f530c3 | ||
|
|
c00ca055bc | ||
|
|
305589cd01 | ||
|
|
6610244275 | ||
|
|
e462e64d42 | ||
|
|
39521df546 | ||
|
|
6dd8a1525c | ||
|
|
fca7a8fa47 | ||
|
|
1175179da1 | ||
|
|
06ab581edb | ||
|
|
dbcecbd3b8 | ||
|
|
4205c0a38d | ||
|
|
a76904c314 | ||
|
|
529ca14534 | ||
|
|
7423077f95 | ||
|
|
f116ee7802 | ||
|
|
09cf8c001e | ||
|
|
cfe0e18e4e | ||
|
|
2caad4a27b | ||
|
|
b5e7938ebe | ||
|
|
bd3e280fe5 | ||
|
|
39164d1438 | ||
|
|
a9c068ae3b | ||
|
|
6c7856549b | ||
|
|
d85cbc7b61 | ||
|
|
d8cbac4576 | ||
|
|
c0874a000e | ||
|
|
e317a39b2d | ||
|
|
61d4bd8adf | ||
|
|
a8deedaa66 | ||
|
|
15790ef4b4 | ||
|
|
8cf618ea75 | ||
|
|
5a81c9ecf0 | ||
|
|
4ccc2b3cfc | ||
|
|
ff8845de52 | ||
|
|
e4d4a2d8eb | ||
|
|
5a2a23cc2d | ||
|
|
8a233ddfbb | ||
|
|
2b40dc133d | ||
|
|
b26263c62d | ||
|
|
2df317eb49 | ||
|
|
5eef0e61ba | ||
|
|
021558d6dd | ||
|
|
7a6cab8381 | ||
|
|
1fcb70e553 | ||
|
|
712bbc9085 | ||
|
|
7b2370d608 | ||
|
|
98f398c99a | ||
|
|
e5efd5bf69 | ||
|
|
9d504a9e19 | ||
|
|
e96e09d112 | ||
|
|
28a6ec8065 | ||
|
|
875560b8dc | ||
|
|
fa360360cb | ||
|
|
e543b5228c | ||
|
|
63ea6cd15a | ||
|
|
79a773d25c | ||
|
|
dcc537e040 | ||
|
|
37488d0f7e | ||
|
|
aa645019e9 | ||
|
|
6179ec5319 | ||
|
|
331f91ba43 | ||
|
|
a50203dfec | ||
|
|
b7eab24f14 | ||
|
|
d824ffd02b | ||
|
|
238c6f7c88 | ||
|
|
0dd244fb0c | ||
|
|
61a8afa06a | ||
|
|
ed49eadb6a | ||
|
|
ecf19f8af4 | ||
|
|
9d5eb462c9 | ||
|
|
1088c5fa57 | ||
|
|
ad2bd3db0f | ||
|
|
abbcf855c4 | ||
|
|
83e648b7d6 | ||
|
|
89d049ff73 | ||
|
|
ac3a2bce72 | ||
|
|
ad20c2d242 | ||
|
|
6c9aa9527d | ||
|
|
7ad1e2be73 | ||
|
|
604f038cfb | ||
|
|
b185b1a4d9 | ||
|
|
89a65000a5 | ||
|
|
9c83903c2a | ||
|
|
68af57b759 | ||
|
|
9c4b4abb50 | ||
|
|
233ffb3b10 | ||
|
|
34e2bac4d0 | ||
|
|
6d4c38a3c8 | ||
|
|
b6ec5707e8 | ||
|
|
68d3b7b20c | ||
|
|
b84b36d885 | ||
|
|
f43e375d62 | ||
|
|
ab67fa2c15 | ||
|
|
7aff56c284 | ||
|
|
c13dc3a829 | ||
|
|
baf89c9d63 | ||
|
|
a8b4d21a65 | ||
|
|
6c20288ff1 | ||
|
|
935d4f3bda |
6
Makefile.am
Normal file
6
Makefile.am
Normal file
@@ -0,0 +1,6 @@
|
||||
EXTRA_DIST = mksymlinks.sh
|
||||
|
||||
dist-hook:
|
||||
tar cf - src/metar | (cd $(distdir); tar xvf -)
|
||||
|
||||
SUBDIRS = src
|
||||
1
VERSION.in
Normal file
1
VERSION.in
Normal file
@@ -0,0 +1 @@
|
||||
@VERSION@
|
||||
324
acconfig.h
Normal file
324
acconfig.h
Normal file
@@ -0,0 +1,324 @@
|
||||
/* acconfig.h
|
||||
This file is in the public domain.
|
||||
|
||||
Descriptive text for the C preprocessor macros that
|
||||
the distributed Autoconf macros can define.
|
||||
No software package will use all of them; autoheader copies the ones
|
||||
your configure.in uses into your configuration header file templates.
|
||||
|
||||
The entries are in sort -df order: alphabetical, case insensitive,
|
||||
ignoring punctuation (such as underscores). Although this order
|
||||
can split up related entries, it makes it easier to check whether
|
||||
a given entry is in the file.
|
||||
|
||||
Leave the following blank line there!! Autoheader needs it. */
|
||||
|
||||
|
||||
/* Define if on AIX 3.
|
||||
System headers sometimes define this.
|
||||
We just want to avoid a redefinition error message. */
|
||||
#ifndef _ALL_SOURCE
|
||||
#undef _ALL_SOURCE
|
||||
#endif
|
||||
|
||||
/* Define if using alloca.c. */
|
||||
#undef C_ALLOCA
|
||||
|
||||
/* Define if type char is unsigned and you are not using gcc. */
|
||||
#ifndef __CHAR_UNSIGNED__
|
||||
#undef __CHAR_UNSIGNED__
|
||||
#endif
|
||||
|
||||
/* Define if the closedir function returns void instead of int. */
|
||||
#undef CLOSEDIR_VOID
|
||||
|
||||
/* Define to empty if the keyword does not work. */
|
||||
#undef const
|
||||
|
||||
/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
|
||||
This function is required for alloca.c support on those systems. */
|
||||
#undef CRAY_STACKSEG_END
|
||||
|
||||
/* Define for DGUX with <sys/dg_sys_info.h>. */
|
||||
#undef DGUX
|
||||
|
||||
/* Define if you have <dirent.h>. */
|
||||
#undef DIRENT
|
||||
|
||||
/* Define to enable audio support */
|
||||
#undef ENABLE_AUDIO_SUPPORT
|
||||
|
||||
/* Define to enable GLUT joystick support (limited to 3 axes) */
|
||||
#undef ENABLE_GLUT_JOYSTICK
|
||||
|
||||
/* Define to enable plib joystick support (recommended) */
|
||||
#undef ENABLE_PLIB_JOYSTICK
|
||||
|
||||
/* Define to eliminate all trace of debugging messages such as for a
|
||||
release build */
|
||||
#undef FG_NDEBUG
|
||||
|
||||
/* Define to include Oliver's networking support */
|
||||
#undef FG_NETWORK_OLK
|
||||
|
||||
/* Define to avoid Christian's new weather code */
|
||||
#undef FG_OLD_WEATHER
|
||||
|
||||
/* Define if we are building FGFS (should always be defined) */
|
||||
#undef FGFS
|
||||
|
||||
/* Define to enable 3dfx/glide render in a window hack under unix.
|
||||
This probably won't work under windows. */
|
||||
#undef XMESA
|
||||
#undef FX
|
||||
|
||||
/* Define to the type of elements in the array set by `getgroups'.
|
||||
Usually this is either `int' or `gid_t'. */
|
||||
#undef GETGROUPS_T
|
||||
|
||||
/* Define if the `getloadavg' function needs to be run setuid or setgid. */
|
||||
#undef GETLOADAVG_PRIVILEGED
|
||||
|
||||
/* Define if the `getpgrp' function takes no argument. */
|
||||
#undef GETPGRP_VOID
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
#undef gid_t
|
||||
|
||||
/* Define if you have alloca, as a function or macro. */
|
||||
#undef HAVE_ALLOCA
|
||||
|
||||
/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
|
||||
#undef HAVE_ALLOCA_H
|
||||
|
||||
/* Define if you external variables daylight. */
|
||||
#undef HAVE_DAYLIGHT
|
||||
|
||||
/* Define if you don't have vprintf but do have _doprnt. */
|
||||
#undef HAVE_DOPRNT
|
||||
|
||||
/* Define if your system has a working fnmatch function. */
|
||||
#undef HAVE_FNMATCH
|
||||
|
||||
/* Define if your system has its own `getloadavg' function. */
|
||||
#undef HAVE_GETLOADAVG
|
||||
|
||||
/* Define if you have getrusage() */
|
||||
#undef HAVE_GETRUSAGE
|
||||
|
||||
/* Define if you have the getmntent function. */
|
||||
#undef HAVE_GETMNTENT
|
||||
|
||||
/* Define if you have the gpc library and headers installed. */
|
||||
#undef HAVE_GPC_H
|
||||
|
||||
/* Define if the `long double' type works. */
|
||||
#undef HAVE_LONG_DOUBLE
|
||||
|
||||
/* Define if you support file names longer than 14 characters. */
|
||||
#undef HAVE_LONG_FILE_NAMES
|
||||
|
||||
/* Define if you have a working `mmap' system call. */
|
||||
#undef HAVE_MMAP
|
||||
|
||||
/* Define if system calls automatically restart after interruption
|
||||
by a signal. */
|
||||
#undef HAVE_RESTARTABLE_SYSCALLS
|
||||
|
||||
/* Define if you have rint() which rounds to closest int but returns
|
||||
result as a double data type. */
|
||||
#undef HAVE_RINT
|
||||
|
||||
/* Define if your struct stat has st_blksize. */
|
||||
#undef HAVE_ST_BLKSIZE
|
||||
|
||||
/* Define if your struct stat has st_blocks. */
|
||||
#undef HAVE_ST_BLOCKS
|
||||
|
||||
/* Define if you have the strcoll function and it is properly defined. */
|
||||
#undef HAVE_STRCOLL
|
||||
|
||||
/* Define if your struct stat has st_rdev. */
|
||||
#undef HAVE_ST_RDEV
|
||||
|
||||
/* Define if you have the strftime function. */
|
||||
#undef HAVE_STRFTIME
|
||||
|
||||
/* Define if you have <sys/param.h> */
|
||||
#undef HAVE_SYS_PARAM_H
|
||||
|
||||
/* Define if you have <sys/stat.h> that is POSIX.1 compatible. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
|
||||
#undef HAVE_SYS_WAIT_H
|
||||
|
||||
/* Define if you have timegm() */
|
||||
#undef HAVE_TIMEGM
|
||||
|
||||
/* Define if you external variables timezone. */
|
||||
#undef HAVE_TIMEZONE
|
||||
|
||||
/* Define if your struct tm has tm_zone. */
|
||||
#undef HAVE_TM_ZONE
|
||||
|
||||
/* Define if you don't have tm_zone but do have the external array
|
||||
tzname. */
|
||||
#undef HAVE_TZNAME
|
||||
|
||||
/* Define if you have <unistd.h>. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define if utime(file, NULL) sets file's timestamp to the present. */
|
||||
#undef HAVE_UTIME_NULL
|
||||
|
||||
/* Define if you have <vfork.h>. */
|
||||
#undef HAVE_VFORK_H
|
||||
|
||||
/* Define if you have the vprintf function. */
|
||||
#undef HAVE_VPRINTF
|
||||
|
||||
/* Define if you have the wait3 system call. */
|
||||
#undef HAVE_WAIT3
|
||||
|
||||
/* Define as __inline if that's what the C compiler calls it. */
|
||||
#undef inline
|
||||
|
||||
/* Define if int is 16 bits instead of 32. */
|
||||
#undef INT_16_BITS
|
||||
|
||||
/* Define if long int is 64 bits. */
|
||||
#undef LONG_64_BITS
|
||||
|
||||
/* Define if major, minor, and makedev are declared in <mkdev.h>. */
|
||||
#undef MAJOR_IN_MKDEV
|
||||
|
||||
/* Define if major, minor, and makedev are declared in <sysmacros.h>. */
|
||||
#undef MAJOR_IN_SYSMACROS
|
||||
|
||||
/* Define if on MINIX. */
|
||||
#undef _MINIX
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
#undef mode_t
|
||||
|
||||
/* Define if you don't have <dirent.h>, but have <ndir.h>. */
|
||||
#undef NDIR
|
||||
|
||||
/* Define if you have <memory.h>, and <string.h> doesn't declare the
|
||||
mem* functions. */
|
||||
#undef NEED_MEMORY_H
|
||||
|
||||
/* Define if your struct nlist has an n_un member. */
|
||||
#undef NLIST_NAME_UNION
|
||||
|
||||
/* Define if you have <nlist.h>. */
|
||||
#undef NLIST_STRUCT
|
||||
|
||||
/* Define if your C compiler doesn't accept -c and -o together. */
|
||||
#undef NO_MINUS_C_MINUS_O
|
||||
|
||||
/* Define to `long' if <sys/types.h> doesn't define. */
|
||||
#undef off_t
|
||||
|
||||
/* Define to package name */
|
||||
#undef PACKAGE
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
#undef pid_t
|
||||
|
||||
/* Define if the system does not provide POSIX.1 features except
|
||||
with this defined. */
|
||||
#undef _POSIX_1_SOURCE
|
||||
|
||||
/* Define if you need to in order for stat and other things to work. */
|
||||
#undef _POSIX_SOURCE
|
||||
|
||||
/* Define as the return type of signal handlers (int or void). */
|
||||
#undef RETSIGTYPE
|
||||
|
||||
/* Define if the `setpgrp' function takes no argument. */
|
||||
#undef SETPGRP_VOID
|
||||
|
||||
/* Define if the setvbuf function takes the buffering type as its second
|
||||
argument and the buffer pointer as the third, as on System V
|
||||
before release 3. */
|
||||
#undef SETVBUF_REVERSED
|
||||
|
||||
/* Define to `unsigned' if <sys/types.h> doesn't define. */
|
||||
#undef size_t
|
||||
|
||||
/* If using the C implementation of alloca, define if you know the
|
||||
direction of stack growth for your system; otherwise it will be
|
||||
automatically deduced at run-time.
|
||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||
STACK_DIRECTION = 0 => direction of growth unknown
|
||||
*/
|
||||
#undef STACK_DIRECTION
|
||||
|
||||
/* Define if the `S_IS*' macros in <sys/stat.h> do not work properly. */
|
||||
#undef STAT_MACROS_BROKEN
|
||||
|
||||
/* Define if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Define on System V Release 4. */
|
||||
#undef SVR4
|
||||
|
||||
/* Define if you don't have <dirent.h>, but have <sys/dir.h>. */
|
||||
#undef SYSDIR
|
||||
|
||||
/* Define if you don't have <dirent.h>, but have <sys/ndir.h>. */
|
||||
#undef SYSNDIR
|
||||
|
||||
/* Define if `sys_siglist' is declared by <signal.h>. */
|
||||
#undef SYS_SIGLIST_DECLARED
|
||||
|
||||
/* Define if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#undef TIME_WITH_SYS_TIME
|
||||
|
||||
/* Define if your <sys/time.h> declares struct tm. */
|
||||
#undef TM_IN_SYS_TIME
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
#undef uid_t
|
||||
|
||||
/* Define for Encore UMAX. */
|
||||
#undef UMAX
|
||||
|
||||
/* Define for Encore UMAX 4.3 that has <inq_status/cpustats.h>
|
||||
instead of <sys/cpustats.h>. */
|
||||
#undef UMAX4_3
|
||||
|
||||
/* Define if you do not have <strings.h>, index, bzero, etc.. */
|
||||
#undef USG
|
||||
|
||||
/* Define to version number */
|
||||
#undef VERSION
|
||||
|
||||
/* Define vfork as fork if vfork does not work. */
|
||||
#undef vfork
|
||||
|
||||
/* Define if the closedir function returns void instead of int. */
|
||||
#undef VOID_CLOSEDIR
|
||||
|
||||
/* Define if compiling on a Winbloze (95, NT, etc.) platform */
|
||||
#undef WIN32
|
||||
|
||||
/* Define if your processor stores words with the most significant
|
||||
byte first (like Motorola and SPARC, unlike Intel and VAX). */
|
||||
#undef WORDS_BIGENDIAN
|
||||
|
||||
/* Define if the X Window System is missing or not being used. */
|
||||
#undef X_DISPLAY_MISSING
|
||||
|
||||
/* Define if lex declares yytext as a char * by default, not a char[]. */
|
||||
#undef YYTEXT_POINTER
|
||||
|
||||
|
||||
/* Leave that blank line there!! Autoheader needs it.
|
||||
If you're adding to this file, keep in mind:
|
||||
The entries are in sort -df order: alphabetical, case insensitive,
|
||||
ignoring punctuation (such as underscores). */
|
||||
|
||||
149
aclocal.m4
vendored
Normal file
149
aclocal.m4
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
dnl aclocal.m4 generated automatically by aclocal 1.3
|
||||
|
||||
dnl Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
dnl This Makefile.in is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
dnl with or without modifications, as long as this notice is preserved.
|
||||
|
||||
dnl This program is distributed in the hope that it will be useful,
|
||||
dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
dnl PARTICULAR PURPOSE.
|
||||
|
||||
# Do all the work for Automake. This macro actually does too much --
|
||||
# some checks are only needed if your package does certain things.
|
||||
# But this isn't really a big deal.
|
||||
|
||||
# serial 1
|
||||
|
||||
dnl Usage:
|
||||
dnl AM_INIT_AUTOMAKE(package,version, [no-define])
|
||||
|
||||
AC_DEFUN(AM_INIT_AUTOMAKE,
|
||||
[AC_REQUIRE([AM_PROG_INSTALL])
|
||||
PACKAGE=[$1]
|
||||
AC_SUBST(PACKAGE)
|
||||
VERSION=[$2]
|
||||
AC_SUBST(VERSION)
|
||||
dnl test to see if srcdir already configured
|
||||
if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
|
||||
AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
|
||||
fi
|
||||
ifelse([$3],,
|
||||
AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE")
|
||||
AC_DEFINE_UNQUOTED(VERSION, "$VERSION"))
|
||||
AC_REQUIRE([AM_SANITY_CHECK])
|
||||
AC_REQUIRE([AC_ARG_PROGRAM])
|
||||
dnl FIXME This is truly gross.
|
||||
missing_dir=`cd $ac_aux_dir && pwd`
|
||||
AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
|
||||
AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
|
||||
AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
|
||||
AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
|
||||
AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
|
||||
AC_REQUIRE([AC_PROG_MAKE_SET])])
|
||||
|
||||
|
||||
# serial 1
|
||||
|
||||
AC_DEFUN(AM_PROG_INSTALL,
|
||||
[AC_REQUIRE([AC_PROG_INSTALL])
|
||||
test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
|
||||
AC_SUBST(INSTALL_SCRIPT)dnl
|
||||
])
|
||||
|
||||
#
|
||||
# Check to make sure that the build environment is sane.
|
||||
#
|
||||
|
||||
AC_DEFUN(AM_SANITY_CHECK,
|
||||
[AC_MSG_CHECKING([whether build environment is sane])
|
||||
# Just in case
|
||||
sleep 1
|
||||
echo timestamp > conftestfile
|
||||
# Do `set' in a subshell so we don't clobber the current shell's
|
||||
# arguments. Must try -L first in case configure is actually a
|
||||
# symlink; some systems play weird games with the mod time of symlinks
|
||||
# (eg FreeBSD returns the mod time of the symlink's containing
|
||||
# directory).
|
||||
if (
|
||||
set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
|
||||
if test "[$]*" = "X"; then
|
||||
# -L didn't work.
|
||||
set X `ls -t $srcdir/configure conftestfile`
|
||||
fi
|
||||
if test "[$]*" != "X $srcdir/configure conftestfile" \
|
||||
&& test "[$]*" != "X conftestfile $srcdir/configure"; then
|
||||
|
||||
# If neither matched, then we have a broken ls. This can happen
|
||||
# if, for instance, CONFIG_SHELL is bash and it inherits a
|
||||
# broken ls alias from the environment. This has actually
|
||||
# happened. Such a system could not be considered "sane".
|
||||
AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
|
||||
alias in your environment])
|
||||
fi
|
||||
|
||||
test "[$]2" = conftestfile
|
||||
)
|
||||
then
|
||||
# Ok.
|
||||
:
|
||||
else
|
||||
AC_MSG_ERROR([newly created file is older than distributed files!
|
||||
Check your system clock])
|
||||
fi
|
||||
rm -f conftest*
|
||||
AC_MSG_RESULT(yes)])
|
||||
|
||||
dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
|
||||
dnl The program must properly implement --version.
|
||||
AC_DEFUN(AM_MISSING_PROG,
|
||||
[AC_MSG_CHECKING(for working $2)
|
||||
# Run test in a subshell; some versions of sh will print an error if
|
||||
# an executable is not found, even if stderr is redirected.
|
||||
# Redirect stdin to placate older versions of autoconf. Sigh.
|
||||
if ($2 --version) < /dev/null > /dev/null 2>&1; then
|
||||
$1=$2
|
||||
AC_MSG_RESULT(found)
|
||||
else
|
||||
$1="$3/missing $2"
|
||||
AC_MSG_RESULT(missing)
|
||||
fi
|
||||
AC_SUBST($1)])
|
||||
|
||||
# Define a conditional.
|
||||
|
||||
AC_DEFUN(AM_CONDITIONAL,
|
||||
[AC_SUBST($1_TRUE)
|
||||
AC_SUBST($1_FALSE)
|
||||
if $2; then
|
||||
$1_TRUE=
|
||||
$1_FALSE='#'
|
||||
else
|
||||
$1_TRUE='#'
|
||||
$1_FALSE=
|
||||
fi])
|
||||
|
||||
# Like AC_CONFIG_HEADER, but automatically create stamp file.
|
||||
|
||||
AC_DEFUN(AM_CONFIG_HEADER,
|
||||
[AC_PREREQ([2.12])
|
||||
AC_CONFIG_HEADER([$1])
|
||||
dnl When config.status generates a header, we must update the stamp-h file.
|
||||
dnl This file resides in the same directory as the config header
|
||||
dnl that is generated. We must strip everything past the first ":",
|
||||
dnl and everything past the last "/".
|
||||
AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl
|
||||
ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>,
|
||||
<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>,
|
||||
<<am_indx=1
|
||||
for am_file in <<$1>>; do
|
||||
case " <<$>>CONFIG_HEADERS " in
|
||||
*" <<$>>am_file "*<<)>>
|
||||
echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx
|
||||
;;
|
||||
esac
|
||||
am_indx=`expr "<<$>>am_indx" + 1`
|
||||
done<<>>dnl>>)
|
||||
changequote([,]))])
|
||||
|
||||
394
acsite.m4
Normal file
394
acsite.m4
Normal file
@@ -0,0 +1,394 @@
|
||||
dnl
|
||||
dnl originally from ncftp 2.3.0
|
||||
dnl added wi_EXTRA_PDIR and wi_ANSI_C
|
||||
dnl $Id$
|
||||
dnl
|
||||
AC_DEFUN(wi_EXTRA_IDIR, [
|
||||
incdir="$1"
|
||||
if test -r $incdir ; then
|
||||
case "$CPPFLAGS" in
|
||||
*-I${incdir}*)
|
||||
# echo " + already had $incdir" 1>&6
|
||||
;;
|
||||
*)
|
||||
if test "$CPPFLAGS" = "" ; then
|
||||
CPPFLAGS="-I$incdir"
|
||||
else
|
||||
CPPFLAGS="$CPPFLAGS -I$incdir"
|
||||
fi
|
||||
echo " + found $incdir" 1>&6
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
])
|
||||
dnl
|
||||
dnl
|
||||
dnl
|
||||
dnl
|
||||
AC_DEFUN(wi_EXTRA_LDIR, [
|
||||
mylibdir="$1"
|
||||
if test -r $mylibdir ; then
|
||||
case "$LDFLAGS" in
|
||||
*-L${mylibdir}*)
|
||||
# echo " + already had $mylibdir" 1>&6
|
||||
;;
|
||||
*)
|
||||
if test "$LDFLAGS" = "" ; then
|
||||
LDFLAGS="-L$mylibdir"
|
||||
else
|
||||
LDFLAGS="$LDFLAGS -L$mylibdir"
|
||||
fi
|
||||
echo " + found $mylibdir" 1>&6
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
])
|
||||
dnl
|
||||
dnl __FP__
|
||||
dnl
|
||||
dnl
|
||||
AC_DEFUN(wi_EXTRA_PDIR, [
|
||||
progdir="$1"
|
||||
if test -r $progdir ; then
|
||||
case "$PATH" in
|
||||
*:${progdir}*)
|
||||
# echo " + already had $progdir" 1>&6
|
||||
;;
|
||||
*${progdir}:*)
|
||||
# echo " + already had $progdir" 1>&6
|
||||
;;
|
||||
*)
|
||||
if test "$PATH" = "" ; then
|
||||
PATH="$progdir"
|
||||
else
|
||||
PATH="$PATH:$progdir"
|
||||
fi
|
||||
echo " + found $progdir" 1>&6
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
])
|
||||
dnl
|
||||
dnl
|
||||
dnl If you want to also look for include and lib subdirectories in the
|
||||
dnl $HOME tree, you supply "yes" as the first argument to this macro.
|
||||
dnl
|
||||
dnl If you want to look for subdirectories in include/lib directories,
|
||||
dnl you pass the names in argument 3, otherwise pass a dash.
|
||||
dnl
|
||||
AC_DEFUN(wi_EXTRA_DIRS, [echo "checking for extra include and lib directories..." 1>&6
|
||||
ifelse([$1], yes, [dnl
|
||||
b1=`cd .. ; pwd`
|
||||
b2=`cd ../.. ; pwd`
|
||||
exdirs="$HOME $j $b1 $b2 $prefix $2"
|
||||
],[dnl
|
||||
exdirs="$prefix $2"
|
||||
])
|
||||
subexdirs="$3"
|
||||
if test "$subexdirs" = "" ; then
|
||||
subexdirs="-"
|
||||
fi
|
||||
for subexdir in $subexdirs ; do
|
||||
if test "$subexdir" = "-" ; then
|
||||
subexdir=""
|
||||
else
|
||||
subexdir="/$subexdir"
|
||||
fi
|
||||
for exdir in $exdirs ; do
|
||||
if test "$exdir" != "/usr" || test "$subexdir" != ""; then
|
||||
incdir="${exdir}/include${subexdir}"
|
||||
wi_EXTRA_IDIR($incdir)
|
||||
|
||||
mylibdir="${exdir}/lib${subexdir}"
|
||||
wi_EXTRA_LDIR($mylibdir)
|
||||
|
||||
progdir="${exdir}/bin${subexdirr}"
|
||||
wi_EXTRA_PDIR($progdir)
|
||||
fi
|
||||
done
|
||||
done
|
||||
])
|
||||
dnl
|
||||
dnl
|
||||
dnl
|
||||
AC_DEFUN(wi_HPUX_CFLAGS,
|
||||
[AC_MSG_CHECKING(if HP-UX ansi C compiler flags are needed)
|
||||
AC_REQUIRE([AC_PROG_CC])
|
||||
os=`uname -s | tr '[A-Z]' '[a-z]'`
|
||||
ac_cv_hpux_flags=no
|
||||
if test "$os" = hp-ux ; then
|
||||
if test "$ac_cv_prog_gcc" = yes ; then
|
||||
if test "$CFLAGS" != "" ; then
|
||||
# Shouldn't be in there.
|
||||
CFLAGS=`echo "$CFLAGS" | sed 's/-Aa//g'`
|
||||
fi
|
||||
else
|
||||
# If you're not using gcc, then you better have a cc/c89
|
||||
# that is usable. If you have the barebones compiler, it
|
||||
# won't work. The good compiler uses -Aa for the ANSI
|
||||
# compatible stuff.
|
||||
x=`echo $CFLAGS | grep 'Aa' 2>/dev/null`
|
||||
if test "$x" = "" ; then
|
||||
CFLAGS="$CFLAGS -Aa"
|
||||
fi
|
||||
ac_cv_hpux_flags=yes
|
||||
fi
|
||||
# Also add _HPUX_SOURCE to get the extended namespace.
|
||||
x=`echo $CFLAGS | grep '_HPUX_SOURCE' 2>/dev/null`
|
||||
if test "$x" = "" ; then
|
||||
CFLAGS="$CFLAGS -D_HPUX_SOURCE"
|
||||
fi
|
||||
fi
|
||||
AC_MSG_RESULT($ac_cv_hpux_flags)
|
||||
])
|
||||
dnl
|
||||
dnl
|
||||
dnl
|
||||
AC_DEFUN(wi_CFLAGS, [AC_REQUIRE([AC_PROG_CC])
|
||||
wi_HPUX_CFLAGS
|
||||
if test "$CFLAGS" = "" ; then
|
||||
CFLAGS="-O"
|
||||
elif test "$ac_cv_prog_gcc" = "yes" ; then
|
||||
case "$CFLAGS" in
|
||||
*"-g -O"*)
|
||||
#echo "using -g as default gcc CFLAGS" 1>&6
|
||||
CFLAGS=`echo $CFLAGS | sed 's/-g\ -O/-O/'`
|
||||
;;
|
||||
*"-O -g"*)
|
||||
# Leave the -g, but remove all -O options.
|
||||
#echo "using -g as default gcc CFLAGS" 1>&6
|
||||
CFLAGS=`echo $CFLAGS | sed 's/-O\ -g/-O/'`
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
])
|
||||
dnl
|
||||
dnl
|
||||
dnl
|
||||
AC_DEFUN(wi_PROTOTYPES, [
|
||||
AC_MSG_CHECKING(if the compiler supports function prototypes)
|
||||
AC_TRY_COMPILE(,[extern void exit(int status);],[wi_cv_prototypes=yes
|
||||
AC_DEFINE(PROTOTYPES)],wi_cv_prototypes=no)
|
||||
AC_MSG_RESULT($wi_cv_prototypes)
|
||||
])
|
||||
dnl
|
||||
dnl
|
||||
dnl
|
||||
AC_DEFUN(wi_ANSI_C, [
|
||||
AC_MSG_CHECKING(ANSI-style function definitions)
|
||||
AC_TRY_COMPILE(,[int blubb(int x) { return 0; }],[wi_cv_ansi_funcs=yes
|
||||
AC_DEFINE(ANSI_FUNCS)],wi_cv_ansi_funcs=no)
|
||||
AC_MSG_RESULT($wi_cv_ansi_funcs)
|
||||
])
|
||||
dnl
|
||||
dnl
|
||||
dnl
|
||||
AC_DEFUN(wi_HEADER_SYS_SELECT_H, [
|
||||
# See if <sys/select.h> is includable after <sys/time.h>
|
||||
if test "$ac_cv_header_sys_time_h" = no ; then
|
||||
AC_CHECK_HEADERS(sys/time.h sys/select.h)
|
||||
else
|
||||
AC_CHECK_HEADERS(sys/select.h)
|
||||
fi
|
||||
if test "$ac_cv_header_sys_select_h" = yes ; then
|
||||
AC_MSG_CHECKING([if <sys/select.h> is compatible with <sys/time.h>])
|
||||
selecth=yes
|
||||
if test "$ac_cv_header_sys_time_h" = yes ; then
|
||||
AC_TRY_COMPILE([#include <sys/time.h>
|
||||
#include <sys/select.h>],[
|
||||
fd_set a;
|
||||
struct timeval tmval;
|
||||
|
||||
tmval.tv_sec = 0;],selecth=yes,selecth=no)
|
||||
|
||||
if test "$selecth" = yes ; then
|
||||
AC_DEFINE(CAN_USE_SYS_SELECT_H)
|
||||
fi
|
||||
fi
|
||||
AC_MSG_RESULT($selecth)
|
||||
fi
|
||||
])
|
||||
dnl
|
||||
dnl
|
||||
dnl
|
||||
AC_DEFUN(wi_LIB_RESOLV, [
|
||||
# See if we could access two well-known sites without help of any special
|
||||
# libraries, like resolv.
|
||||
|
||||
AC_TRY_RUN([
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
|
||||
main()
|
||||
{
|
||||
struct hostent *hp1, *hp2;
|
||||
int result;
|
||||
|
||||
hp1 = gethostbyname("gatekeeper.dec.com");
|
||||
hp2 = gethostbyname("ftp.ncsa.uiuc.edu");
|
||||
result = ((hp1 != (struct hostent *) 0) && (hp2 != (struct hostent *) 0));
|
||||
exit(! result);
|
||||
}],look_for_resolv=no,look_for_resolv=yes,look_for_resolv=yes)
|
||||
|
||||
AC_MSG_CHECKING([if we need to look for -lresolv])
|
||||
AC_MSG_RESULT($look_for_resolv)
|
||||
if test "$look_for_resolv" = yes ; then
|
||||
AC_CHECK_LIB(resolv,main)
|
||||
else
|
||||
ac_cv_lib_resolv=no
|
||||
fi
|
||||
])
|
||||
dnl
|
||||
dnl
|
||||
dnl
|
||||
|
||||
AC_DEFUN(wi_LIB_NSL, [
|
||||
AC_MSG_CHECKING(if we can use -lnsl)
|
||||
ac_save_LIBS="$LIBS";
|
||||
LIBS="$LIBS -lnsl";
|
||||
AC_CACHE_VAL(r_cv_use_libnsl, [
|
||||
AC_TRY_RUN(
|
||||
main() { if (getpwuid(getuid())) exit(0); exit(-1); },
|
||||
nc_cv_use_libnsl=yes, nc_cv_use_libnsl=no, nc_cv_use_libnsl=no)
|
||||
])
|
||||
if test "$nc_cv_use_libnsl" = "no"; then LIBS="$ac_save_LIBS"; fi
|
||||
AC_MSG_RESULT($nc_cv_use_libnsl)
|
||||
])dnl
|
||||
|
||||
dnl
|
||||
dnl
|
||||
dnl
|
||||
|
||||
AC_DEFUN(nc_PATH_PROG_ZCAT, [
|
||||
AC_PATH_PROG(GZCAT,gzcat)
|
||||
AC_PATH_PROG(ZCAT,zcat)
|
||||
if test "x$GZCAT" = x ; then
|
||||
if test "x$ZCAT" != x ; then
|
||||
# See if zcat is really gzcat. gzcat has a --version option, regular
|
||||
# zcat does not.
|
||||
AC_MSG_CHECKING(if zcat is really gzcat in disguise)
|
||||
if $ZCAT --version 2> /dev/null ; then
|
||||
AC_DEFINE_UNQUOTED(GZCAT, "$ZCAT")
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
fi
|
||||
else
|
||||
AC_DEFINE_UNQUOTED(GZCAT, "$GZCAT")
|
||||
fi
|
||||
|
||||
if test "x$ZCAT" != x ; then
|
||||
AC_DEFINE_UNQUOTED(ZCAT, "$ZCAT")
|
||||
fi
|
||||
])
|
||||
dnl
|
||||
dnl
|
||||
dnl
|
||||
AC_DEFUN(wi_SYSV_EXTRA_DIRS, [
|
||||
# Use System V because their curses extensions are required. This must
|
||||
# be done early so we use the -I and -L in the library checks also.
|
||||
# This is mostly a Solaris/SunOS hack. Note that doing this will also
|
||||
# use all of the other System V libraries and headers.
|
||||
|
||||
AC_MSG_CHECKING(for alternative System V libraries)
|
||||
if test -f /usr/5include/curses.h ; then
|
||||
CPPFLAGS="$CPPFLAGS -I/usr/5include"
|
||||
LDFLAGS="$LDFLAGS -L/usr/5lib"
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
])
|
||||
dnl
|
||||
dnl
|
||||
dnl
|
||||
AC_DEFUN(wi_DEFINE_UNAME, [
|
||||
# Get first 127 chars of all uname information. Some folks have
|
||||
# way too much stuff there, so grab only the first 127.
|
||||
unam=`uname -a 2>/dev/null | cut -c1-127`
|
||||
if test "$unam" != "" ; then
|
||||
AC_DEFINE_UNQUOTED(UNAME, "$unam")
|
||||
fi
|
||||
])
|
||||
dnl
|
||||
dnl
|
||||
dnl
|
||||
AC_DEFUN(wi_READLINE_WITH_NCURSES, [
|
||||
# Readline and Ncurses could both define "backspace".
|
||||
# Warn about this if we have both things in our definitions list.
|
||||
|
||||
if test "$ac_cv_lib_readline" = yes && test "$ac_cv_lib_ncurses" = yes ; then
|
||||
|
||||
AC_MSG_CHECKING(if readline and ncurses will link together)
|
||||
j="$LIBS"
|
||||
LIBS="-lreadline -lncurses"
|
||||
AC_TRY_LINK(,[
|
||||
readline("prompt");
|
||||
endwin();
|
||||
],k=yes,k=no)
|
||||
if test "$k" = no ; then
|
||||
AC_MSG_RESULT(no)
|
||||
# Remove '-lreadline' from LIBS.
|
||||
LIBS=`echo $j | sed s/-lreadline//g`
|
||||
ac_cv_lib_readline=no
|
||||
AC_WARN([The versions of GNU readline and ncurses you have installed on this system
|
||||
can't be used together, because they use the same symbol, backspace. If
|
||||
possible, recompile one of the libraries with -Dbackspace=back_space, then
|
||||
re-run configure.])
|
||||
|
||||
else
|
||||
AC_MSG_RESULT(yes)
|
||||
LIBS="$j"
|
||||
fi
|
||||
|
||||
fi
|
||||
])
|
||||
dnl
|
||||
dnl
|
||||
dnl
|
||||
|
||||
dnl AC_EXT_DAYLIGHT
|
||||
dnl Check for an external variable daylight. Stolen from w3c-libwww.
|
||||
AC_DEFUN(AC_EXT_DAYLIGHT,
|
||||
[ AC_MSG_CHECKING(int daylight variable)
|
||||
AC_TRY_COMPILE([#include <time.h>], [return daylight;],
|
||||
have_daylight=yes,
|
||||
have_daylight=no)
|
||||
AC_MSG_RESULT($have_daylight)
|
||||
])dnl
|
||||
|
||||
dnl AC_EXT_TIMEZONE
|
||||
dnl Check for an external variable timezone. Stolen from tcl-8.0.
|
||||
AC_DEFUN(AC_EXT_TIMEZONE,
|
||||
[
|
||||
#
|
||||
# Its important to include time.h in this check, as some systems (like convex)
|
||||
# have timezone functions, etc.
|
||||
#
|
||||
have_timezone=no
|
||||
AC_MSG_CHECKING([long timezone variable])
|
||||
AC_TRY_COMPILE([#include <time.h>],
|
||||
[extern long timezone;
|
||||
timezone += 1;
|
||||
exit (0);],
|
||||
[have_timezone=yes
|
||||
AC_MSG_RESULT(yes)],
|
||||
AC_MSG_RESULT(no))
|
||||
|
||||
#
|
||||
# On some systems (eg IRIX 6.2), timezone is a time_t and not a long.
|
||||
#
|
||||
if test "$have_timezone" = no; then
|
||||
AC_MSG_CHECKING([time_t timezone variable])
|
||||
AC_TRY_COMPILE([#include <time.h>],
|
||||
[extern time_t timezone;
|
||||
timezone += 1;
|
||||
exit (0);],
|
||||
[have_timezone=yes
|
||||
AC_MSG_RESULT(yes)],
|
||||
AC_MSG_RESULT(no))
|
||||
fi
|
||||
])dnl
|
||||
259
configure.in
Normal file
259
configure.in
Normal file
@@ -0,0 +1,259 @@
|
||||
dnl Process this file with aclocal ; automake -a ; autoconf to produce a
|
||||
dnl working configure script.
|
||||
dnl
|
||||
dnl $Id$
|
||||
|
||||
AC_INIT(src/bucket/newbucket.cxx)
|
||||
|
||||
dnl Initialize the automake stuff
|
||||
AM_INIT_AUTOMAKE(SimGear, 0.0.1)
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_MAKE_SET
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
AC_PROG_RANLIB
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_LN_S
|
||||
|
||||
if echo $includedir | egrep "simgear$" > /dev/null; then
|
||||
echo "includedir is" $includedir "libdir is" $libdir
|
||||
else
|
||||
includedir="${includedir}/simgear"
|
||||
echo "includedir changed to" $includedir "libdir is" $libdir
|
||||
fi
|
||||
|
||||
|
||||
dnl Specify if we want logging (testing build) or not (release build)
|
||||
# set logging default value
|
||||
# with_logging=yes
|
||||
AC_ARG_WITH(logging, [ --with-logging Include logging output (default)])
|
||||
if test "x$with_logging" = "xno" ; then
|
||||
AC_DEFINE(FG_NDEBUG)
|
||||
fi
|
||||
|
||||
dnl specify if we are building with "checker"
|
||||
AC_ARG_WITH(efence, [ --with-efence Specify if we are building with "electric-fence"])
|
||||
|
||||
if test "x$with_efence" = "xyes" ; then
|
||||
echo "Building with efence"
|
||||
LIBS= "$LIBS -lefence"
|
||||
fi
|
||||
|
||||
dnl Check for MS Windows environment
|
||||
AC_CHECK_HEADER(windows.h)
|
||||
|
||||
dnl extra library and include directories
|
||||
EXTRA_DIRS="/usr/local /usr/local/plib /usr/X11R6"
|
||||
|
||||
if test -d /opt/X11R6 ; then
|
||||
EXTRA_DIRS="$EXTRA_DIRS /opt/X11R6"
|
||||
fi
|
||||
|
||||
if test "x$ac_cv_header_windows_h" = "xyes" ; then
|
||||
EXTRA_DIRS="${EXTRA_DIRS} `pwd`/Win32"
|
||||
# elif test `uname -s` = "SunOS" ; then
|
||||
# EXTRA_DIRS="${EXTRA_DIRS} `pwd`/SunOS"
|
||||
fi
|
||||
wi_EXTRA_DIRS(no, ${EXTRA_DIRS})
|
||||
|
||||
dnl Using AM_CONDITIONAL is a step out of the protected little
|
||||
dnl automake fold so it is potentially dangerous. But, we are
|
||||
dnl beginning to run into cases where the standard checks are not
|
||||
dnl enough. AM_CONDITIONALS are then referenced to conditionally
|
||||
dnl build a Makefile.in from a Makefile.am which lets us define custom
|
||||
dnl includes, compile alternative source files, etc.
|
||||
|
||||
dnl Enable serial support on Unix type systems
|
||||
AM_CONDITIONAL(ENABLE_UNIX_SERIAL, true)
|
||||
|
||||
dnl Check for X11 (fancy)
|
||||
AC_PATH_XTRA
|
||||
|
||||
dnl Checks for libraries.
|
||||
|
||||
null_LIBS="$LIBS"
|
||||
|
||||
AC_CHECK_LIB(m, cos)
|
||||
|
||||
base_LIBS="$LIBS"
|
||||
|
||||
AC_CHECK_LIB(socket, socket)
|
||||
AC_CHECK_LIB(X11, XCreateWindow)
|
||||
AC_CHECK_LIB(Xext, XShmCreateImage)
|
||||
AC_CHECK_LIB(Xi, XGetExtensionVersion)
|
||||
AC_CHECK_LIB(ICE, IceOpenConnection)
|
||||
AC_CHECK_LIB(SM, SmcOpenConnection)
|
||||
AC_CHECK_LIB(Xt, XtMalloc)
|
||||
AC_CHECK_LIB(Xmu, XmuLookupStandardColormap)
|
||||
|
||||
dnl check for OpenGL related libraries
|
||||
|
||||
if test "x$ac_cv_header_windows_h" != "xyes" ; then
|
||||
dnl Reasonable stuff for non-windoze variants ... :-)
|
||||
|
||||
AC_CHECK_LIB(GLcore, glNewList)
|
||||
if test "x$ac_cv_lib_GLcore_glNewList" = "xno" ; then
|
||||
dnl if no GLcore, check for GL
|
||||
AC_CHECK_LIB(GL, glNewList)
|
||||
if test "x$ac_cv_lib_GL_glNewList" = "xno" ; then
|
||||
dnl if no GL, check for MesaGL
|
||||
AC_CHECK_LIB(MesaGL, glNewList)
|
||||
fi
|
||||
else
|
||||
dnl if GLcore found, then also check for GL
|
||||
AC_CHECK_LIB(GL, glXCreateContext)
|
||||
fi
|
||||
|
||||
dnl if using mesa, check for xmesa.h
|
||||
if test "x$ac_cv_lib_MesaGL_glNewList" = "xyes" ; then
|
||||
AC_CHECK_HEADER(GL/xmesa.h)
|
||||
if test "x$ac_cv_header_GL_xmesa_h" = "xyes"; then
|
||||
AC_DEFINE( XMESA )
|
||||
AC_DEFINE( FX )
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_CHECK_LIB(GLU, gluLookAt)
|
||||
if test "x$ac_cv_lib_GLU_gluLookAt" = "xno" ; then
|
||||
dnl if no GLU, check for MesaGLU
|
||||
AC_CHECK_LIB(MesaGLU, gluLookAt)
|
||||
fi
|
||||
|
||||
dnl check for glut
|
||||
AC_CHECK_LIB(glut, glutGetModifiers)
|
||||
|
||||
dnl test for glutGameModeString, but avoid adding glut a second time into
|
||||
dnl the list of libraries
|
||||
save_LIBS="$LIBS"
|
||||
AC_CHECK_LIB(glut, glutGameModeString)
|
||||
LIBS="$save_LIBS"
|
||||
else
|
||||
dnl Win32 is a little wierd because it has to try to handle the various
|
||||
dnl winbloze-isms. We'll just do this manually for now.
|
||||
|
||||
echo Win32 specific hacks...
|
||||
AC_DEFINE(WIN32)
|
||||
|
||||
dnl force a failed check since we will be building under windoze
|
||||
AM_CONDITIONAL(ENABLE_XMESA_FX, test "no" = "yes")
|
||||
|
||||
dnl just define these to true and hope for the best
|
||||
ac_cv_lib_glut_glutGetModifiers="yes"
|
||||
ac_cv_lib_glut_glutGameModeString="yes"
|
||||
|
||||
if test "x$with_sgi_opengl" = "xyes" ; then
|
||||
echo "Building with glut.dll, glu.dll, and opengl.dll"
|
||||
WIN32_GLUT=glut
|
||||
WIN32_GLU=glu
|
||||
WIN32_OPENGL=opengl
|
||||
else
|
||||
echo "Building with glut32.dll, glu32.dll, and opengl32.dll"
|
||||
WIN32_GLUT=glut32
|
||||
WIN32_GLU=glu32
|
||||
WIN32_OPENGL=opengl32
|
||||
fi
|
||||
|
||||
LIBS="$LIBS -l${WIN32_GLUT} -l${WIN32_GLU} -l${WIN32_OPENGL}"
|
||||
LIBS="$LIBS -luser32 -lgdi32"
|
||||
echo "Will link apps with $LIBS"
|
||||
fi
|
||||
|
||||
if test "x$ac_cv_lib_glut_glutGetModifiers" = "xno"; then
|
||||
echo
|
||||
echo "Unable to find the necessary OpenGL or GLUT libraries."
|
||||
echo "See config.log for automated test details and results ..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test "x$ac_cv_lib_glut_glutGameModeString" = "xno"; then
|
||||
echo
|
||||
echo "Your version of glut doesn't support game mode."
|
||||
echo "You need to fetch and install the latest version of glut from:"
|
||||
echo
|
||||
echo " http://reality.sgi.com/opengl/glut3/glut3.html"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
opengl_LIBS="$LIBS"
|
||||
LIBS="$base_LIBS"
|
||||
|
||||
AC_SUBST(base_LIBS)
|
||||
AC_SUBST(opengl_LIBS)
|
||||
|
||||
AM_CONDITIONAL(HAVE_XWINDOWS, test "x$ac_cv_lib_X11_XCreateWindow" = "xyes" )
|
||||
|
||||
dnl Check for "plib" without which we cannot go on
|
||||
AC_CHECK_HEADER(plib/pu.h)
|
||||
if test "x$ac_cv_header_plib_pu_h" != "xyes"; then
|
||||
echo
|
||||
echo "You *must* have the plib library installed on your system to build"
|
||||
echo "the FGFS simulator!"
|
||||
echo
|
||||
echo "Please see README.plib for more details."
|
||||
echo
|
||||
echo "configure aborted."
|
||||
exit
|
||||
fi
|
||||
|
||||
dnl Check for system installed zlib
|
||||
AC_CHECK_HEADER(zlib.h)
|
||||
if test "x$ac_cv_header_zlib_h" != "xyes"; then
|
||||
echo "no zlib found, building."
|
||||
fi
|
||||
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 )
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
AC_TYPE_SIZE_T
|
||||
AC_HEADER_TIME
|
||||
AC_STRUCT_TM
|
||||
|
||||
dnl Checks for library functions.
|
||||
AC_TYPE_SIGNAL
|
||||
AC_FUNC_VPRINTF
|
||||
AC_CHECK_FUNCS( ftime gettimeofday timegm memcpy bcopy mktime strstr rand \
|
||||
random setitimer getitimer signal GetLocalTime rint getrusage )
|
||||
|
||||
AM_CONFIG_HEADER(src/include/config.h)
|
||||
|
||||
AC_OUTPUT( \
|
||||
VERSION \
|
||||
Makefile \
|
||||
src/Makefile \
|
||||
src/include/Makefile \
|
||||
src/bucket/Makefile \
|
||||
src/debug/Makefile \
|
||||
src/math/Makefile \
|
||||
src/misc/Makefile \
|
||||
src/screen/Makefile \
|
||||
src/serial/Makefile \
|
||||
src/xgl/Makefile \
|
||||
src/zlib/Makefile \
|
||||
)
|
||||
|
||||
AC_OUTPUT_COMMANDS([./mksymlinks.sh])
|
||||
|
||||
echo ""
|
||||
echo "Configure Summary"
|
||||
echo "================="
|
||||
|
||||
echo "Prefix: $prefix"
|
||||
|
||||
if test "x$with_logging" != "x"; then
|
||||
echo "Debug messages: $with_logging"
|
||||
else
|
||||
echo "Debug messages: yes"
|
||||
fi
|
||||
|
||||
if test "x$with_efence" != "x"; then
|
||||
echo "Electric fence: $with_efence"
|
||||
else
|
||||
echo "Electric fence: no"
|
||||
fi
|
||||
39
mksymlinks.sh
Executable file
39
mksymlinks.sh
Executable file
@@ -0,0 +1,39 @@
|
||||
#! /bin/sh
|
||||
|
||||
echo ""
|
||||
echo "running $0 to rebuild simgear include links"
|
||||
|
||||
# toast the old directory
|
||||
rm -rf src/simgear
|
||||
mkdir src/simgear
|
||||
mkdir src/simgear/bucket
|
||||
mkdir src/simgear/debug
|
||||
mkdir src/simgear/math
|
||||
mkdir src/simgear/misc
|
||||
mkdir src/simgear/screen
|
||||
mkdir src/simgear/serial
|
||||
mkdir src/simgear/xgl
|
||||
mkdir src/simgear/zlib
|
||||
|
||||
# build new links
|
||||
ln -s ../include/compiler.h src/simgear/compiler.h
|
||||
ln -s ../include/constants.h src/simgear/constants.h
|
||||
ln -s ../include/fg_traits.hxx src/simgear/fg_traits.hxx
|
||||
ln -s ../include/fg_zlib.h src/simgear/fg_zlib.h
|
||||
|
||||
ln -s ../../bucket/newbucket.hxx src/simgear/bucket/newbucket.hxx
|
||||
|
||||
ln -s ../../debug/debug_types.h src/simgear/debug/debug_types.h
|
||||
ln -s ../../debug/logstream.hxx src/simgear/debug/logstream.hxx
|
||||
|
||||
ln -s ../../math/fg_memory.h src/simgear/math/fg_memory.h
|
||||
ln -s ../../math/fg_types.hxx src/simgear/math/fg_types.hxx
|
||||
ln -s ../../math/mat3.h src/simgear/math/mat3.h
|
||||
ln -s ../../math/point3d.hxx src/simgear/math/point3d.hxx
|
||||
ln -s ../../math/polar3d.hxx src/simgear/math/polar3d.hxx
|
||||
|
||||
ln -s ../../misc/fgpath.hxx src/simgear/misc/fgpath.hxx
|
||||
ln -s ../../misc/fgstream.hxx src/simgear/misc/fgstream.hxx
|
||||
ln -s ../../misc/zfstream.hxx src/simgear/misc/zfstream.hxx
|
||||
|
||||
ln -s ../../xgl/xgl.h src/simgear/xgl/xgl.h
|
||||
27
simgear/Makefile.am
Normal file
27
simgear/Makefile.am
Normal file
@@ -0,0 +1,27 @@
|
||||
if ENABLE_UNIX_SERIAL
|
||||
SERIAL_DIRS = serial
|
||||
else
|
||||
SERIAL_DIRS =
|
||||
endif
|
||||
|
||||
if HAVE_ZLIB
|
||||
ZLIB_DIRS =
|
||||
else
|
||||
ZLIB_DIRS = zlib
|
||||
endif
|
||||
|
||||
METAR_DIRS =
|
||||
# METAR_DIRS = metar
|
||||
|
||||
SUBDIRS = \
|
||||
include \
|
||||
bucket \
|
||||
debug \
|
||||
math \
|
||||
$(METAR_DIRS) \
|
||||
misc \
|
||||
screen \
|
||||
$(SERIAL_DIRS) \
|
||||
xgl \
|
||||
$(ZLIB_DIRS)
|
||||
|
||||
17
simgear/bucket/Makefile.am
Normal file
17
simgear/bucket/Makefile.am
Normal file
@@ -0,0 +1,17 @@
|
||||
includedir = @includedir@/bucket
|
||||
|
||||
lib_LIBRARIES = libsgbucket.a
|
||||
|
||||
include_HEADERS = newbucket.hxx
|
||||
|
||||
libsgbucket_a_SOURCES = newbucket.cxx
|
||||
|
||||
# noinst_PROGRAMS = testbucket
|
||||
|
||||
# testbucket_SOURCES = testbucket.cxx
|
||||
|
||||
# testbucket_LDADD = \
|
||||
# $(top_builddir)/bucket/libsgbucket.a \
|
||||
# $(top_builddir)/misc/libsgmisc.a
|
||||
|
||||
INCLUDES += -I$(top_builddir)/src
|
||||
155
simgear/bucket/newbucket.cxx
Normal file
155
simgear/bucket/newbucket.cxx
Normal file
@@ -0,0 +1,155 @@
|
||||
/**************************************************************************
|
||||
* newbucket.hxx -- new bucket routines for better world modeling
|
||||
*
|
||||
* Written by Curtis L. Olson, started February 1999.
|
||||
*
|
||||
* Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id$
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <simgear/misc/fgpath.hxx>
|
||||
|
||||
#include "newbucket.hxx"
|
||||
|
||||
|
||||
// Build the path name for this bucket
|
||||
string FGBucket::gen_base_path() const {
|
||||
// long int index;
|
||||
int top_lon, top_lat, main_lon, main_lat;
|
||||
char hem, pole;
|
||||
char raw_path[256];
|
||||
|
||||
top_lon = lon / 10;
|
||||
main_lon = lon;
|
||||
if ( (lon < 0) && (top_lon * 10 != lon) ) {
|
||||
top_lon -= 1;
|
||||
}
|
||||
top_lon *= 10;
|
||||
if ( top_lon >= 0 ) {
|
||||
hem = 'e';
|
||||
} else {
|
||||
hem = 'w';
|
||||
top_lon *= -1;
|
||||
}
|
||||
if ( main_lon < 0 ) {
|
||||
main_lon *= -1;
|
||||
}
|
||||
|
||||
top_lat = lat / 10;
|
||||
main_lat = lat;
|
||||
if ( (lat < 0) && (top_lat * 10 != lat) ) {
|
||||
top_lat -= 1;
|
||||
}
|
||||
top_lat *= 10;
|
||||
if ( top_lat >= 0 ) {
|
||||
pole = 'n';
|
||||
} else {
|
||||
pole = 's';
|
||||
top_lat *= -1;
|
||||
}
|
||||
if ( main_lat < 0 ) {
|
||||
main_lat *= -1;
|
||||
}
|
||||
|
||||
sprintf(raw_path, "%c%03d%c%02d/%c%03d%c%02d",
|
||||
hem, top_lon, pole, top_lat,
|
||||
hem, main_lon, pole, main_lat);
|
||||
|
||||
FGPath path( raw_path );
|
||||
|
||||
return path.str();
|
||||
}
|
||||
|
||||
|
||||
// find the bucket which is offset by the specified tile units in the
|
||||
// X & Y direction. We need the current lon and lat to resolve
|
||||
// ambiguities when going from a wider tile to a narrower one above or
|
||||
// below. This assumes that we are feeding in
|
||||
FGBucket fgBucketOffset( double dlon, double dlat, int dx, int dy ) {
|
||||
FGBucket result( dlon, dlat );
|
||||
double clat = result.get_center_lat() + dy * FG_BUCKET_SPAN;
|
||||
|
||||
// walk dy units in the lat direction
|
||||
result.set_bucket( dlon, clat );
|
||||
|
||||
// find the lon span for the new latitude
|
||||
double span = bucket_span( clat );
|
||||
|
||||
// walk dx units in the lon direction
|
||||
double tmp = dlon + dx * span;
|
||||
while ( tmp < -180.0 ) {
|
||||
tmp += 360.0;
|
||||
}
|
||||
while ( tmp >= 180.0 ) {
|
||||
tmp -= 360.0;
|
||||
}
|
||||
result.set_bucket( tmp, clat );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// calculate the offset between two buckets
|
||||
void fgBucketDiff( const FGBucket& b1, const FGBucket& b2, int *dx, int *dy ) {
|
||||
|
||||
// Latitude difference
|
||||
double c1_lat = b1.get_center_lat();
|
||||
double c2_lat = b2.get_center_lat();
|
||||
double diff_lat = c2_lat - c1_lat;
|
||||
|
||||
#ifdef HAVE_RINT
|
||||
*dy = (int)rint( diff_lat / FG_BUCKET_SPAN );
|
||||
#else
|
||||
if ( diff_lat > 0 ) {
|
||||
*dy = (int)( diff_lat / FG_BUCKET_SPAN + 0.5 );
|
||||
} else {
|
||||
*dy = (int)( diff_lat / FG_BUCKET_SPAN - 0.5 );
|
||||
}
|
||||
#endif
|
||||
|
||||
// longitude difference
|
||||
double c1_lon = b1.get_center_lon();
|
||||
double c2_lon = b2.get_center_lon();
|
||||
double diff_lon = c2_lon - c1_lon;
|
||||
double span;
|
||||
if ( bucket_span(c1_lat) <= bucket_span(c2_lat) ) {
|
||||
span = bucket_span(c1_lat);
|
||||
} else {
|
||||
span = bucket_span(c2_lat);
|
||||
}
|
||||
|
||||
#ifdef HAVE_RINT
|
||||
*dx = (int)rint( diff_lon / span );
|
||||
#else
|
||||
if ( diff_lon > 0 ) {
|
||||
*dx = (int)( diff_lon / span + 0.5 );
|
||||
} else {
|
||||
*dx = (int)( diff_lon / span - 0.5 );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
351
simgear/bucket/newbucket.hxx
Normal file
351
simgear/bucket/newbucket.hxx
Normal file
@@ -0,0 +1,351 @@
|
||||
/**************************************************************************
|
||||
* newbucket.hxx -- new bucket routines for better world modeling
|
||||
*
|
||||
* Written by Curtis L. Olson, started February 1999.
|
||||
*
|
||||
* Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Id$
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#ifndef _NEWBUCKET_HXX
|
||||
#define _NEWBUCKET_HXX
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
#include <simgear/constants.h>
|
||||
|
||||
#ifdef FG_HAVE_STD_INCLUDES
|
||||
# include <cmath>
|
||||
# include <cstdio> // sprintf()
|
||||
# include <iostream>
|
||||
#else
|
||||
# include <math.h>
|
||||
# include <stdio.h> // sprintf()
|
||||
# include <iostream.h>
|
||||
#endif
|
||||
|
||||
// I don't understand ... <math.h> or <cmath> should be included
|
||||
// already depending on how you defined FG_HAVE_STD_INCLUDES, but I
|
||||
// can go ahead and add this -- CLO
|
||||
#ifdef __MWERKS__
|
||||
# include <math.h> // needed fabs()
|
||||
#endif
|
||||
|
||||
#include STL_STRING
|
||||
|
||||
FG_USING_STD(string);
|
||||
|
||||
#if ! defined( FG_HAVE_NATIVE_SGI_COMPILERS )
|
||||
FG_USING_STD(ostream);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define FG_BUCKET_SPAN 0.125 // 1/8 of a degree
|
||||
#define FG_HALF_BUCKET_SPAN 0.0625 // 1/2 of 1/8 of a degree = 1/16 = 0.0625
|
||||
|
||||
class FGBucket;
|
||||
ostream& operator<< ( ostream&, const FGBucket& );
|
||||
bool operator== ( const FGBucket&, const FGBucket& );
|
||||
|
||||
class FGBucket {
|
||||
|
||||
private:
|
||||
double cx, cy; // centerpoint (lon, lat) in degrees of bucket
|
||||
int lon; // longitude index (-180 to 179)
|
||||
int lat; // latitude index (-90 to 89)
|
||||
int x; // x subdivision (0 to 7)
|
||||
int y; // y subdivision (0 to 7)
|
||||
|
||||
public:
|
||||
|
||||
// default constructor
|
||||
FGBucket();
|
||||
|
||||
// create a bucket which would contain the specified lon/lat
|
||||
FGBucket(const double lon, const double lat);
|
||||
|
||||
// create a bucket based on "long int" index
|
||||
FGBucket(const long int bindex);
|
||||
|
||||
// create an impossible bucket if false
|
||||
FGBucket(const bool is_good);
|
||||
|
||||
~FGBucket();
|
||||
|
||||
// Set the bucket params for the specified lat and lon
|
||||
void set_bucket( double dlon, double dlat );
|
||||
void make_bad ( void );
|
||||
|
||||
// Generate the unique scenery tile index for this bucket
|
||||
long int gen_index();
|
||||
string gen_index_str() const;
|
||||
|
||||
// Build the path name for this bucket
|
||||
string gen_base_path() const;
|
||||
|
||||
// return the center lon of a tile
|
||||
double get_center_lon() const;
|
||||
|
||||
// return width of the tile
|
||||
double get_width() const;
|
||||
|
||||
// return the center lat of a tile
|
||||
double get_center_lat() const;
|
||||
|
||||
// return height of the tile
|
||||
double get_height() const;
|
||||
|
||||
// Informational methods
|
||||
inline int get_lon() const { return lon; }
|
||||
inline int get_lat() const { return lat; }
|
||||
inline int get_x() const { return x; }
|
||||
inline int get_y() const { return y; }
|
||||
|
||||
// friends
|
||||
friend ostream& operator<< ( ostream&, const FGBucket& );
|
||||
friend bool operator== ( const FGBucket&, const FGBucket& );
|
||||
};
|
||||
|
||||
|
||||
// return the horizontal tile span factor based on latitude
|
||||
inline double bucket_span( double l ) {
|
||||
if ( l >= 89.0 ) {
|
||||
return 360.0;
|
||||
} else if ( l >= 88.0 ) {
|
||||
return 8.0;
|
||||
} else if ( l >= 86.0 ) {
|
||||
return 4.0;
|
||||
} else if ( l >= 83.0 ) {
|
||||
return 2.0;
|
||||
} else if ( l >= 76.0 ) {
|
||||
return 1.0;
|
||||
} else if ( l >= 62.0 ) {
|
||||
return 0.5;
|
||||
} else if ( l >= 22.0 ) {
|
||||
return 0.25;
|
||||
} else if ( l >= -22.0 ) {
|
||||
return 0.125;
|
||||
} else if ( l >= -62.0 ) {
|
||||
return 0.25;
|
||||
} else if ( l >= -76.0 ) {
|
||||
return 0.5;
|
||||
} else if ( l >= -83.0 ) {
|
||||
return 1.0;
|
||||
} else if ( l >= -86.0 ) {
|
||||
return 2.0;
|
||||
} else if ( l >= -88.0 ) {
|
||||
return 4.0;
|
||||
} else if ( l >= -89.0 ) {
|
||||
return 8.0;
|
||||
} else {
|
||||
return 360.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Set the bucket params for the specified lat and lon
|
||||
inline void FGBucket::set_bucket( double dlon, double dlat ) {
|
||||
//
|
||||
// latitude first
|
||||
//
|
||||
double span = bucket_span( dlat );
|
||||
double diff = dlon - (double)(int)dlon;
|
||||
|
||||
// cout << "diff = " << diff << " span = " << span << endl;
|
||||
|
||||
if ( (dlon >= 0) || (fabs(diff) < FG_EPSILON) ) {
|
||||
lon = (int)dlon;
|
||||
} else {
|
||||
lon = (int)dlon - 1;
|
||||
}
|
||||
|
||||
// find subdivision or super lon if needed
|
||||
if ( span < FG_EPSILON ) {
|
||||
// polar cap
|
||||
lon = 0;
|
||||
x = 0;
|
||||
} else if ( span <= 1.0 ) {
|
||||
x = (int)((dlon - lon) / span);
|
||||
} else {
|
||||
if ( (dlon >= 0) || (fabs(diff) < FG_EPSILON) ) {
|
||||
lon = (int)( (int)(lon / span) * span);
|
||||
} else {
|
||||
// cout << " lon = " << lon
|
||||
// << " tmp = " << (int)((lon-1) / span) << endl;
|
||||
lon = (int)( (int)((lon + 1) / span) * span - span);
|
||||
if ( lon < -180 ) {
|
||||
lon = -180;
|
||||
}
|
||||
}
|
||||
x = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// then latitude
|
||||
//
|
||||
diff = dlat - (double)(int)dlat;
|
||||
|
||||
if ( (dlat >= 0) || (fabs(diff) < FG_EPSILON) ) {
|
||||
lat = (int)dlat;
|
||||
} else {
|
||||
lat = (int)dlat - 1;
|
||||
}
|
||||
y = (int)((dlat - lat) * 8);
|
||||
}
|
||||
|
||||
|
||||
// default constructor
|
||||
inline FGBucket::FGBucket() {}
|
||||
|
||||
|
||||
// constructor for specified location
|
||||
inline FGBucket::FGBucket(const double dlon, const double dlat) {
|
||||
set_bucket(dlon, dlat);
|
||||
}
|
||||
|
||||
|
||||
// create an impossible bucket if false
|
||||
inline FGBucket::FGBucket(const bool is_good) {
|
||||
set_bucket(0.0, 0.0);
|
||||
if ( !is_good ) {
|
||||
lon = -1000;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Parse a unique scenery tile index and find the lon, lat, x, and y
|
||||
inline FGBucket::FGBucket(const long int bindex) {
|
||||
long int index = bindex;
|
||||
|
||||
lon = index >> 14;
|
||||
index -= lon << 14;
|
||||
lon -= 180;
|
||||
|
||||
lat = index >> 6;
|
||||
index -= lat << 6;
|
||||
lat -= 90;
|
||||
|
||||
y = index >> 3;
|
||||
index -= y << 3;
|
||||
|
||||
x = index;
|
||||
}
|
||||
|
||||
|
||||
// default destructor
|
||||
inline FGBucket::~FGBucket() {}
|
||||
|
||||
|
||||
// Generate the unique scenery tile index for this bucket
|
||||
//
|
||||
// The index is constructed as follows:
|
||||
//
|
||||
// 9 bits - to represent 360 degrees of longitude (-180 to 179)
|
||||
// 8 bits - to represent 180 degrees of latitude (-90 to 89)
|
||||
//
|
||||
// Each 1 degree by 1 degree tile is further broken down into an 8x8
|
||||
// grid. So we also need:
|
||||
//
|
||||
// 3 bits - to represent x (0 to 7)
|
||||
// 3 bits - to represent y (0 to 7)
|
||||
|
||||
inline long int FGBucket::gen_index() {
|
||||
return ((lon + 180) << 14) + ((lat + 90) << 6) + (y << 3) + x;
|
||||
}
|
||||
|
||||
inline string FGBucket::gen_index_str() const {
|
||||
char tmp[20];
|
||||
sprintf(tmp, "%ld",
|
||||
(((long)lon + 180) << 14) + ((lat + 90) << 6) + (y << 3) + x);
|
||||
return (string)tmp;
|
||||
}
|
||||
|
||||
|
||||
// return the center lon of a tile
|
||||
inline double FGBucket::get_center_lon() const {
|
||||
double span = bucket_span( lat + y / 8.0 + FG_HALF_BUCKET_SPAN );
|
||||
|
||||
if ( span >= 1.0 ) {
|
||||
return lon + span / 2.0;
|
||||
} else {
|
||||
return lon + x * span + span / 2.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// return the center lat of a tile
|
||||
inline double FGBucket::get_center_lat() const {
|
||||
return lat + y / 8.0 + FG_HALF_BUCKET_SPAN;
|
||||
}
|
||||
|
||||
|
||||
// return width of the tile
|
||||
inline double FGBucket::get_width() const {
|
||||
return bucket_span( get_center_lat() );
|
||||
}
|
||||
|
||||
|
||||
// return height of the tile
|
||||
inline double FGBucket::get_height() const {
|
||||
return FG_BUCKET_SPAN;
|
||||
}
|
||||
|
||||
|
||||
// create an impossible bucket
|
||||
inline void FGBucket::make_bad( void ) {
|
||||
set_bucket(0.0, 0.0);
|
||||
lon = -1000;
|
||||
}
|
||||
|
||||
|
||||
// offset a bucket struct by the specified tile units in the X & Y
|
||||
// direction
|
||||
FGBucket fgBucketOffset( double dlon, double dlat, int x, int y );
|
||||
|
||||
|
||||
// calculate the offset between two buckets
|
||||
void fgBucketDiff( const FGBucket& b1, const FGBucket& b2, int *dx, int *dy );
|
||||
|
||||
|
||||
/*
|
||||
// Given a lat/lon, fill in the local tile index array
|
||||
void fgBucketGenIdxArray(fgBUCKET *p1, fgBUCKET *tiles, int width, int height);
|
||||
*/
|
||||
|
||||
|
||||
inline ostream&
|
||||
operator<< ( ostream& out, const FGBucket& b )
|
||||
{
|
||||
return out << b.lon << ":" << b.x << ", " << b.lat << ":" << b.y;
|
||||
}
|
||||
|
||||
|
||||
inline bool
|
||||
operator== ( const FGBucket& b1, const FGBucket& b2 )
|
||||
{
|
||||
return ( b1.lon == b2.lon &&
|
||||
b1.lat == b2.lat &&
|
||||
b1.x == b2.x &&
|
||||
b1.y == b2.y );
|
||||
}
|
||||
|
||||
|
||||
#endif // _NEWBUCKET_HXX
|
||||
|
||||
|
||||
11
simgear/debug/Makefile.am
Normal file
11
simgear/debug/Makefile.am
Normal file
@@ -0,0 +1,11 @@
|
||||
includedir = @includedir@/debug
|
||||
|
||||
EXTRA_DIST = logtest.cxx
|
||||
|
||||
lib_LIBRARIES = libsgdebug.a
|
||||
|
||||
include_HEADERS = debug_types.h logstream.hxx
|
||||
|
||||
libsgdebug_a_SOURCES = logstream.cxx
|
||||
|
||||
INCLUDES += -I$(top_builddir)/src
|
||||
38
simgear/debug/debug_types.h
Normal file
38
simgear/debug/debug_types.h
Normal file
@@ -0,0 +1,38 @@
|
||||
// NB: To add a dbg_class, add it here, and add it to the structure in
|
||||
// fg_debug.c
|
||||
|
||||
typedef enum {
|
||||
FG_NONE = 0x00000000,
|
||||
|
||||
FG_TERRAIN = 0x00000001,
|
||||
FG_ASTRO = 0x00000002,
|
||||
FG_FLIGHT = 0x00000004,
|
||||
FG_INPUT = 0x00000008,
|
||||
FG_GL = 0x00000010,
|
||||
FG_VIEW = 0x00000020,
|
||||
FG_COCKPIT = 0x00000040,
|
||||
FG_GENERAL = 0x00000080,
|
||||
FG_MATH = 0x00000100,
|
||||
FG_EVENT = 0x00000200,
|
||||
FG_AIRCRAFT = 0x00000400,
|
||||
FG_AUTOPILOT = 0x00000800,
|
||||
FG_IO = 0x00001000,
|
||||
FG_CLIPPER = 0x00002000,
|
||||
FG_NETWORK = 0x00004000,
|
||||
FG_UNDEFD = 0x00008000, // For range checking
|
||||
|
||||
FG_ALL = 0xFFFFFFFF
|
||||
} fgDebugClass;
|
||||
|
||||
|
||||
// NB: To add a priority, add it here.
|
||||
typedef enum {
|
||||
FG_BULK, // For frequent messages
|
||||
FG_DEBUG, // Less frequent debug type messages
|
||||
FG_INFO, // Informatory messages
|
||||
FG_WARN, // Possible impending problem
|
||||
FG_ALERT // Very possible impending problem
|
||||
// FG_EXIT, // Problem (no core)
|
||||
// FG_ABORT // Abandon ship (core)
|
||||
} fgDebugPriority;
|
||||
|
||||
63
simgear/debug/logstream.cxx
Normal file
63
simgear/debug/logstream.cxx
Normal file
@@ -0,0 +1,63 @@
|
||||
// Stream based logging mechanism.
|
||||
//
|
||||
// Written by Bernie Bright, 1998
|
||||
//
|
||||
// Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
#include "logstream.hxx"
|
||||
|
||||
bool logbuf::logging_enabled = true;
|
||||
fgDebugClass logbuf::logClass = FG_NONE;
|
||||
fgDebugPriority logbuf::logPriority = FG_INFO;
|
||||
streambuf* logbuf::sbuf = NULL;
|
||||
|
||||
logbuf::logbuf()
|
||||
{
|
||||
// if ( sbuf == NULL )
|
||||
// sbuf = cerr.rdbuf();
|
||||
}
|
||||
|
||||
logbuf::~logbuf()
|
||||
{
|
||||
if ( sbuf )
|
||||
sync();
|
||||
}
|
||||
|
||||
void
|
||||
logbuf::set_sb( streambuf* sb )
|
||||
{
|
||||
if ( sbuf )
|
||||
sync();
|
||||
|
||||
sbuf = sb;
|
||||
}
|
||||
|
||||
void
|
||||
logbuf::set_log_level( fgDebugClass c, fgDebugPriority p )
|
||||
{
|
||||
logClass = c;
|
||||
logPriority = p;
|
||||
}
|
||||
|
||||
void
|
||||
logstream::setLogLevels( fgDebugClass c, fgDebugPriority p )
|
||||
{
|
||||
logbuf::set_log_level( c, p );
|
||||
}
|
||||
|
||||
220
simgear/debug/logstream.hxx
Normal file
220
simgear/debug/logstream.hxx
Normal file
@@ -0,0 +1,220 @@
|
||||
// Stream based logging mechanism.
|
||||
//
|
||||
// Written by Bernie Bright, 1998
|
||||
//
|
||||
// Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
#ifndef _LOGSTREAM_H
|
||||
#define _LOGSTREAM_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#ifdef FG_HAVE_STD_INCLUDES
|
||||
# include <streambuf>
|
||||
# include <iostream>
|
||||
#else
|
||||
# include <iostream.h>
|
||||
# include <simgear/fg_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);
|
||||
#endif
|
||||
|
||||
#ifdef __MWERKS__
|
||||
# define cerr std::cerr
|
||||
# define endl std::endl
|
||||
FG_USING_STD(iostream);
|
||||
#endif
|
||||
|
||||
//
|
||||
// TODO:
|
||||
//
|
||||
// 1. Change output destination. Done.
|
||||
// 2. Make logbuf thread safe.
|
||||
// 3. Read environment for default debugClass and debugPriority.
|
||||
//
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// logbuf is an output-only streambuf with the ability to disable sets of
|
||||
// messages at runtime. Only messages with priority >= logbuf::logPriority
|
||||
// and debugClass == logbuf::logClass are output.
|
||||
//
|
||||
class logbuf : public streambuf
|
||||
{
|
||||
public:
|
||||
|
||||
#ifndef FG_HAVE_STD_INCLUDES
|
||||
typedef char_traits<char> traits_type;
|
||||
typedef char_traits<char>::int_type int_type;
|
||||
typedef char_traits<char>::pos_type pos_type;
|
||||
typedef char_traits<char>::off_type off_type;
|
||||
#endif
|
||||
// logbuf( streambuf* sb ) : sbuf(sb) {}
|
||||
logbuf();
|
||||
~logbuf();
|
||||
|
||||
// Is logging enabled?
|
||||
bool enabled() { return logging_enabled; }
|
||||
|
||||
// Set the logging level of subsequent messages.
|
||||
void set_log_state( fgDebugClass c, fgDebugPriority p );
|
||||
|
||||
// Set the global logging level.
|
||||
static void set_log_level( fgDebugClass c, fgDebugPriority p );
|
||||
|
||||
//
|
||||
void set_sb( streambuf* sb );
|
||||
|
||||
protected:
|
||||
|
||||
inline virtual int sync();
|
||||
int_type overflow( int ch );
|
||||
// int xsputn( const char* s, istreamsize n );
|
||||
|
||||
private:
|
||||
|
||||
// The streambuf used for actual output. Defaults to cerr.rdbuf().
|
||||
static streambuf* sbuf;
|
||||
|
||||
static bool logging_enabled;
|
||||
static fgDebugClass logClass;
|
||||
static fgDebugPriority logPriority;
|
||||
|
||||
private:
|
||||
|
||||
// Not defined.
|
||||
logbuf( const logbuf& );
|
||||
void operator= ( const logbuf& );
|
||||
};
|
||||
|
||||
inline int
|
||||
logbuf::sync()
|
||||
{
|
||||
#ifdef FG_HAVE_STD_INCLUDES
|
||||
return sbuf->pubsync();
|
||||
#else
|
||||
return sbuf->sync();
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void
|
||||
logbuf::set_log_state( fgDebugClass c, fgDebugPriority p )
|
||||
{
|
||||
logging_enabled = ((c & logClass) != 0 && p >= logPriority);
|
||||
}
|
||||
|
||||
inline logbuf::int_type
|
||||
logbuf::overflow( int c )
|
||||
{
|
||||
return logging_enabled ? sbuf->sputc(c) : (EOF == 0 ? 1: 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// logstream manipulator for setting the log level of a message.
|
||||
//
|
||||
struct loglevel
|
||||
{
|
||||
loglevel( fgDebugClass c, fgDebugPriority p )
|
||||
: logClass(c), logPriority(p) {}
|
||||
|
||||
fgDebugClass logClass;
|
||||
fgDebugPriority logPriority;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// A helper class that ensures a streambuf and ostream are constructed and
|
||||
// destroyed in the correct order. The streambuf must be created before the
|
||||
// ostream but bases are constructed before members. Thus, making this class
|
||||
// a private base of logstream, declared to the left of ostream, we ensure the
|
||||
// correct order of construction and destruction.
|
||||
//
|
||||
struct logstream_base
|
||||
{
|
||||
// logstream_base( streambuf* sb ) : lbuf(sb) {}
|
||||
logstream_base() {}
|
||||
|
||||
logbuf lbuf;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
class logstream : private logstream_base, public ostream
|
||||
{
|
||||
public:
|
||||
// The default is to send messages to cerr.
|
||||
logstream( ostream& out )
|
||||
// : logstream_base(out.rdbuf()),
|
||||
: logstream_base(),
|
||||
ostream(&lbuf) { lbuf.set_sb(out.rdbuf());}
|
||||
|
||||
void set_output( ostream& out ) { lbuf.set_sb( out.rdbuf() ); }
|
||||
|
||||
// Set the global log class and priority level.
|
||||
void setLogLevels( fgDebugClass c, fgDebugPriority p );
|
||||
|
||||
// Output operator to capture the debug level and priority of a message.
|
||||
inline ostream& operator<< ( const loglevel& l );
|
||||
};
|
||||
|
||||
inline ostream&
|
||||
logstream::operator<< ( const loglevel& l )
|
||||
{
|
||||
lbuf.set_log_state( l.logClass, l.logPriority );
|
||||
return *this;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Return the one and only logstream instance.
|
||||
// We use a function instead of a global object so we are assured that cerr
|
||||
// has been initialised.
|
||||
//
|
||||
inline logstream&
|
||||
fglog()
|
||||
{
|
||||
static logstream logstrm( cerr );
|
||||
return logstrm;
|
||||
}
|
||||
|
||||
#ifdef FG_NDEBUG
|
||||
# define FG_LOG(C,P,M)
|
||||
#elif defined( __MWERKS__ )
|
||||
# define FG_LOG(C,P,M) ::fglog() << ::loglevel(C,P) << M << std::endl
|
||||
#else
|
||||
# define FG_LOG(C,P,M) fglog() << loglevel(C,P) << M << endl
|
||||
#endif
|
||||
|
||||
#endif // _LOGSTREAM_H
|
||||
|
||||
34
simgear/debug/logtest.cxx
Normal file
34
simgear/debug/logtest.cxx
Normal file
@@ -0,0 +1,34 @@
|
||||
#include <string>
|
||||
#include "Debug/logstream.hxx"
|
||||
|
||||
int
|
||||
main( int argc, char* argv[] )
|
||||
{
|
||||
fglog().setLogLevels( FG_ALL, FG_INFO );
|
||||
|
||||
FG_LOG( FG_TERRAIN, FG_BULK, "terrain::bulk" ); // shouldnt appear
|
||||
FG_LOG( FG_TERRAIN, FG_DEBUG, "terrain::debug" ); // shouldnt appear
|
||||
FG_LOG( FG_TERRAIN, FG_INFO, "terrain::info" );
|
||||
FG_LOG( FG_TERRAIN, FG_WARN, "terrain::warn" );
|
||||
FG_LOG( FG_TERRAIN, FG_ALERT, "terrain::alert" );
|
||||
|
||||
int i = 12345;
|
||||
long l = 54321L;
|
||||
double d = 3.14159;
|
||||
string s = "Hello world!";
|
||||
|
||||
FG_LOG( FG_EVENT, FG_INFO, "event::info "
|
||||
<< "i=" << i
|
||||
<< ", l=" << l
|
||||
<< ", d=" << d
|
||||
<< ", d*l=" << d*l
|
||||
<< ", s=\"" << s << "\"" );
|
||||
|
||||
// This shouldn't appear in log output:
|
||||
FG_LOG( FG_EVENT, FG_DEBUG, "event::debug "
|
||||
<< "- this should be seen - "
|
||||
<< "d=" << d
|
||||
<< ", s=\"" << s << "\"" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -16,4 +16,4 @@ libAstro_a_SOURCES = \
|
||||
uranus.cxx uranus.hxx \
|
||||
venus.cxx venus.hxx
|
||||
|
||||
INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib -I$(top_builddir)/Simulator
|
||||
INCLUDES += -I$(top_builddir) -I$(top_builddir)/src
|
||||
|
||||
@@ -22,15 +22,17 @@
|
||||
* $Id$
|
||||
**************************************************************************/
|
||||
|
||||
#include "celestialBody.hxx"
|
||||
#include "star.hxx"
|
||||
#include <Debug/logstream.hxx>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#ifdef FG_MATH_EXCEPTION_CLASH
|
||||
# define exception c_exception
|
||||
#endif
|
||||
#include <math.h>
|
||||
|
||||
#include "celestialBody.hxx"
|
||||
#include "star.hxx"
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* void CelestialBody::updatePosition(fgTIME *t, Star *ourSun)
|
||||
*
|
||||
|
||||
@@ -31,8 +31,9 @@
|
||||
#endif
|
||||
|
||||
|
||||
#include <simgear/constants.h>
|
||||
|
||||
#include <Time/fg_time.hxx>
|
||||
#include <Include/fg_constants.h>
|
||||
|
||||
class Star;
|
||||
|
||||
|
||||
@@ -22,14 +22,13 @@
|
||||
* $Id$
|
||||
**************************************************************************/
|
||||
|
||||
#include <FDM/flight.hxx>
|
||||
|
||||
#include <string.h>
|
||||
#include "moon.hxx"
|
||||
|
||||
#include <Debug/logstream.hxx>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/misc/fgpath.hxx>
|
||||
|
||||
#include <Main/options.hxx>
|
||||
#include <Misc/fgpath.hxx>
|
||||
#include <Objects/texload.h>
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
@@ -37,6 +36,9 @@
|
||||
#endif
|
||||
#include <math.h>
|
||||
|
||||
#include <FDM/flight.hxx>
|
||||
|
||||
#include "moon.hxx"
|
||||
|
||||
/*************************************************************************
|
||||
* Moon::Moon(FGTime *t)
|
||||
@@ -156,27 +158,22 @@ void Moon::setHalo()
|
||||
for (i=0; i < texWidth; i++) {
|
||||
for (j=0; j < texWidth; j++) {
|
||||
double x, y, d;
|
||||
|
||||
|
||||
*p = 0xff;
|
||||
*(p+1) = 0xff;
|
||||
*(p+2) = 0xff;
|
||||
|
||||
x = fabs((double)(i - (texWidth / 2)));
|
||||
y = fabs((double)(j - (texWidth / 2)));
|
||||
|
||||
d = sqrt((x * x) + (y * y));
|
||||
if (d < radius)
|
||||
{
|
||||
if (d < radius) {
|
||||
double t = 1.0 - (d / radius); // t is 1.0 at center, 0.0 at edge */
|
||||
// inverse square looks nice
|
||||
*p = (int)((double)0xff * (t * t));
|
||||
*(p+1) = (int)((double) 0xff * (t*t));
|
||||
*(p+2) = (int)((double) 0xff * (t*t));
|
||||
*(p+3) = 0x11;
|
||||
}
|
||||
else
|
||||
{
|
||||
*p = 0x00;
|
||||
*(p+1) = 0x00;
|
||||
*(p+2) = 0x00;
|
||||
*(p+3) = 0x11;
|
||||
}
|
||||
*(p+3) = (int)((double) 0x20 * (t*t));
|
||||
} else {
|
||||
*(p+3) = 0x00;
|
||||
}
|
||||
p += 4;
|
||||
}
|
||||
}
|
||||
@@ -353,7 +350,8 @@ void Moon::newImage()
|
||||
// Draw the halo...
|
||||
if (current_options.get_textures())
|
||||
{
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
// glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
|
||||
glEnable(GL_TEXTURE_2D); // TEXTURE ENABLED
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
glBindTexture(GL_TEXTURE_2D, moon_halotexid);
|
||||
|
||||
@@ -24,8 +24,9 @@
|
||||
#ifndef _MOON_HXX_
|
||||
#define _MOON_HXX_
|
||||
|
||||
#include <simgear/constants.h>
|
||||
|
||||
#include <Aircraft/aircraft.hxx>
|
||||
#include <Include/fg_constants.h>
|
||||
#include <Main/views.hxx>
|
||||
#include <Time/fg_time.hxx>
|
||||
|
||||
|
||||
@@ -32,14 +32,15 @@
|
||||
#include <math.h>
|
||||
|
||||
#include <GL/glut.h>
|
||||
#include <XGL/xgl.h>
|
||||
#include <simgear/xgl/xgl.h>
|
||||
|
||||
#include <simgear/constants.h>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/math/fg_random.h>
|
||||
|
||||
#include <Aircraft/aircraft.hxx>
|
||||
#include <Debug/logstream.hxx>
|
||||
#include <FDM/flight.hxx>
|
||||
#include <Include/fg_constants.h>
|
||||
#include <Main/views.hxx>
|
||||
#include <Math/fg_random.h>
|
||||
#include <Time/event.hxx>
|
||||
#include <Time/fg_time.hxx>
|
||||
|
||||
@@ -72,9 +73,9 @@ static float middle_vertex[12][3];
|
||||
static float outer_vertex[12][3];
|
||||
static float bottom_vertex[12][3];
|
||||
|
||||
static float inner_color[12][4];
|
||||
static float middle_color[12][4];
|
||||
static float outer_color[12][4];
|
||||
static GLubyte inner_color[12][4];
|
||||
static GLubyte middle_color[12][4];
|
||||
static GLubyte outer_color[12][4];
|
||||
|
||||
|
||||
// Calculate the sky structure vertices
|
||||
@@ -168,19 +169,21 @@ void fgSkyColorsInit( void ) {
|
||||
// printf("sky = %.2f fog = %.2f diff = %.2f\n",
|
||||
// l->sky_color[j], l->fog_color[j], diff);
|
||||
|
||||
inner_color[i][j] = l->sky_color[j] - diff * 0.3;
|
||||
middle_color[i][j] = l->sky_color[j] - diff * 0.9 + middle_amt[j];
|
||||
outer_color[i][j] = l->fog_color[j] + outer_amt[j];
|
||||
inner_color[i][j] = (GLubyte)((l->sky_color[j] - diff * 0.3) * 255);
|
||||
middle_color[i][j] = (GLubyte)((l->sky_color[j] - diff * 0.9
|
||||
+ middle_amt[j]) * 255);
|
||||
outer_color[i][j] = (GLubyte)((l->fog_color[j] + outer_amt[j])
|
||||
* 255);
|
||||
|
||||
if ( inner_color[i][j] > 1.00 ) { inner_color[i][j] = 1.00; }
|
||||
if ( inner_color[i][j] < 0.10 ) { inner_color[i][j] = 0.10; }
|
||||
if ( middle_color[i][j] > 1.00 ) { middle_color[i][j] = 1.00; }
|
||||
if ( middle_color[i][j] < 0.10 ) { middle_color[i][j] = 0.10; }
|
||||
if ( outer_color[i][j] > 1.00 ) { outer_color[i][j] = 1.00; }
|
||||
if ( outer_color[i][j] < 0.10 ) { outer_color[i][j] = 0.10; }
|
||||
if ( inner_color[i][j] > 255 ) { inner_color[i][j] = 255; }
|
||||
if ( inner_color[i][j] < 25 ) { inner_color[i][j] = 25; }
|
||||
if ( middle_color[i][j] > 255 ) { middle_color[i][j] = 255; }
|
||||
if ( middle_color[i][j] < 25 ) { middle_color[i][j] = 25; }
|
||||
if ( outer_color[i][j] > 255 ) { outer_color[i][j] = 255; }
|
||||
if ( outer_color[i][j] < 25 ) { outer_color[i][j] = 25; }
|
||||
}
|
||||
inner_color[i][3] = middle_color[i][3] = outer_color[i][3] =
|
||||
l->sky_color[3];
|
||||
(GLubyte)(l->sky_color[3] * 255);
|
||||
|
||||
for ( j = 0; j < 3; j++ ) {
|
||||
outer_amt[j] -= outer_diff[j];
|
||||
@@ -212,19 +215,21 @@ void fgSkyColorsInit( void ) {
|
||||
// printf("sky = %.2f fog = %.2f diff = %.2f\n",
|
||||
// l->sky_color[j], l->fog_color[j], diff);
|
||||
|
||||
inner_color[i][j] = l->sky_color[j] - diff * 0.3;
|
||||
middle_color[i][j] = l->sky_color[j] - diff * 0.9 + middle_amt[j];
|
||||
outer_color[i][j] = l->fog_color[j] + outer_amt[j];
|
||||
inner_color[i][j] = (GLubyte)((l->sky_color[j] - diff * 0.3) * 255);
|
||||
middle_color[i][j] = (GLubyte)((l->sky_color[j] - diff * 0.9
|
||||
+ middle_amt[j]) * 255);
|
||||
outer_color[i][j] = (GLubyte)((l->fog_color[j] + outer_amt[j])
|
||||
* 255);
|
||||
|
||||
if ( inner_color[i][j] > 1.00 ) { inner_color[i][j] = 1.00; }
|
||||
if ( inner_color[i][j] < 0.10 ) { inner_color[i][j] = 0.10; }
|
||||
if ( middle_color[i][j] > 1.00 ) { middle_color[i][j] = 1.00; }
|
||||
if ( middle_color[i][j] < 0.10 ) { middle_color[i][j] = 0.10; }
|
||||
if ( outer_color[i][j] > 1.00 ) { outer_color[i][j] = 1.00; }
|
||||
if ( outer_color[i][j] < 0.15 ) { outer_color[i][j] = 0.15; }
|
||||
if ( inner_color[i][j] > 255 ) { inner_color[i][j] = 255; }
|
||||
if ( inner_color[i][j] < 25 ) { inner_color[i][j] = 25; }
|
||||
if ( middle_color[i][j] > 255 ) { middle_color[i][j] = 255; }
|
||||
if ( middle_color[i][j] < 25 ) { middle_color[i][j] = 25; }
|
||||
if ( outer_color[i][j] > 255 ) { outer_color[i][j] = 255; }
|
||||
if ( outer_color[i][j] < 35 ) { outer_color[i][j] = 35; }
|
||||
}
|
||||
inner_color[i][3] = middle_color[i][3] = outer_color[i][3] =
|
||||
l->sky_color[3];
|
||||
(GLubyte)(l->sky_color[3] * 255);
|
||||
|
||||
for ( j = 0; j < 3; j++ ) {
|
||||
outer_amt[j] += outer_diff[j];
|
||||
@@ -261,9 +266,10 @@ void fgSkyInit( void ) {
|
||||
void fgSkyRender( void ) {
|
||||
FGInterface *f;
|
||||
fgLIGHT *l;
|
||||
float inner_color[4];
|
||||
float middle_color[4];
|
||||
float outer_color[4];
|
||||
GLubyte sky_color[4];
|
||||
GLubyte inner_color[4];
|
||||
GLubyte middle_color[4];
|
||||
GLubyte outer_color[4];
|
||||
double diff;
|
||||
int i;
|
||||
|
||||
@@ -279,11 +285,12 @@ void fgSkyRender( void ) {
|
||||
// printf("sky = %.2f fog = %.2f diff = %.2f\n",
|
||||
// l->sky_color[j], l->adj_fog_color[j], diff);
|
||||
|
||||
inner_color[i] = l->sky_color[i] - diff * 0.3;
|
||||
middle_color[i] = l->sky_color[i] - diff * 0.9;
|
||||
outer_color[i] = l->adj_fog_color[i];
|
||||
inner_color[i] = (GLubyte)((l->sky_color[i] - diff * 0.3) * 255);
|
||||
middle_color[i] = (GLubyte)((l->sky_color[i] - diff * 0.9) * 255);
|
||||
outer_color[i] = (GLubyte)(l->adj_fog_color[i] * 255);
|
||||
}
|
||||
inner_color[3] = middle_color[3] = outer_color[3] = l->adj_fog_color[3];
|
||||
inner_color[3] = middle_color[3] = outer_color[3] =
|
||||
(GLubyte)(l->adj_fog_color[3] * 255);
|
||||
|
||||
xglPushMatrix();
|
||||
|
||||
@@ -302,36 +309,39 @@ void fgSkyRender( void ) {
|
||||
|
||||
// Draw inner/center section of sky*/
|
||||
xglBegin( GL_TRIANGLE_FAN );
|
||||
for ( i = 0; i < 4; i++ ) {
|
||||
sky_color[i] = (GLubyte)(l->sky_color[i] * 255);
|
||||
}
|
||||
xglColor4fv(l->sky_color);
|
||||
xglVertex3f(0.0, 0.0, CENTER_ELEV);
|
||||
for ( i = 11; i >= 0; i-- ) {
|
||||
xglColor4fv( inner_color );
|
||||
xglColor4ubv( inner_color );
|
||||
xglVertex3fv( inner_vertex[i] );
|
||||
}
|
||||
xglColor4fv( inner_color );
|
||||
xglColor4ubv( inner_color );
|
||||
xglVertex3fv( inner_vertex[11] );
|
||||
xglEnd();
|
||||
|
||||
// Draw the middle ring
|
||||
xglBegin( GL_TRIANGLE_STRIP );
|
||||
for ( i = 0; i < 12; i++ ) {
|
||||
xglColor4fv( middle_color );
|
||||
xglColor4ubv( middle_color );
|
||||
// printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i,
|
||||
// middle_color[i][0], middle_color[i][1], middle_color[i][2],
|
||||
// middle_color[i][3]);
|
||||
// xglColor4f(1.0, 0.0, 0.0, 1.0);
|
||||
xglVertex3fv( middle_vertex[i] );
|
||||
xglColor4fv( inner_color );
|
||||
xglColor4ubv( inner_color );
|
||||
// printf("inner_color[%d] = %.2f %.2f %.2f %.2f\n", i,
|
||||
// inner_color[i][0], inner_color[i][1], inner_color[i][2],
|
||||
// inner_color[i][3]);
|
||||
// xglColor4f(0.0, 0.0, 1.0, 1.0);
|
||||
xglVertex3fv( inner_vertex[i] );
|
||||
}
|
||||
xglColor4fv( middle_color );
|
||||
xglColor4ubv( middle_color );
|
||||
// xglColor4f(1.0, 0.0, 0.0, 1.0);
|
||||
xglVertex3fv( middle_vertex[0] );
|
||||
xglColor4fv( inner_color );
|
||||
xglColor4ubv( inner_color );
|
||||
// xglColor4f(0.0, 0.0, 1.0, 1.0);
|
||||
xglVertex3fv( inner_vertex[0] );
|
||||
xglEnd();
|
||||
@@ -339,20 +349,20 @@ void fgSkyRender( void ) {
|
||||
// Draw the outer ring
|
||||
xglBegin( GL_TRIANGLE_STRIP );
|
||||
for ( i = 0; i < 12; i++ ) {
|
||||
xglColor4fv( outer_color );
|
||||
xglColor4ubv( outer_color );
|
||||
xglVertex3fv( outer_vertex[i] );
|
||||
xglColor4fv( middle_color );
|
||||
xglColor4ubv( middle_color );
|
||||
xglVertex3fv( middle_vertex[i] );
|
||||
}
|
||||
xglColor4fv( outer_color );
|
||||
xglColor4ubv( outer_color );
|
||||
xglVertex3fv( outer_vertex[0] );
|
||||
xglColor4fv( middle_color );
|
||||
xglColor4ubv( middle_color );
|
||||
xglVertex3fv( middle_vertex[0] );
|
||||
xglEnd();
|
||||
|
||||
// Draw the bottom skirt
|
||||
xglBegin( GL_TRIANGLE_STRIP );
|
||||
xglColor4fv( outer_color );
|
||||
xglColor4ubv( outer_color );
|
||||
for ( i = 0; i < 12; i++ ) {
|
||||
xglVertex3fv( bottom_vertex[i] );
|
||||
xglVertex3fv( outer_vertex[i] );
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#endif
|
||||
|
||||
|
||||
#include <ssg.h> // plib include
|
||||
#include <plib/ssg.h> // plib include
|
||||
|
||||
|
||||
class fgSky : ssgLeaf
|
||||
|
||||
@@ -36,8 +36,10 @@
|
||||
#include <math.h>
|
||||
|
||||
#include <GL/glut.h>
|
||||
#include <XGL/xgl.h>
|
||||
#include <Debug/logstream.hxx>
|
||||
#include <simgear/xgl/xgl.h>
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#include <Time/sunpos.hxx>
|
||||
#include <Time/moonpos.hxx>
|
||||
#include "solarsystem.hxx"
|
||||
|
||||
@@ -26,10 +26,13 @@
|
||||
# define exception c_exception
|
||||
#endif
|
||||
#include <math.h>
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#include <Time/sunpos.hxx>
|
||||
#include <Debug/logstream.hxx>
|
||||
#include <Time/light.hxx>
|
||||
#include <Main/options.hxx>
|
||||
|
||||
#include "star.hxx"
|
||||
|
||||
/*************************************************************************
|
||||
@@ -116,26 +119,21 @@ void Star::setTexture()
|
||||
for (j=0; j < texWidth; j++) {
|
||||
double x, y, d;
|
||||
|
||||
*p = 0xff;
|
||||
*(p+1) = 0xff;
|
||||
*(p+2) = 0xff;
|
||||
|
||||
x = fabs((double)(i - (texWidth / 2)));
|
||||
y = fabs((double)(j - (texWidth / 2)));
|
||||
|
||||
d = sqrt((x * x) + (y * y));
|
||||
if (d < radius)
|
||||
{
|
||||
if (d < radius) {
|
||||
double t = 1.0 - (d / radius); // t is 1.0 at center, 0.0 at edge */
|
||||
// inverse square looks nice
|
||||
*p = (int)((double)0xff * (t * t));
|
||||
*(p+1) = (int)((double) 0xff * (t*t));
|
||||
*(p+2) = (int)((double) 0xff * (t*t));
|
||||
*(p+3) = (int)((double) 0xff * (t*t));
|
||||
}
|
||||
else
|
||||
{
|
||||
*p = 0x00;
|
||||
*(p+1) = 0x00;
|
||||
*(p+2) = 0x00;
|
||||
} else {
|
||||
*(p+3) = 0x00;
|
||||
}
|
||||
}
|
||||
p += 4;
|
||||
}
|
||||
}
|
||||
@@ -235,10 +233,11 @@ void Star::newImage(void)
|
||||
xglTranslatef(0,60000,0);
|
||||
if (current_options.get_textures())
|
||||
{
|
||||
glEnable(GL_TEXTURE_2D); // TEXTURE ENABLED
|
||||
glEnable(GL_BLEND); // BLEND ENABLED
|
||||
glEnable(GL_TEXTURE_2D); // TEXTURE ENABLED
|
||||
glEnable(GL_BLEND); // BLEND ENABLED
|
||||
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
// glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
glBindTexture(GL_TEXTURE_2D, sun_texid);
|
||||
|
||||
@@ -254,8 +253,8 @@ void Star::newImage(void)
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
glDisable(GL_LIGHTING); //LIGHTING DISABLED
|
||||
glDisable(GL_BLEND); //BLEND DISABLED
|
||||
glDisable(GL_LIGHTING); // LIGHTING DISABLED
|
||||
glDisable(GL_BLEND); // BLEND DISABLED
|
||||
glPushMatrix();
|
||||
{
|
||||
xglRotatef(((RAD_TO_DEG * rightAscension)- 90.0), 0.0, 0.0, 1.0);
|
||||
@@ -265,7 +264,7 @@ void Star::newImage(void)
|
||||
gluSphere( SunObject, sun_size, 10, 10 );
|
||||
}
|
||||
glPopMatrix();
|
||||
glDisable(GL_TEXTURE_2D); // TEXTURE DISABLED
|
||||
glDisable(GL_BLEND); // BLEND DISABLED
|
||||
glDisable(GL_TEXTURE_2D); // TEXTURE DISABLED
|
||||
glDisable(GL_BLEND); // BLEND DISABLED
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,8 @@
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "Include/compiler.h"
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#ifdef FG_HAVE_STD_INCLUDES
|
||||
# include <cmath>
|
||||
# include <cstdio>
|
||||
@@ -46,22 +47,22 @@
|
||||
#include <string>
|
||||
|
||||
#include <GL/glut.h>
|
||||
#include <XGL/xgl.h>
|
||||
#include <simgear/xgl/xgl.h>
|
||||
|
||||
#include <simgear/constants.h>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/misc/fgpath.hxx>
|
||||
#include <simgear/misc/fgstream.hxx>
|
||||
#include <simgear/misc/stopwatch.hxx>
|
||||
|
||||
#include <Aircraft/aircraft.hxx>
|
||||
#include <Debug/logstream.hxx>
|
||||
#include <Include/fg_constants.h>
|
||||
#include <Misc/fgpath.hxx>
|
||||
#include <Misc/fgstream.hxx>
|
||||
#include <Misc/stopwatch.hxx>
|
||||
#include <Main/options.hxx>
|
||||
#include <Main/views.hxx>
|
||||
#include <Time/fg_time.hxx>
|
||||
#include "Misc/stopwatch.hxx"
|
||||
|
||||
#include "stars.hxx"
|
||||
|
||||
FG_USING_STD(getline);
|
||||
// FG_USING_STD(getline);
|
||||
|
||||
#define EpochStart (631065600)
|
||||
#define DaysSinceEpoch(secs) (((secs)-EpochStart)*(1.0/(24*3600)))
|
||||
|
||||
168
simgear/math/MAT3geom.c
Normal file
168
simgear/math/MAT3geom.c
Normal file
@@ -0,0 +1,168 @@
|
||||
/* #include "HEADERS.h" */
|
||||
/* Copyright 1988, Brown Computer Graphics Group. All Rights Reserved. */
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
* This file contains routines that perform geometry-related operations
|
||||
* on matrices.
|
||||
* -------------------------------------------------------------------------*/
|
||||
|
||||
#include "mat3defs.h"
|
||||
|
||||
/* -------------------------- Static Routines ---------------------------- */
|
||||
|
||||
/* ------------------------- Internal Routines --------------------------- */
|
||||
|
||||
/* -------------------------- Public Routines ---------------------------- */
|
||||
|
||||
/*
|
||||
* This takes a matrix used to transform points, and returns a corresponding
|
||||
* matrix that can be used to transform direction vectors (between points).
|
||||
*/
|
||||
|
||||
void
|
||||
MAT3direction_matrix(register double (*result_mat)[4], register double (*mat)[4])
|
||||
{
|
||||
register int i;
|
||||
|
||||
MAT3copy(result_mat, mat);
|
||||
|
||||
for (i = 0; i < 4; i++) result_mat[i][3] = result_mat[3][i] = 0.0;
|
||||
|
||||
result_mat[3][3] = 1.0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This takes a matrix used to transform points, and returns a corresponding
|
||||
* matrix that can be used to transform vectors that must remain perpendicular
|
||||
* to planes defined by the points. It is useful when you are transforming
|
||||
* some object that has both points and normals in its definition, and you
|
||||
* only have the transformation matrix for the points. This routine returns
|
||||
* FALSE if the normal matrix is uncomputable. Otherwise, it returns TRUE.
|
||||
*
|
||||
* Spike sez: "This is the adjoint for the non-homogeneous part of the
|
||||
* transformation."
|
||||
*/
|
||||
|
||||
int
|
||||
MAT3normal_matrix(register double (*result_mat)[4], register double (*mat)[4])
|
||||
{
|
||||
register int ret;
|
||||
MAT3mat tmp_mat;
|
||||
|
||||
MAT3direction_matrix(result_mat, mat);
|
||||
|
||||
if ( (ret = MAT3invert(tmp_mat, tmp_mat)) ) {
|
||||
MAT3transpose(result_mat, tmp_mat);
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the given matrix to be a scale matrix for the given vector of
|
||||
* scale values.
|
||||
*/
|
||||
|
||||
void
|
||||
MAT3scale(double (*result_mat)[4], double *scale)
|
||||
{
|
||||
MAT3identity(result_mat);
|
||||
|
||||
result_mat[0][0] = scale[0];
|
||||
result_mat[1][1] = scale[1];
|
||||
result_mat[2][2] = scale[2];
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets up a matrix for a rotation about an axis given by the line from
|
||||
* (0,0,0) to axis, through an angle (in radians).
|
||||
* Looking along the axis toward the origin, the rotation is counter-clockwise.
|
||||
*/
|
||||
|
||||
#define SELECT .7071 /* selection constant (roughly .5*sqrt(2) */
|
||||
|
||||
void
|
||||
MAT3rotate(double (*result_mat)[4], double *axis, double angle_in_radians)
|
||||
{
|
||||
MAT3vec naxis, /* Axis of rotation, normalized */
|
||||
base2, /* 2nd unit basis vec, perp to axis */
|
||||
base3; /* 3rd unit basis vec, perp to axis & base2 */
|
||||
double dot;
|
||||
MAT3mat base_mat, /* Change-of-basis matrix */
|
||||
base_mat_trans; /* Inverse of c-o-b matrix */
|
||||
register int i;
|
||||
|
||||
/* Step 1: extend { axis } to a basis for 3-space: { axis, base2, base3 }
|
||||
* which is orthonormal (all three have unit length, and all three are
|
||||
* mutually orthogonal). Also should be oriented, i.e. axis cross base2 =
|
||||
* base3, rather than -base3.
|
||||
*
|
||||
* Method: Find a vector linearly independent from axis. For this we
|
||||
* either use the y-axis, or, if that is too close to axis, the
|
||||
* z-axis. 'Too close' means that the dot product is too near to 1.
|
||||
*/
|
||||
|
||||
MAT3_COPY_VEC(naxis, axis);
|
||||
MAT3_NORMALIZE_VEC(naxis, dot);
|
||||
|
||||
if (dot == 0.0) {
|
||||
/* ERR_ERROR(MAT3_errid, ERR_SEVERE,
|
||||
(ERR_S, "Zero-length axis vector given to MAT3rotate")); */
|
||||
return;
|
||||
}
|
||||
|
||||
MAT3perp_vec(base2, naxis, TRUE);
|
||||
MAT3cross_product(base3, naxis, base2);
|
||||
|
||||
/* Set up the change-of-basis matrix, and its inverse */
|
||||
MAT3identity(base_mat);
|
||||
MAT3identity(base_mat_trans);
|
||||
MAT3identity(result_mat);
|
||||
|
||||
for (i = 0; i < 3; i++){
|
||||
base_mat_trans[i][0] = base_mat[0][i] = naxis[i];
|
||||
base_mat_trans[i][1] = base_mat[1][i] = base2[i];
|
||||
base_mat_trans[i][2] = base_mat[2][i] = base3[i];
|
||||
}
|
||||
|
||||
/* If T(u) = uR, where R is base_mat, then T(x-axis) = naxis,
|
||||
* T(y-axis) = base2, and T(z-axis) = base3. The inverse of base_mat is
|
||||
* its transpose. OK?
|
||||
*/
|
||||
|
||||
result_mat[1][1] = result_mat[2][2] = cos(angle_in_radians);
|
||||
result_mat[2][1] = -(result_mat[1][2] = sin(angle_in_radians));
|
||||
|
||||
MAT3mult(result_mat, base_mat_trans, result_mat);
|
||||
MAT3mult(result_mat, result_mat, base_mat);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the given matrix to be a translation matrix for the given vector of
|
||||
* translation values.
|
||||
*/
|
||||
|
||||
void
|
||||
MAT3translate(double (*result_mat)[4], double *trans)
|
||||
{
|
||||
MAT3identity(result_mat);
|
||||
|
||||
result_mat[3][0] = trans[0];
|
||||
result_mat[3][1] = trans[1];
|
||||
result_mat[3][2] = trans[2];
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the given matrix to be a shear matrix for the given x and y shear
|
||||
* values.
|
||||
*/
|
||||
|
||||
void
|
||||
MAT3shear(double (*result_mat)[4], double xshear, double yshear)
|
||||
{
|
||||
MAT3identity(result_mat);
|
||||
|
||||
result_mat[2][0] = xshear;
|
||||
result_mat[2][1] = yshear;
|
||||
}
|
||||
|
||||
311
simgear/math/MAT3inv.c
Normal file
311
simgear/math/MAT3inv.c
Normal file
@@ -0,0 +1,311 @@
|
||||
/* Copyright 1988, Brown Computer Graphics Group. All Rights Reserved. */
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
* This file contains routines that operate solely on matrices.
|
||||
* -------------------------------------------------------------------------*/
|
||||
|
||||
#include "mat3defs.h"
|
||||
|
||||
/* -------------------------- Static Routines ---------------------------- */
|
||||
|
||||
#define SMALL 1e-20 /* Small enough to be considered zero */
|
||||
|
||||
/*
|
||||
* Shuffles rows in inverse of 3x3. See comment in MAT3_inv3_second_col().
|
||||
*/
|
||||
|
||||
static void
|
||||
MAT3_inv3_swap( register double inv[3][3], int row0, int row1, int row2)
|
||||
{
|
||||
register int i, tempi;
|
||||
double temp;
|
||||
|
||||
#define SWAP_ROWS(a, b) \
|
||||
for (i = 0; i < 3; i++) SWAP(inv[a][i], inv[b][i], temp); \
|
||||
SWAP(a, b, tempi)
|
||||
|
||||
if (row0 != 0){
|
||||
if (row1 == 0) {
|
||||
SWAP_ROWS(row0, row1);
|
||||
}
|
||||
else {
|
||||
SWAP_ROWS(row0, row2);
|
||||
}
|
||||
}
|
||||
|
||||
if (row1 != 1) {
|
||||
SWAP_ROWS(row1, row2);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Does Gaussian elimination on second column.
|
||||
*/
|
||||
|
||||
static int
|
||||
MAT3_inv3_second_col (register double source[3][3], register double inv[3][3], int row0)
|
||||
{
|
||||
register int row1, row2, i1, i2, i;
|
||||
double temp;
|
||||
double a, b;
|
||||
|
||||
/* Find which row to use */
|
||||
if (row0 == 0) i1 = 1, i2 = 2;
|
||||
else if (row0 == 1) i1 = 0, i2 = 2;
|
||||
else i1 = 0, i2 = 1;
|
||||
|
||||
/* Find which is larger in abs. val.:the entry in [i1][1] or [i2][1] */
|
||||
/* and use that value for pivoting. */
|
||||
|
||||
a = source[i1][1]; if (a < 0) a = -a;
|
||||
b = source[i2][1]; if (b < 0) b = -b;
|
||||
if (a > b) row1 = i1;
|
||||
else row1 = i2;
|
||||
row2 = (row1 == i1 ? i2 : i1);
|
||||
|
||||
/* Scale row1 in source */
|
||||
if ((source[row1][1] < SMALL) && (source[row1][1] > -SMALL)) return(FALSE);
|
||||
temp = 1.0 / source[row1][1];
|
||||
source[row1][1] = 1.0;
|
||||
source[row1][2] *= temp; /* source[row1][0] is zero already */
|
||||
|
||||
/* Scale row1 in inv */
|
||||
inv[row1][row1] = temp; /* it used to be a 1.0 */
|
||||
inv[row1][row0] *= temp;
|
||||
|
||||
/* Clear column one, source, and make corresponding changes in inv */
|
||||
|
||||
for (i = 0; i < 3; i++) if (i != row1) { /* for i = all rows but row1 */
|
||||
temp = -source[i][1];
|
||||
source[i][1] = 0.0;
|
||||
source[i][2] += temp * source[row1][2];
|
||||
|
||||
inv[i][row1] = temp * inv[row1][row1];
|
||||
inv[i][row0] += temp * inv[row1][row0];
|
||||
}
|
||||
|
||||
/* Scale row2 in source */
|
||||
if ((source[row2][2] < SMALL) && (source[row2][2] > -SMALL)) return(FALSE);
|
||||
temp = 1.0 / source[row2][2];
|
||||
source[row2][2] = 1.0; /* source[row2][*] is zero already */
|
||||
|
||||
/* Scale row2 in inv */
|
||||
inv[row2][row2] = temp; /* it used to be a 1.0 */
|
||||
inv[row2][row0] *= temp;
|
||||
inv[row2][row1] *= temp;
|
||||
|
||||
/* Clear column one, source, and make corresponding changes in inv */
|
||||
for (i = 0; i < 3; i++) if (i != row2) { /* for i = all rows but row2 */
|
||||
temp = -source[i][2];
|
||||
source[i][2] = 0.0;
|
||||
inv[i][row0] += temp * inv[row2][row0];
|
||||
inv[i][row1] += temp * inv[row2][row1];
|
||||
inv[i][row2] += temp * inv[row2][row2];
|
||||
}
|
||||
|
||||
/*
|
||||
* Now all is done except that the inverse needs to have its rows shuffled.
|
||||
* row0 needs to be moved to inv[0][*], row1 to inv[1][*], etc.
|
||||
*
|
||||
* We *didn't* do the swapping before the elimination so that we could more
|
||||
* easily keep track of what ops are needed to be done in the inverse.
|
||||
*/
|
||||
MAT3_inv3_swap(inv, row0, row1, row2);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fast inversion routine for 3 x 3 matrices. - Written by jfh.
|
||||
*
|
||||
* This takes 30 multiplies/divides, as opposed to 39 for Cramer's Rule.
|
||||
* The algorithm consists of performing fast gaussian elimination, by never
|
||||
* doing any operations where the result is guaranteed to be zero, or where
|
||||
* one operand is guaranteed to be zero. This is done at the cost of clarity,
|
||||
* alas.
|
||||
*
|
||||
* Returns 1 if the inverse was successful, 0 if it failed.
|
||||
*/
|
||||
|
||||
static int
|
||||
MAT3_invert3 (register double source[3][3], register double inv[3][3])
|
||||
{
|
||||
register int i, row0;
|
||||
double temp;
|
||||
double a, b, c;
|
||||
|
||||
inv[0][0] = inv[1][1] = inv[2][2] = 1.0;
|
||||
inv[0][1] = inv[0][2] = inv[1][0] = inv[1][2] = inv[2][0] = inv[2][1] = 0.0;
|
||||
|
||||
/* attempt to find the largest entry in first column to use as pivot */
|
||||
a = source[0][0]; if (a < 0) a = -a;
|
||||
b = source[1][0]; if (b < 0) b = -b;
|
||||
c = source[2][0]; if (c < 0) c = -c;
|
||||
|
||||
if (a > b) {
|
||||
if (a > c) row0 = 0;
|
||||
else row0 = 2;
|
||||
}
|
||||
else {
|
||||
if (b > c) row0 = 1;
|
||||
else row0 = 2;
|
||||
}
|
||||
|
||||
/* Scale row0 of source */
|
||||
if ((source[row0][0] < SMALL) && (source[row0][0] > -SMALL)) return(FALSE);
|
||||
temp = 1.0 / source[row0][0];
|
||||
source[row0][0] = 1.0;
|
||||
source[row0][1] *= temp;
|
||||
source[row0][2] *= temp;
|
||||
|
||||
/* Scale row0 of inverse */
|
||||
inv[row0][row0] = temp; /* other entries are zero -- no effort */
|
||||
|
||||
/* Clear column zero of source, and make corresponding changes in inverse */
|
||||
|
||||
for (i = 0; i < 3; i++) if (i != row0) { /* for i = all rows but row0 */
|
||||
temp = -source[i][0];
|
||||
source[i][0] = 0.0;
|
||||
source[i][1] += temp * source[row0][1];
|
||||
source[i][2] += temp * source[row0][2];
|
||||
inv[i][row0] = temp * inv[row0][row0];
|
||||
}
|
||||
|
||||
/*
|
||||
* We've now done gaussian elimination so that the source and
|
||||
* inverse look like this:
|
||||
*
|
||||
* 1 * * * 0 0
|
||||
* 0 * * * 1 0
|
||||
* 0 * * * 0 1
|
||||
*
|
||||
* We now proceed to do elimination on the second column.
|
||||
*/
|
||||
if (! MAT3_inv3_second_col(source, inv, row0)) return(FALSE);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Finds a new pivot for a non-simple 4x4. See comments in MAT3invert().
|
||||
*/
|
||||
|
||||
static int
|
||||
MAT3_inv4_pivot (register MAT3mat src, MAT3vec r, double *s, int *swap)
|
||||
{
|
||||
register int i, j;
|
||||
double temp, max;
|
||||
|
||||
*swap = -1;
|
||||
|
||||
if (MAT3_IS_ZERO(src[3][3])) {
|
||||
|
||||
/* Look for a different pivot element: one with largest abs value */
|
||||
max = 0.0;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (src[i][3] > max) max = src[*swap = i][3];
|
||||
else if (src[i][3] < -max) max = -src[*swap = i][3];
|
||||
}
|
||||
|
||||
/* No pivot element available ! */
|
||||
if (*swap < 0) return(FALSE);
|
||||
|
||||
else for (j = 0; j < 4; j++) SWAP(src[*swap][j], src[3][j], temp);
|
||||
}
|
||||
|
||||
MAT3_SET_VEC (r, -src[0][3], -src[1][3], -src[2][3]);
|
||||
|
||||
*s = 1.0 / src[3][3];
|
||||
|
||||
src[0][3] = src[1][3] = src[2][3] = 0.0;
|
||||
src[3][3] = 1.0;
|
||||
|
||||
MAT3_SCALE_VEC(src[3], src[3], *s);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
src[0][i] += r[0] * src[3][i];
|
||||
src[1][i] += r[1] * src[3][i];
|
||||
src[2][i] += r[2] * src[3][i];
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/* ------------------------- Internal Routines --------------------------- */
|
||||
|
||||
/* -------------------------- Public Routines ---------------------------- */
|
||||
|
||||
/*
|
||||
* This returns the inverse of the given matrix. The result matrix
|
||||
* may be the same as the one to invert.
|
||||
*
|
||||
* Fast inversion routine for 4 x 4 matrices, written by jfh.
|
||||
*
|
||||
* Returns 1 if the inverse was successful, 0 if it failed.
|
||||
*
|
||||
* This routine has been specially tweaked to notice the following:
|
||||
* If the matrix has the form
|
||||
* * * * 0
|
||||
* * * * 0
|
||||
* * * * 0
|
||||
* * * * 1
|
||||
*
|
||||
* (as do many matrices in graphics), then we compute the inverse of
|
||||
* the upper left 3x3 matrix and use this to find the general inverse.
|
||||
*
|
||||
* In the event that the right column is not 0-0-0-1, we do gaussian
|
||||
* elimination to make it so, then use the 3x3 inverse, and then do
|
||||
* our gaussian elimination.
|
||||
*/
|
||||
|
||||
int
|
||||
MAT3invert(double (*result_mat)[4], double (*mat)[4])
|
||||
{
|
||||
MAT3mat src, inv;
|
||||
register int i, j, simple;
|
||||
double m[3][3], inv3[3][3], s, temp;
|
||||
MAT3vec r, t;
|
||||
int swap;
|
||||
|
||||
MAT3copy(src, mat);
|
||||
MAT3identity(inv);
|
||||
|
||||
/* If last column is not (0,0,0,1), use special code */
|
||||
simple = (mat[0][3] == 0.0 && mat[1][3] == 0.0 &&
|
||||
mat[2][3] == 0.0 && mat[3][3] == 1.0);
|
||||
|
||||
if (! simple && ! MAT3_inv4_pivot(src, r, &s, &swap)) return(FALSE);
|
||||
|
||||
MAT3_COPY_VEC(t, src[3]); /* Translation vector */
|
||||
|
||||
/* Copy upper-left 3x3 matrix */
|
||||
for (i = 0; i < 3; i++) for (j = 0; j < 3; j++) m[i][j] = src[i][j];
|
||||
|
||||
if (! MAT3_invert3(m, inv3)) return(FALSE);
|
||||
|
||||
for (i = 0; i < 3; i++) for (j = 0; j < 3; j++) inv[i][j] = inv3[i][j];
|
||||
|
||||
for (i = 0; i < 3; i++) for (j = 0; j < 3; j++)
|
||||
inv[3][i] -= t[j] * inv3[j][i];
|
||||
|
||||
if (! simple) {
|
||||
|
||||
/* We still have to undo our gaussian elimination from earlier on */
|
||||
/* add r0 * first col to last col */
|
||||
/* add r1 * 2nd col to last col */
|
||||
/* add r2 * 3rd col to last col */
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
inv[i][3] += r[0] * inv[i][0] + r[1] * inv[i][1] + r[2] * inv[i][2];
|
||||
inv[i][3] *= s;
|
||||
}
|
||||
|
||||
if (swap >= 0)
|
||||
for (i = 0; i < 4; i++) SWAP(inv[i][swap], inv[i][3], temp);
|
||||
}
|
||||
|
||||
MAT3copy(result_mat, inv);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
120
simgear/math/MAT3mat.c
Normal file
120
simgear/math/MAT3mat.c
Normal file
@@ -0,0 +1,120 @@
|
||||
/* #include "HEADERS.h" */
|
||||
/* Copyright 1988, Brown Computer Graphics Group. All Rights Reserved. */
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
* This file contains routines that operate solely on matrices.
|
||||
* -------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
# ifndef HAVE_STL_SGI_PORT
|
||||
# ifdef __BORLANDC__
|
||||
# include <mem.h>
|
||||
# else
|
||||
# include <memory.h> /* required for memset() and memcpy() */
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include "mat3defs.h"
|
||||
|
||||
MAT3mat identityMatrix = {
|
||||
{ 1.0, 0.0, 0.0, 0.0 },
|
||||
{ 0.0, 1.0, 0.0, 0.0 },
|
||||
{ 0.0, 0.0, 1.0, 0.0 },
|
||||
{ 0.0, 0.0, 0.0, 1.0 }
|
||||
};
|
||||
|
||||
/* #include "macros.h" */
|
||||
|
||||
/* -------------------------- Static Routines ---------------------------- */
|
||||
|
||||
/* ------------------------- Internal Routines --------------------------- */
|
||||
|
||||
/* -------------------------- Public Routines ---------------------------- */
|
||||
|
||||
|
||||
#if !defined( USE_XTRA_MAT3_INLINES )
|
||||
|
||||
/*
|
||||
* This multiplies two matrices, producing a third, which may the same as
|
||||
* either of the first two.
|
||||
*/
|
||||
|
||||
void
|
||||
MAT3mult (double (*result_mat)[4], register double (*mat1)[4], register double (*mat2)[4])
|
||||
{
|
||||
register int i, j;
|
||||
MAT3mat tmp_mat;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
for (j = 0; j < 4; j++)
|
||||
tmp_mat[i][j] = (mat1[i][0] * mat2[0][j] +
|
||||
mat1[i][1] * mat2[1][j] +
|
||||
mat1[i][2] * mat2[2][j] +
|
||||
mat1[i][3] * mat2[3][j]);
|
||||
MAT3copy (result_mat, tmp_mat);
|
||||
}
|
||||
#endif // !defined( USE_XTRA_MAT3_INLINES )
|
||||
|
||||
/*
|
||||
* This returns the transpose of a matrix. The result matrix may be
|
||||
* the same as the one to transpose.
|
||||
*/
|
||||
|
||||
void
|
||||
MAT3transpose (double (*result_mat)[4], register double (*mat)[4])
|
||||
{
|
||||
register int i, j;
|
||||
MAT3mat tmp_mat;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
for (j = 0; j < 4; j++)
|
||||
tmp_mat[i][j] = mat[j][i];
|
||||
|
||||
MAT3copy (result_mat, tmp_mat);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This prints the given matrix to the given file pointer.
|
||||
*/
|
||||
|
||||
void
|
||||
MAT3print(double (*mat)[4], FILE *fp)
|
||||
{
|
||||
MAT3print_formatted(mat, fp, CNULL, CNULL, CNULL, CNULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* This prints the given matrix to the given file pointer.
|
||||
* use the format string to pass to fprintf. head and tail
|
||||
* are printed at the beginning and end of each line.
|
||||
*/
|
||||
|
||||
void
|
||||
MAT3print_formatted(double (*mat)[4], FILE *fp, char *title, char *head, char *format, char *tail)
|
||||
{
|
||||
register int i, j;
|
||||
|
||||
/* This is to allow this to be called easily from a debugger */
|
||||
if (fp == NULL) fp = stderr;
|
||||
|
||||
if (title == NULL) title = "MAT3 matrix:\n";
|
||||
if (head == NULL) head = " ";
|
||||
if (format == NULL) format = "%#8.4lf ";
|
||||
if (tail == NULL) tail = "\n";
|
||||
|
||||
(void) fprintf(fp, title);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
(void) fprintf(fp, head);
|
||||
for (j = 0; j < 4; j++) (void) fprintf(fp, format, mat[i][j]);
|
||||
(void) fprintf(fp, tail);
|
||||
}
|
||||
}
|
||||
154
simgear/math/MAT3vec.c
Normal file
154
simgear/math/MAT3vec.c
Normal file
@@ -0,0 +1,154 @@
|
||||
/* Copyright 1988, Brown Computer Graphics Group. All Rights Reserved. */
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
* This file contains routines that operate on matrices and vectors, or
|
||||
* vectors and vectors.
|
||||
* -------------------------------------------------------------------------*/
|
||||
|
||||
/* #include "sphigslocal.h" */
|
||||
|
||||
/* -------------------------- Static Routines ---------------------------- */
|
||||
|
||||
/* ------------------------- Internal Routines --------------------------- */
|
||||
|
||||
/* -------------------------- Public Routines ---------------------------- */
|
||||
|
||||
/*
|
||||
* Multiplies a vector by a matrix, setting the result vector.
|
||||
* It assumes all homogeneous coordinates are 1.
|
||||
* The two vectors involved may be the same.
|
||||
*/
|
||||
|
||||
#include "mat3.h"
|
||||
|
||||
#ifndef TRUE
|
||||
# define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
# define FALSE 0
|
||||
#endif
|
||||
|
||||
#if !defined( USE_XTRA_MAT3_INLINES )
|
||||
|
||||
void
|
||||
MAT3mult_vec(double *result_vec, register double *vec, register double (*mat)[4])
|
||||
{
|
||||
MAT3vec tempvec;
|
||||
register double *temp = tempvec;
|
||||
|
||||
temp[0] = vec[0] * mat[0][0] + vec[1] * mat[1][0] +
|
||||
vec[2] * mat[2][0] + mat[3][0];
|
||||
temp[1] = vec[0] * mat[0][1] + vec[1] * mat[1][1] +
|
||||
vec[2] * mat[2][1] + mat[3][1];
|
||||
temp[2] = vec[0] * mat[0][2] + vec[1] * mat[1][2] +
|
||||
vec[2] * mat[2][2] + mat[3][2];
|
||||
|
||||
MAT3_COPY_VEC(result_vec, temp);
|
||||
}
|
||||
#endif // !defined( USE_XTRA_MAT3_INLINES )
|
||||
|
||||
/*
|
||||
* Multiplies a vector of size 4 by a matrix, setting the result vector.
|
||||
* The fourth element of the vector is the homogeneous coordinate, which
|
||||
* may or may not be 1. If the "normalize" parameter is TRUE, then the
|
||||
* result vector will be normalized so that the homogeneous coordinate is 1.
|
||||
* The two vectors involved may be the same.
|
||||
* This returns zero if the vector was to be normalized, but couldn't be.
|
||||
*/
|
||||
|
||||
int
|
||||
MAT3mult_hvec(double *result_vec, register double *vec, register double (*mat)[4], int normalize)
|
||||
{
|
||||
MAT3hvec tempvec;
|
||||
double norm_fac;
|
||||
register double *temp = tempvec;
|
||||
register int ret = TRUE;
|
||||
|
||||
temp[0] = vec[0] * mat[0][0] + vec[1] * mat[1][0] +
|
||||
vec[2] * mat[2][0] + vec[3] * mat[3][0];
|
||||
temp[1] = vec[0] * mat[0][1] + vec[1] * mat[1][1] +
|
||||
vec[2] * mat[2][1] + vec[3] * mat[3][1];
|
||||
temp[2] = vec[0] * mat[0][2] + vec[1] * mat[1][2] +
|
||||
vec[2] * mat[2][2] + vec[3] * mat[3][2];
|
||||
temp[3] = vec[0] * mat[0][3] + vec[1] * mat[1][3] +
|
||||
vec[2] * mat[2][3] + vec[3] * mat[3][3];
|
||||
|
||||
/* Normalize if asked for, possible, and necessary */
|
||||
if (normalize) {
|
||||
if (MAT3_IS_ZERO(temp[3])) {
|
||||
#ifndef THINK_C
|
||||
fprintf (stderr,
|
||||
"Can't normalize vector: homogeneous coordinate is 0");
|
||||
#endif
|
||||
ret = FALSE;
|
||||
}
|
||||
else {
|
||||
norm_fac = 1.0 / temp[3];
|
||||
MAT3_SCALE_VEC(result_vec, temp, norm_fac);
|
||||
result_vec[3] = 1.0;
|
||||
}
|
||||
}
|
||||
else MAT3_COPY_HVEC(result_vec, temp);
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
#if !defined( USE_XTRA_MAT3_INLINES )
|
||||
|
||||
/*
|
||||
* Sets the first vector to be the cross-product of the last two vectors.
|
||||
*/
|
||||
|
||||
void
|
||||
MAT3cross_product(double *result_vec, register double *vec1, register double *vec2)
|
||||
{
|
||||
MAT3vec tempvec;
|
||||
register double *temp = tempvec;
|
||||
|
||||
temp[0] = vec1[1] * vec2[2] - vec1[2] * vec2[1];
|
||||
temp[1] = vec1[2] * vec2[0] - vec1[0] * vec2[2];
|
||||
temp[2] = vec1[0] * vec2[1] - vec1[1] * vec2[0];
|
||||
|
||||
MAT3_COPY_VEC(result_vec, temp);
|
||||
}
|
||||
#endif // !defined( USE_XTRA_MAT3_INLINES )
|
||||
|
||||
/*
|
||||
* Finds a vector perpendicular to vec and stores it in result_vec.
|
||||
* Method: take any vector (we use <0,1,0>) and subtract the
|
||||
* portion of it pointing in the vec direction. This doesn't
|
||||
* work if vec IS <0,1,0> or is very near it. So if this is
|
||||
* the case, use <0,0,1> instead.
|
||||
* If "is_unit" is TRUE, the given vector is assumed to be unit length.
|
||||
*/
|
||||
|
||||
#define SELECT .7071 /* selection constant (roughly .5*sqrt(2) */
|
||||
|
||||
void
|
||||
MAT3perp_vec(double *result_vec, double *vec, int is_unit)
|
||||
{
|
||||
MAT3vec norm;
|
||||
double dot;
|
||||
|
||||
MAT3_SET_VEC(result_vec, 0.0, 1.0, 0.0);
|
||||
|
||||
MAT3_COPY_VEC(norm, vec);
|
||||
|
||||
if (! is_unit) MAT3_NORMALIZE_VEC(norm, dot);
|
||||
|
||||
/* See if vector is too close to <0,1,0>. If so, use <0,0,1> */
|
||||
if ((dot = MAT3_DOT_PRODUCT(norm, result_vec)) > SELECT || dot < -SELECT) {
|
||||
result_vec[1] = 0.0;
|
||||
result_vec[2] = 1.0;
|
||||
dot = MAT3_DOT_PRODUCT(norm, result_vec);
|
||||
}
|
||||
|
||||
/* Subtract off non-perpendicular part */
|
||||
result_vec[0] -= dot * norm[0];
|
||||
result_vec[1] -= dot * norm[1];
|
||||
result_vec[2] -= dot * norm[2];
|
||||
|
||||
/* Make result unit length */
|
||||
MAT3_NORMALIZE_VEC(result_vec, dot);
|
||||
}
|
||||
32
simgear/math/Makefile.am
Normal file
32
simgear/math/Makefile.am
Normal file
@@ -0,0 +1,32 @@
|
||||
includedir = @includedir@/math
|
||||
|
||||
lib_LIBRARIES = libsgmath.a
|
||||
|
||||
include_HEADERS = \
|
||||
fg_geodesy.hxx \
|
||||
fg_memory.h \
|
||||
fg_random.h \
|
||||
fg_types.hxx \
|
||||
interpolater.hxx \
|
||||
leastsqs.hxx \
|
||||
mat3.h \
|
||||
point3d.hxx \
|
||||
polar3d.hxx \
|
||||
vector.hxx
|
||||
|
||||
EXTRA_DIST = linintp2.h linintp2.inl sphrintp.h sphrintp.inl
|
||||
|
||||
libsgmath_a_SOURCES = \
|
||||
MAT3geom.c \
|
||||
MAT3inv.c \
|
||||
MAT3mat.c \
|
||||
MAT3vec.c \
|
||||
fg_geodesy.cxx \
|
||||
fg_random.c \
|
||||
interpolater.cxx \
|
||||
leastsqs.cxx \
|
||||
mat3defs.h mat3err.h \
|
||||
polar3d.cxx \
|
||||
vector.cxx
|
||||
|
||||
INCLUDES += -I$(top_builddir)/src
|
||||
446
simgear/math/fg_geodesy.cxx
Normal file
446
simgear/math/fg_geodesy.cxx
Normal file
@@ -0,0 +1,446 @@
|
||||
// fg_geodesy.cxx -- routines to convert between geodetic and geocentric
|
||||
// coordinate systems.
|
||||
//
|
||||
// Copied and adapted directly from LaRCsim/ls_geodesy.c
|
||||
//
|
||||
// See below for the complete original LaRCsim comments.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#ifdef FG_HAVE_STD_INCLUDES
|
||||
# include <cmath>
|
||||
# include <cerrno>
|
||||
#else
|
||||
# include <math.h>
|
||||
# include <errno.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/constants.h>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#include "point3d.hxx"
|
||||
#include "fg_geodesy.hxx"
|
||||
|
||||
#ifndef FG_HAVE_NATIVE_SGI_COMPILERS
|
||||
FG_USING_STD(cout);
|
||||
#endif
|
||||
|
||||
// ONE_SECOND is pi/180/60/60, or about 100 feet at earths' equator
|
||||
#define ONE_SECOND 4.848136811E-6
|
||||
|
||||
|
||||
// fgGeocToGeod(lat_geoc, radius, *lat_geod, *alt, *sea_level_r)
|
||||
// INPUTS:
|
||||
// lat_geoc Geocentric latitude, radians, + = North
|
||||
// radius C.G. radius to earth center (meters)
|
||||
//
|
||||
// OUTPUTS:
|
||||
// lat_geod Geodetic latitude, radians, + = North
|
||||
// alt C.G. altitude above mean sea level (meters)
|
||||
// sea_level_r radius from earth center to sea level at
|
||||
// local vertical (surface normal) of C.G. (meters)
|
||||
|
||||
|
||||
void fgGeocToGeod( double lat_geoc, double radius, double
|
||||
*lat_geod, double *alt, double *sea_level_r )
|
||||
{
|
||||
double t_lat, x_alpha, mu_alpha, delt_mu, r_alpha, l_point, rho_alpha;
|
||||
double sin_mu_a, denom,delt_lambda, lambda_sl, sin_lambda_sl;
|
||||
|
||||
if( ( (FG_PI_2 - lat_geoc) < ONE_SECOND ) // near North pole
|
||||
|| ( (FG_PI_2 + lat_geoc) < ONE_SECOND ) ) // near South pole
|
||||
{
|
||||
*lat_geod = lat_geoc;
|
||||
*sea_level_r = EQUATORIAL_RADIUS_M*E;
|
||||
*alt = radius - *sea_level_r;
|
||||
} else {
|
||||
t_lat = tan(lat_geoc);
|
||||
x_alpha = E*EQUATORIAL_RADIUS_M/sqrt(t_lat*t_lat + E*E);
|
||||
double tmp = RESQ_M - x_alpha * x_alpha;
|
||||
if ( tmp < 0.0 ) { tmp = 0.0; }
|
||||
mu_alpha = atan2(sqrt(tmp),E*x_alpha);
|
||||
if (lat_geoc < 0) mu_alpha = - mu_alpha;
|
||||
sin_mu_a = sin(mu_alpha);
|
||||
delt_lambda = mu_alpha - lat_geoc;
|
||||
r_alpha = x_alpha/cos(lat_geoc);
|
||||
l_point = radius - r_alpha;
|
||||
*alt = l_point*cos(delt_lambda);
|
||||
|
||||
// check for domain error
|
||||
if ( errno == EDOM ) {
|
||||
FG_LOG( FG_GENERAL, FG_ALERT, "Domain ERROR in fgGeocToGeod!!!!" );
|
||||
*alt = 0.0;
|
||||
}
|
||||
|
||||
denom = sqrt(1-EPS*EPS*sin_mu_a*sin_mu_a);
|
||||
rho_alpha = EQUATORIAL_RADIUS_M*(1-EPS)/
|
||||
(denom*denom*denom);
|
||||
delt_mu = atan2(l_point*sin(delt_lambda),rho_alpha + *alt);
|
||||
*lat_geod = mu_alpha - delt_mu;
|
||||
lambda_sl = atan( E*E * tan(*lat_geod) ); // SL geoc. latitude
|
||||
sin_lambda_sl = sin( lambda_sl );
|
||||
*sea_level_r =
|
||||
sqrt(RESQ_M / (1 + ((1/(E*E))-1)*sin_lambda_sl*sin_lambda_sl));
|
||||
|
||||
// check for domain error
|
||||
if ( errno == EDOM ) {
|
||||
FG_LOG( FG_GENERAL, FG_ALERT, "Domain ERROR in fgGeocToGeod!!!!" );
|
||||
*sea_level_r = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// fgGeodToGeoc( lat_geod, alt, *sl_radius, *lat_geoc )
|
||||
// INPUTS:
|
||||
// lat_geod Geodetic latitude, radians, + = North
|
||||
// alt C.G. altitude above mean sea level (meters)
|
||||
//
|
||||
// OUTPUTS:
|
||||
// sl_radius SEA LEVEL radius to earth center (meters)
|
||||
// (add Altitude to get true distance from earth center.
|
||||
// lat_geoc Geocentric latitude, radians, + = North
|
||||
//
|
||||
|
||||
|
||||
void fgGeodToGeoc( double lat_geod, double alt, double *sl_radius,
|
||||
double *lat_geoc )
|
||||
{
|
||||
double lambda_sl, sin_lambda_sl, cos_lambda_sl, sin_mu, cos_mu, px, py;
|
||||
|
||||
lambda_sl = atan( E*E * tan(lat_geod) ); // sea level geocentric latitude
|
||||
sin_lambda_sl = sin( lambda_sl );
|
||||
cos_lambda_sl = cos( lambda_sl );
|
||||
sin_mu = sin(lat_geod); // Geodetic (map makers') latitude
|
||||
cos_mu = cos(lat_geod);
|
||||
*sl_radius =
|
||||
sqrt(RESQ_M / (1 + ((1/(E*E))-1)*sin_lambda_sl*sin_lambda_sl));
|
||||
py = *sl_radius*sin_lambda_sl + alt*sin_mu;
|
||||
px = *sl_radius*cos_lambda_sl + alt*cos_mu;
|
||||
*lat_geoc = atan2( py, px );
|
||||
}
|
||||
|
||||
|
||||
// Direct and inverse distance functions
|
||||
//
|
||||
// Proceedings of the 7th International Symposium on Geodetic
|
||||
// Computations, 1985
|
||||
//
|
||||
// "The Nested Coefficient Method for Accurate Solutions of Direct and
|
||||
// Inverse Geodetic Problems With Any Length"
|
||||
//
|
||||
// Zhang Xue-Lian
|
||||
// pp 747-763
|
||||
//
|
||||
// modified for FlightGear to use WGS84 only -- Norman Vine
|
||||
|
||||
#define GEOD_INV_PI FG_PI
|
||||
|
||||
// s == distance
|
||||
// az = azimuth
|
||||
|
||||
// for WGS_84 a = 6378137.000, rf = 298.257223563;
|
||||
|
||||
static double M0( double e2 ) {
|
||||
//double e4 = e2*e2;
|
||||
return GEOD_INV_PI*(1.0 - e2*( 1.0/4.0 + e2*( 3.0/64.0 +
|
||||
e2*(5.0/256.0) )))/2.0;
|
||||
}
|
||||
|
||||
|
||||
// given, alt, lat1, lon1, az1 and distance (s), calculate lat2, lon2
|
||||
// and az2. Lat, lon, and azimuth are in degrees. distance in meters
|
||||
int geo_direct_wgs_84 ( double alt, double lat1, double lon1, double az1,
|
||||
double s, double *lat2, double *lon2, double *az2 )
|
||||
{
|
||||
double a = 6378137.000, rf = 298.257223563;
|
||||
double RADDEG = (GEOD_INV_PI)/180.0, testv = 1.0E-10;
|
||||
double f = ( rf > 0.0 ? 1.0/rf : 0.0 );
|
||||
double b = a*(1.0-f);
|
||||
double e2 = f*(2.0-f);
|
||||
double phi1 = lat1*RADDEG, lam1 = lon1*RADDEG;
|
||||
double sinphi1 = sin(phi1), cosphi1 = cos(phi1);
|
||||
double azm1 = az1*RADDEG;
|
||||
double sinaz1 = sin(azm1), cosaz1 = cos(azm1);
|
||||
|
||||
|
||||
if( fabs(s) < 0.01 ) { // distance < centimeter => congruency
|
||||
*lat2 = lat1;
|
||||
*lon2 = lon1;
|
||||
*az2 = 180.0 + az1;
|
||||
if( *az2 > 360.0 ) *az2 -= 360.0;
|
||||
return 0;
|
||||
} else if( cosphi1 ) { // non-polar origin
|
||||
// u1 is reduced latitude
|
||||
double tanu1 = sqrt(1.0-e2)*sinphi1/cosphi1;
|
||||
double sig1 = atan2(tanu1,cosaz1);
|
||||
double cosu1 = 1.0/sqrt( 1.0 + tanu1*tanu1 ), sinu1 = tanu1*cosu1;
|
||||
double sinaz = cosu1*sinaz1, cos2saz = 1.0-sinaz*sinaz;
|
||||
double us = cos2saz*e2/(1.0-e2);
|
||||
|
||||
// Terms
|
||||
double ta = 1.0+us*(4096.0+us*(-768.0+us*(320.0-175.0*us)))/16384.0,
|
||||
tb = us*(256.0+us*(-128.0+us*(74.0-47.0*us)))/1024.0,
|
||||
tc = 0;
|
||||
|
||||
// FIRST ESTIMATE OF SIGMA (SIG)
|
||||
double first = s/(b*ta); // !!
|
||||
double sig = first;
|
||||
double c2sigm, sinsig,cossig, temp,denom,rnumer, dlams, dlam;
|
||||
do {
|
||||
c2sigm = cos(2.0*sig1+sig);
|
||||
sinsig = sin(sig); cossig = cos(sig);
|
||||
temp = sig;
|
||||
sig = first +
|
||||
tb*sinsig*(c2sigm+tb*(cossig*(-1.0+2.0*c2sigm*c2sigm) -
|
||||
tb*c2sigm*(-3.0+4.0*sinsig*sinsig)
|
||||
*(-3.0+4.0*c2sigm*c2sigm)/6.0)
|
||||
/4.0);
|
||||
} while( fabs(sig-temp) > testv);
|
||||
|
||||
// LATITUDE OF POINT 2
|
||||
// DENOMINATOR IN 2 PARTS (TEMP ALSO USED LATER)
|
||||
temp = sinu1*sinsig-cosu1*cossig*cosaz1;
|
||||
denom = (1.0-f)*sqrt(sinaz*sinaz+temp*temp);
|
||||
|
||||
// NUMERATOR
|
||||
rnumer = sinu1*cossig+cosu1*sinsig*cosaz1;
|
||||
*lat2 = atan2(rnumer,denom)/RADDEG;
|
||||
|
||||
// DIFFERENCE IN LONGITUDE ON AUXILARY SPHERE (DLAMS )
|
||||
rnumer = sinsig*sinaz1;
|
||||
denom = cosu1*cossig-sinu1*sinsig*cosaz1;
|
||||
dlams = atan2(rnumer,denom);
|
||||
|
||||
// TERM C
|
||||
tc = f*cos2saz*(4.0+f*(4.0-3.0*cos2saz))/16.0;
|
||||
|
||||
// DIFFERENCE IN LONGITUDE
|
||||
dlam = dlams-(1.0-tc)*f*sinaz*(sig+tc*sinsig*
|
||||
(c2sigm+
|
||||
tc*cossig*(-1.0+2.0*
|
||||
c2sigm*c2sigm)));
|
||||
*lon2 = (lam1+dlam)/RADDEG;
|
||||
if (*lon2 > 180.0 ) *lon2 -= 360.0;
|
||||
if (*lon2 < -180.0 ) *lon2 += 360.0;
|
||||
|
||||
// AZIMUTH - FROM NORTH
|
||||
*az2 = atan2(-sinaz,temp)/RADDEG;
|
||||
if ( fabs(*az2) < testv ) *az2 = 0.0;
|
||||
if( *az2 < 0.0) *az2 += 360.0;
|
||||
return 0;
|
||||
} else { // phi1 == 90 degrees, polar origin
|
||||
double dM = a*M0(e2) - s;
|
||||
double paz = ( phi1 < 0.0 ? 180.0 : 0.0 );
|
||||
return geo_direct_wgs_84( alt, 0.0, lon1, paz, dM,lat2,lon2,az2 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// given alt, lat1, lon1, lat2, lon2, calculate starting and ending
|
||||
// az1, az2 and distance (s). Lat, lon, and azimuth are in degrees.
|
||||
// distance in meters
|
||||
int geo_inverse_wgs_84( double alt, double lat1, double lon1, double lat2,
|
||||
double lon2, double *az1, double *az2, double *s )
|
||||
{
|
||||
double a = 6378137.000, rf = 298.257223563;
|
||||
int iter=0;
|
||||
double RADDEG = (GEOD_INV_PI)/180.0, testv = 1.0E-10;
|
||||
double f = ( rf > 0.0 ? 1.0/rf : 0.0 );
|
||||
double b = a*(1.0-f);
|
||||
// double e2 = f*(2.0-f); // unused in this routine
|
||||
double phi1 = lat1*RADDEG, lam1 = lon1*RADDEG;
|
||||
double sinphi1 = sin(phi1), cosphi1 = cos(phi1);
|
||||
double phi2 = lat2*RADDEG, lam2 = lon2*RADDEG;
|
||||
double sinphi2 = sin(phi2), cosphi2 = cos(phi2);
|
||||
|
||||
if( (fabs(lat1-lat2) < testv &&
|
||||
( fabs(lon1-lon2) < testv) || fabs(lat1-90.0) < testv ) )
|
||||
{
|
||||
// TWO STATIONS ARE IDENTICAL : SET DISTANCE & AZIMUTHS TO ZERO */
|
||||
*az1 = 0.0; *az2 = 0.0; *s = 0.0;
|
||||
return 0;
|
||||
} else if( fabs(cosphi1) < testv ) {
|
||||
// initial point is polar
|
||||
int k = geo_inverse_wgs_84( alt, lat2,lon2,lat1,lon1, az1,az2,s );
|
||||
k = k; // avoid compiler error since return result is unused
|
||||
b = *az1; *az1 = *az2; *az2 = b;
|
||||
return 0;
|
||||
} else if( fabs(cosphi2) < testv ) {
|
||||
// terminal point is polar
|
||||
int k = geo_inverse_wgs_84( alt, lat1,lon1,lat1,lon1+180.0,
|
||||
az1,az2,s );
|
||||
k = k; // avoid compiler error since return result is unused
|
||||
*s /= 2.0;
|
||||
*az2 = *az1 + 180.0;
|
||||
if( *az2 > 360.0 ) *az2 -= 360.0;
|
||||
return 0;
|
||||
} else if( (fabs( fabs(lon1-lon2) - 180 ) < testv) &&
|
||||
(fabs(lat1+lat2) < testv) )
|
||||
{
|
||||
// Geodesic passes through the pole (antipodal)
|
||||
double s1,s2;
|
||||
geo_inverse_wgs_84( alt, lat1,lon1, lat1,lon2, az1,az2, &s1 );
|
||||
geo_inverse_wgs_84( alt, lat2,lon2, lat1,lon2, az1,az2, &s2 );
|
||||
*az2 = *az1;
|
||||
*s = s1 + s2;
|
||||
return 0;
|
||||
} else {
|
||||
// antipodal and polar points don't get here
|
||||
double dlam = lam2 - lam1, dlams = dlam;
|
||||
double sdlams,cdlams, sig,sinsig,cossig, sinaz,
|
||||
cos2saz, c2sigm;
|
||||
double tc,temp, us,rnumer,denom, ta,tb;
|
||||
double cosu1,sinu1, sinu2,cosu2;
|
||||
|
||||
// Reduced latitudes
|
||||
temp = (1.0-f)*sinphi1/cosphi1;
|
||||
cosu1 = 1.0/sqrt(1.0+temp*temp);
|
||||
sinu1 = temp*cosu1;
|
||||
temp = (1.0-f)*sinphi2/cosphi2;
|
||||
cosu2 = 1.0/sqrt(1.0+temp*temp);
|
||||
sinu2 = temp*cosu2;
|
||||
|
||||
do {
|
||||
sdlams = sin(dlams), cdlams = cos(dlams);
|
||||
sinsig = sqrt(cosu2*cosu2*sdlams*sdlams+
|
||||
(cosu1*sinu2-sinu1*cosu2*cdlams)*
|
||||
(cosu1*sinu2-sinu1*cosu2*cdlams));
|
||||
cossig = sinu1*sinu2+cosu1*cosu2*cdlams;
|
||||
|
||||
sig = atan2(sinsig,cossig);
|
||||
sinaz = cosu1*cosu2*sdlams/sinsig;
|
||||
cos2saz = 1.0-sinaz*sinaz;
|
||||
c2sigm = (sinu1 == 0.0 || sinu2 == 0.0 ? cossig :
|
||||
cossig-2.0*sinu1*sinu2/cos2saz);
|
||||
tc = f*cos2saz*(4.0+f*(4.0-3.0*cos2saz))/16.0;
|
||||
temp = dlams;
|
||||
dlams = dlam+(1.0-tc)*f*sinaz*
|
||||
(sig+tc*sinsig*
|
||||
(c2sigm+tc*cossig*(-1.0+2.0*c2sigm*c2sigm)));
|
||||
if (fabs(dlams) > GEOD_INV_PI && iter++ > 50) {
|
||||
return iter;
|
||||
}
|
||||
} while ( fabs(temp-dlams) > testv);
|
||||
|
||||
us = cos2saz*(a*a-b*b)/(b*b); // !!
|
||||
// BACK AZIMUTH FROM NORTH
|
||||
rnumer = -(cosu1*sdlams);
|
||||
denom = sinu1*cosu2-cosu1*sinu2*cdlams;
|
||||
*az2 = atan2(rnumer,denom)/RADDEG;
|
||||
if( fabs(*az2) < testv ) *az2 = 0.0;
|
||||
if(*az2 < 0.0) *az2 += 360.0;
|
||||
|
||||
// FORWARD AZIMUTH FROM NORTH
|
||||
rnumer = cosu2*sdlams;
|
||||
denom = cosu1*sinu2-sinu1*cosu2*cdlams;
|
||||
*az1 = atan2(rnumer,denom)/RADDEG;
|
||||
if( fabs(*az1) < testv ) *az1 = 0.0;
|
||||
if(*az1 < 0.0) *az1 += 360.0;
|
||||
|
||||
// Terms a & b
|
||||
ta = 1.0+us*(4096.0+us*(-768.0+us*(320.0-175.0*us)))/
|
||||
16384.0;
|
||||
tb = us*(256.0+us*(-128.0+us*(74.0-47.0*us)))/1024.0;
|
||||
|
||||
// GEODETIC DISTANCE
|
||||
*s = b*ta*(sig-tb*sinsig*
|
||||
(c2sigm+tb*(cossig*(-1.0+2.0*c2sigm*c2sigm)-tb*
|
||||
c2sigm*(-3.0+4.0*sinsig*sinsig)*
|
||||
(-3.0+4.0*c2sigm*c2sigm)/6.0)/
|
||||
4.0));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
TITLE: ls_geodesy
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
FUNCTION: Converts geocentric coordinates to geodetic positions
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
MODULE STATUS: developmental
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
GENEALOGY: Written as part of LaRCSim project by E. B. Jackson
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
DESIGNED BY: E. B. Jackson
|
||||
|
||||
CODED BY: E. B. Jackson
|
||||
|
||||
MAINTAINED BY: E. B. Jackson
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
MODIFICATION HISTORY:
|
||||
|
||||
DATE PURPOSE BY
|
||||
|
||||
930208 Modified to avoid singularity near polar region. EBJ
|
||||
930602 Moved backwards calcs here from ls_step. EBJ
|
||||
931214 Changed erroneous Latitude and Altitude variables to
|
||||
*lat_geod and *alt in routine ls_geoc_to_geod. EBJ
|
||||
940111 Changed header files from old ls_eom.h style to ls_types,
|
||||
and ls_constants. Also replaced old DATA type with new
|
||||
SCALAR type. EBJ
|
||||
|
||||
CURRENT RCS HEADER:
|
||||
|
||||
$Header$
|
||||
* Revision 1.5 1994/01/11 18:47:05 bjax
|
||||
* Changed include files to use types and constants, not ls_eom.h
|
||||
* Also changed DATA type to SCALAR type.
|
||||
*
|
||||
* Revision 1.4 1993/12/14 21:06:47 bjax
|
||||
* Removed global variable references Altitude and Latitude. EBJ
|
||||
*
|
||||
* Revision 1.3 1993/06/02 15:03:40 bjax
|
||||
* Made new subroutine for calculating geodetic to geocentric; changed name
|
||||
* of forward conversion routine from ls_geodesy to ls_geoc_to_geod.
|
||||
*
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
REFERENCES:
|
||||
|
||||
[ 1] Stevens, Brian L.; and Lewis, Frank L.: "Aircraft
|
||||
Control and Simulation", Wiley and Sons, 1992.
|
||||
ISBN 0-471-61397-5
|
||||
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
CALLED BY: ls_aux
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
CALLS TO:
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
INPUTS:
|
||||
lat_geoc Geocentric latitude, radians, + = North
|
||||
radius C.G. radius to earth center, ft
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
OUTPUTS:
|
||||
lat_geod Geodetic latitude, radians, + = North
|
||||
alt C.G. altitude above mean sea level, ft
|
||||
sea_level_r radius from earth center to sea level at
|
||||
local vertical (surface normal) of C.G.
|
||||
|
||||
--------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
175
simgear/math/fg_geodesy.hxx
Normal file
175
simgear/math/fg_geodesy.hxx
Normal file
@@ -0,0 +1,175 @@
|
||||
// fg_geodesy.hxx -- routines to convert between geodetic and geocentric
|
||||
// coordinate systems.
|
||||
//
|
||||
// Copied and adapted directly from LaRCsim/ls_geodesy.c
|
||||
//
|
||||
// See below for the complete original LaRCsim comments.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#ifndef _FG_GEODESY_HXX
|
||||
#define _FG_GEODESY_HXX
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
|
||||
#include <simgear/math/point3d.hxx>
|
||||
#include <simgear/math/polar3d.hxx>
|
||||
|
||||
|
||||
// fgGeocToGeod(lat_geoc, radius, *lat_geod, *alt, *sea_level_r)
|
||||
// INPUTS:
|
||||
// lat_geoc Geocentric latitude, radians, + = North
|
||||
// radius C.G. radius to earth center (meters)
|
||||
//
|
||||
// OUTPUTS:
|
||||
// lat_geod Geodetic latitude, radians, + = North
|
||||
// alt C.G. altitude above mean sea level (meters)
|
||||
// sea_level_r radius from earth center to sea level at
|
||||
// local vertical (surface normal) of C.G. (meters)
|
||||
|
||||
void fgGeocToGeod( double lat_geoc, double radius, double
|
||||
*lat_geod, double *alt, double *sea_level_r );
|
||||
|
||||
|
||||
// fgGeodToGeoc( lat_geod, alt, *sl_radius, *lat_geoc )
|
||||
// INPUTS:
|
||||
// lat_geod Geodetic latitude, radians, + = North
|
||||
// alt C.G. altitude above mean sea level (meters)
|
||||
//
|
||||
// OUTPUTS:
|
||||
// sl_radius SEA LEVEL radius to earth center (meters)
|
||||
// (add Altitude to get true distance from earth center.
|
||||
// lat_geoc Geocentric latitude, radians, + = North
|
||||
//
|
||||
|
||||
void fgGeodToGeoc( double lat_geod, double alt, double *sl_radius,
|
||||
double *lat_geoc );
|
||||
|
||||
|
||||
// convert a geodetic point lon(radians), lat(radians), elev(meter) to
|
||||
// a cartesian point
|
||||
|
||||
inline Point3D fgGeodToCart(const Point3D& geod) {
|
||||
double gc_lon, gc_lat, sl_radius;
|
||||
|
||||
// printf("A geodetic point is (%.2f, %.2f, %.2f)\n",
|
||||
// geod[0], geod[1], geod[2]);
|
||||
|
||||
gc_lon = geod.lon();
|
||||
fgGeodToGeoc(geod.lat(), geod.radius(), &sl_radius, &gc_lat);
|
||||
|
||||
// printf("A geocentric point is (%.2f, %.2f, %.2f)\n", gc_lon,
|
||||
// gc_lat, sl_radius+geod[2]);
|
||||
|
||||
Point3D pp = Point3D( gc_lon, gc_lat, sl_radius + geod.radius());
|
||||
return fgPolarToCart3d(pp);
|
||||
}
|
||||
|
||||
|
||||
// given, alt, lat1, lon1, az1 and distance (s), calculate lat2, lon2
|
||||
// and az2. Lat, lon, and azimuth are in degrees. distance in meters
|
||||
int geo_direct_wgs_84 ( double alt, double lat1, double lon1, double az1,
|
||||
double s, double *lat2, double *lon2, double *az2 );
|
||||
|
||||
|
||||
// given alt, lat1, lon1, lat2, lon2, calculate starting and ending
|
||||
// az1, az2 and distance (s). Lat, lon, and azimuth are in degrees.
|
||||
// distance in meters
|
||||
int geo_inverse_wgs_84( double alt, double lat1, double lon1, double lat2,
|
||||
double lon2, double *az1, double *az2, double *s );
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
TITLE: ls_geodesy
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
FUNCTION: Converts geocentric coordinates to geodetic positions
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
MODULE STATUS: developmental
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
GENEALOGY: Written as part of LaRCSim project by E. B. Jackson
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
DESIGNED BY: E. B. Jackson
|
||||
|
||||
CODED BY: E. B. Jackson
|
||||
|
||||
MAINTAINED BY: E. B. Jackson
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
MODIFICATION HISTORY:
|
||||
|
||||
DATE PURPOSE BY
|
||||
|
||||
930208 Modified to avoid singularity near polar region. EBJ
|
||||
930602 Moved backwards calcs here from ls_step. EBJ
|
||||
931214 Changed erroneous Latitude and Altitude variables to
|
||||
*lat_geod and *alt in routine ls_geoc_to_geod. EBJ
|
||||
940111 Changed header files from old ls_eom.h style to ls_types,
|
||||
and ls_constants. Also replaced old DATA type with new
|
||||
SCALAR type. EBJ
|
||||
|
||||
CURRENT RCS HEADER:
|
||||
|
||||
$Header$
|
||||
|
||||
* Revision 1.5 1994/01/11 18:47:05 bjax
|
||||
* Changed include files to use types and constants, not ls_eom.h
|
||||
* Also changed DATA type to SCALAR type.
|
||||
*
|
||||
* Revision 1.4 1993/12/14 21:06:47 bjax
|
||||
* Removed global variable references Altitude and Latitude. EBJ
|
||||
*
|
||||
* Revision 1.3 1993/06/02 15:03:40 bjax
|
||||
* Made new subroutine for calculating geodetic to geocentric; changed name
|
||||
* of forward conversion routine from ls_geodesy to ls_geoc_to_geod.
|
||||
*
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
REFERENCES:
|
||||
|
||||
[ 1] Stevens, Brian L.; and Lewis, Frank L.: "Aircraft
|
||||
Control and Simulation", Wiley and Sons, 1992.
|
||||
ISBN 0-471-61397-5
|
||||
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
CALLED BY: ls_aux
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
CALLS TO:
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
INPUTS:
|
||||
lat_geoc Geocentric latitude, radians, + = North
|
||||
radius C.G. radius to earth center, ft
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
OUTPUTS:
|
||||
lat_geod Geodetic latitude, radians, + = North
|
||||
alt C.G. altitude above mean sea level, ft
|
||||
sea_level_r radius from earth center to sea level at
|
||||
local vertical (surface normal) of C.G.
|
||||
|
||||
--------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#endif // _FG_GEODESY_HXX
|
||||
59
simgear/math/fg_memory.h
Normal file
59
simgear/math/fg_memory.h
Normal file
@@ -0,0 +1,59 @@
|
||||
// fg_memory.h -- memcpy/bcopy portability declarations
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#ifndef _FG_MEMORY_H
|
||||
#define _FG_MEMORY_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MEMCPY
|
||||
|
||||
# ifdef HAVE_MEMORY_H
|
||||
# include <memory.h>
|
||||
# endif
|
||||
|
||||
# define fgmemcmp memcmp
|
||||
# define fgmemcpy memcpy
|
||||
# define fgmemzero(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
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* Neither memcpy() or bcopy() available.
|
||||
* Use substitutes provided be zlib.
|
||||
*/
|
||||
|
||||
# include <zutil.h>
|
||||
# define fgmemcmp zmemcmp
|
||||
# define fgmemcpy zmemcpy
|
||||
# define fgmemzero zmemzero
|
||||
|
||||
#endif
|
||||
|
||||
#endif // _FG_MEMORY_H
|
||||
|
||||
|
||||
71
simgear/math/fg_random.c
Normal file
71
simgear/math/fg_random.c
Normal file
@@ -0,0 +1,71 @@
|
||||
// fg_random.c -- routines to handle random number generation
|
||||
//
|
||||
// Written by Curtis Olson, started July 1997.
|
||||
//
|
||||
// Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> // for random(), srandom()
|
||||
#include <time.h> // for time() to seed srandom()
|
||||
|
||||
#include "fg_random.h"
|
||||
|
||||
#ifndef HAVE_RAND
|
||||
# ifdef sgi
|
||||
# undef RAND_MAX
|
||||
# define RAND_MAX 2147483647
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __SUNPRO_CC
|
||||
extern "C" {
|
||||
long int random(void);
|
||||
void srandom(unsigned int seed);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Seed the random number generater with time() so we don't see the
|
||||
// same sequence every time
|
||||
void fg_srandom(void) {
|
||||
// fgPrintf( FG_MATH, FG_INFO, "Seeding random number generater\n");
|
||||
|
||||
#ifdef HAVE_RAND
|
||||
srand(time(NULL));
|
||||
#else
|
||||
srandom(time(NULL));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// return a random number between [0.0, 1.0)
|
||||
double fg_random(void) {
|
||||
#ifdef HAVE_RAND
|
||||
return(rand() / (double)RAND_MAX);
|
||||
#else
|
||||
return(random() / (double)RAND_MAX);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
48
simgear/math/fg_random.h
Normal file
48
simgear/math/fg_random.h
Normal file
@@ -0,0 +1,48 @@
|
||||
// fg_random.h -- routines to handle random number generation
|
||||
//
|
||||
// Written by Curtis Olson, started July 1997.
|
||||
//
|
||||
// Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#ifndef _FG_RANDOM_H
|
||||
#define _FG_RANDOM_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
// Seed the random number generater with time() so we don't see the
|
||||
// same sequence every time
|
||||
void fg_srandom(void);
|
||||
|
||||
// return a random number between [0.0, 1.0)
|
||||
double fg_random(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif // _FG_RANDOM_H
|
||||
|
||||
|
||||
73
simgear/math/fg_types.hxx
Normal file
73
simgear/math/fg_types.hxx
Normal file
@@ -0,0 +1,73 @@
|
||||
// fg_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
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#ifndef _FG_TYPES_HXX
|
||||
#define _FG_TYPES_HXX
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include STL_STRING
|
||||
#include <vector>
|
||||
|
||||
#include <simgear/math/point3d.hxx>
|
||||
|
||||
FG_USING_STD(vector);
|
||||
FG_USING_STD(string);
|
||||
|
||||
|
||||
typedef vector < int > int_list;
|
||||
typedef int_list::iterator int_list_iterator;
|
||||
typedef int_list::const_iterator const_int_list_iterator;
|
||||
|
||||
typedef vector < Point3D > point_list;
|
||||
typedef point_list::iterator point_list_iterator;
|
||||
typedef point_list::const_iterator const_point_list_iterator;
|
||||
|
||||
typedef vector < string > string_list;
|
||||
typedef string_list::iterator string_list_iterator;
|
||||
typedef string_list::const_iterator const_string_list_iterator;
|
||||
|
||||
|
||||
class point2d {
|
||||
public:
|
||||
union {
|
||||
double x;
|
||||
double dist;
|
||||
double lon;
|
||||
};
|
||||
union {
|
||||
double y;
|
||||
double theta;
|
||||
double lat;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#endif // _FG_TYPES_HXX
|
||||
|
||||
107
simgear/math/interpolater.cxx
Normal file
107
simgear/math/interpolater.cxx
Normal file
@@ -0,0 +1,107 @@
|
||||
//
|
||||
// interpolater.cxx -- routines to handle linear interpolation from a table of
|
||||
// x,y The table must be sorted by "x" in ascending order
|
||||
//
|
||||
// Written by Curtis Olson, started April 1998.
|
||||
//
|
||||
// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#ifdef __MWERKS__
|
||||
#include <stdlib.h> // for exit()
|
||||
#endif
|
||||
|
||||
#include STL_STRING
|
||||
|
||||
#include <simgear/fg_zlib.h>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/misc/fgstream.hxx>
|
||||
|
||||
#include "interpolater.hxx"
|
||||
|
||||
|
||||
// Constructor -- loads the interpolation table from the specified
|
||||
// file
|
||||
fgINTERPTABLE::fgINTERPTABLE( const string& file ) {
|
||||
FG_LOG( FG_MATH, FG_INFO, "Initializing Interpolator for " << file );
|
||||
|
||||
fg_gzifstream in( file );
|
||||
if ( !in ) {
|
||||
FG_LOG( FG_GENERAL, FG_ALERT, "Cannot open file: " << file );
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
size = 0;
|
||||
in >> skipcomment;
|
||||
while ( in ) {
|
||||
if ( size < MAX_TABLE_SIZE ) {
|
||||
in >> table[size][0] >> table[size][1];
|
||||
size++;
|
||||
} else {
|
||||
FG_LOG( FG_MATH, FG_ALERT,
|
||||
"fgInterpolateInit(): Exceed max table size = "
|
||||
<< MAX_TABLE_SIZE );
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Given an x value, linearly interpolate the y value from the table
|
||||
double fgINTERPTABLE::interpolate(double x) {
|
||||
int i;
|
||||
double y;
|
||||
|
||||
i = 0;
|
||||
|
||||
while ( (x > table[i][0]) && (i < size) ) {
|
||||
i++;
|
||||
}
|
||||
|
||||
// printf ("i = %d ", i);
|
||||
|
||||
if ( (i == 0) && (x < table[0][0]) ) {
|
||||
FG_LOG( FG_MATH, FG_ALERT,
|
||||
"fgInterpolateInit(): lookup error, x to small = " << x );
|
||||
return(0.0);
|
||||
}
|
||||
|
||||
if ( x > table[i][0] ) {
|
||||
FG_LOG( FG_MATH, FG_ALERT,
|
||||
"fgInterpolateInit(): lookup error, x to big = " << x );
|
||||
return(0.0);
|
||||
}
|
||||
|
||||
// y = y1 + (y0 - y1)(x - x1) / (x0 - x1)
|
||||
y = table[i][1] +
|
||||
( (table[i-1][1] - table[i][1]) *
|
||||
(x - table[i][0]) ) /
|
||||
(table[i-1][0] - table[i][0]);
|
||||
|
||||
return(y);
|
||||
}
|
||||
|
||||
|
||||
// Destructor
|
||||
fgINTERPTABLE::~fgINTERPTABLE( void ) {
|
||||
}
|
||||
|
||||
|
||||
62
simgear/math/interpolater.hxx
Normal file
62
simgear/math/interpolater.hxx
Normal file
@@ -0,0 +1,62 @@
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// 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 _INTERPOLATER_H
|
||||
#define _INTERPOLATER_H
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include STL_STRING
|
||||
FG_USING_STD(string);
|
||||
|
||||
#define MAX_TABLE_SIZE 32
|
||||
|
||||
|
||||
class fgINTERPTABLE {
|
||||
int size;
|
||||
double table[MAX_TABLE_SIZE][2];
|
||||
|
||||
public:
|
||||
|
||||
// Constructor -- loads the interpolation table from the specified
|
||||
// file
|
||||
fgINTERPTABLE( const string& file );
|
||||
|
||||
// Given an x value, linearly interpolate the y value from the table
|
||||
double interpolate(double x);
|
||||
|
||||
// Destructor
|
||||
~fgINTERPTABLE( void );
|
||||
};
|
||||
|
||||
|
||||
#endif // _INTERPOLATER_H
|
||||
|
||||
|
||||
135
simgear/math/leastsqs.cxx
Normal file
135
simgear/math/leastsqs.cxx
Normal file
@@ -0,0 +1,135 @@
|
||||
// leastsqs.c -- 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
|
||||
//
|
||||
// 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 <stdio.h>
|
||||
|
||||
#include "leastsqs.hxx"
|
||||
|
||||
|
||||
/*
|
||||
Least squares fit:
|
||||
|
||||
y = b0 + b1x
|
||||
|
||||
n*sum(xi*yi) - (sum(xi)*sum(yi))
|
||||
b1 = --------------------------------
|
||||
n*sum(xi^2) - (sum(xi))^2
|
||||
|
||||
|
||||
b0 = sum(yi)/n - b1*(sum(xi)/n)
|
||||
*/
|
||||
|
||||
double sum_xi, sum_yi, sum_xi_2, sum_xi_yi;
|
||||
int sum_n;
|
||||
|
||||
void least_squares(double *x, double *y, int n, double *m, double *b) {
|
||||
int i;
|
||||
|
||||
sum_xi = sum_yi = sum_xi_2 = sum_xi_yi = 0.0;
|
||||
sum_n = n;
|
||||
|
||||
for ( i = 0; i < n; i++ ) {
|
||||
sum_xi += x[i];
|
||||
sum_yi += y[i];
|
||||
sum_xi_2 += x[i] * x[i];
|
||||
sum_xi_yi += x[i] * y[i];
|
||||
}
|
||||
|
||||
/* printf("sum(xi)=%.2f sum(yi)=%.2f sum(xi^2)=%.2f sum(xi*yi)=%.2f\n",
|
||||
sum_xi, sum_yi, sum_xi_2, sum_xi_yi); */
|
||||
|
||||
*m = ( (double)sum_n * sum_xi_yi - sum_xi * sum_yi ) /
|
||||
( (double)sum_n * sum_xi_2 - sum_xi * sum_xi );
|
||||
*b = (sum_yi / (double)sum_n) - (*m) * (sum_xi / (double)sum_n);
|
||||
|
||||
/* printf("slope = %.2f intercept = %.2f\n", *m, *b); */
|
||||
}
|
||||
|
||||
|
||||
/* incrimentally update existing values with a new data point */
|
||||
void least_squares_update(double x, double y, double *m, double *b) {
|
||||
++sum_n;
|
||||
|
||||
sum_xi += x;
|
||||
sum_yi += y;
|
||||
sum_xi_2 += x * x;
|
||||
sum_xi_yi += x * y;
|
||||
|
||||
/* printf("sum(xi)=%.2f sum(yi)=%.2f sum(xi^2)=%.2f sum(xi*yi)=%.2f\n",
|
||||
sum_xi, sum_yi, sum_xi_2, sum_xi_yi); */
|
||||
|
||||
*m = ( (double)sum_n * sum_xi_yi - sum_xi * sum_yi ) /
|
||||
( (double)sum_n * sum_xi_2 - sum_xi * sum_xi );
|
||||
*b = (sum_yi / (double)sum_n) - (*m) * (sum_xi / (double)sum_n);
|
||||
|
||||
/* printf("slope = %.2f intercept = %.2f\n", *m, *b); */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
return the least squares error:
|
||||
|
||||
(y[i] - y_hat[i])^2
|
||||
-------------------
|
||||
n
|
||||
*/
|
||||
double least_squares_error(double *x, double *y, int n, double m, double b) {
|
||||
int i;
|
||||
double error, sum;
|
||||
|
||||
sum = 0.0;
|
||||
|
||||
for ( i = 0; i < n; i++ ) {
|
||||
error = y[i] - (m * x[i] + b);
|
||||
sum += error * error;
|
||||
// printf("%.2f %.2f\n", error, sum);
|
||||
}
|
||||
|
||||
return ( sum / (double)n );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
return the maximum least squares error:
|
||||
|
||||
(y[i] - y_hat[i])^2
|
||||
*/
|
||||
double least_squares_max_error(double *x, double *y, int n, double m, double b){
|
||||
int i;
|
||||
double error, max_error;
|
||||
|
||||
max_error = 0.0;
|
||||
|
||||
for ( i = 0; i < n; i++ ) {
|
||||
error = y[i] - (m * x[i] + b);
|
||||
error = error * error;
|
||||
if ( error > max_error ) {
|
||||
max_error = error;
|
||||
}
|
||||
}
|
||||
|
||||
return ( max_error );
|
||||
}
|
||||
|
||||
|
||||
73
simgear/math/leastsqs.hxx
Normal file
73
simgear/math/leastsqs.hxx
Normal file
@@ -0,0 +1,73 @@
|
||||
// leastsqs.h -- 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
|
||||
//
|
||||
// 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 _LEASTSQS_H
|
||||
#define _LEASTSQS_H
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
Least squares fit:
|
||||
|
||||
y = b0 + b1x
|
||||
|
||||
n*sum(xi*yi) - (sum(xi)*sum(yi))
|
||||
b1 = --------------------------------
|
||||
n*sum(xi^2) - (sum(xi))^2
|
||||
|
||||
|
||||
b0 = sum(yi)/n - b1*(sum(xi)/n)
|
||||
*/
|
||||
|
||||
void least_squares(double *x, double *y, int n, double *m, double *b);
|
||||
|
||||
/* 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:
|
||||
|
||||
(y[i] - y_hat[i])^2
|
||||
-------------------
|
||||
n
|
||||
*/
|
||||
double least_squares_error(double *x, double *y, int n, double m, double b);
|
||||
|
||||
|
||||
/*
|
||||
return the maximum least squares error:
|
||||
|
||||
(y[i] - y_hat[i])^2
|
||||
*/
|
||||
double least_squares_max_error(double *x, double *y, int n, double m, double b);
|
||||
|
||||
|
||||
#endif // _LEASTSQS_H
|
||||
|
||||
|
||||
110
simgear/math/linintp2.h
Normal file
110
simgear/math/linintp2.h
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
WARNING - Do not remove this header.
|
||||
|
||||
This code is a templated version of the 'magic-software' spherical
|
||||
interpolation code by Dave Eberly. The original (un-hacked) code can be
|
||||
obtained from here: http://www.magic-software.com/gr_appr.htm
|
||||
This code is derived from linintp2.h/cpp and sphrintp.h/cpp.
|
||||
|
||||
Dave Eberly says that the conditions for use are:
|
||||
|
||||
* You may distribute the original source code to others at no charge.
|
||||
|
||||
* You may modify the original source code and distribute it to others at
|
||||
no charge. The modified code must be documented to indicate that it is
|
||||
not part of the original package.
|
||||
|
||||
* You may use this code for non-commercial purposes. You may also
|
||||
incorporate this code into commercial packages. However, you may not
|
||||
sell any of your source code which contains my original and/or modified
|
||||
source code. In such a case, you need to factor out my code and freely
|
||||
distribute it.
|
||||
|
||||
* The original code comes with absolutely no warranty and no guarantee is
|
||||
made that the code is bug-free.
|
||||
|
||||
This does not seem incompatible with GPL - so this modified version
|
||||
is hereby placed under GPL along with the rest of FlightGear.
|
||||
|
||||
Christian Mayer
|
||||
*/
|
||||
|
||||
#ifndef LININTP2_H
|
||||
#define LININTP2_H
|
||||
|
||||
template<class T>
|
||||
class mgcLinInterp2D
|
||||
{
|
||||
public:
|
||||
mgcLinInterp2D (int _numPoints, double* x, double* y, T* _f);
|
||||
|
||||
~mgcLinInterp2D ();
|
||||
|
||||
double XMin () { return xmin; }
|
||||
double XMax () { return xmax; }
|
||||
double XRange () { return xmax-xmin; }
|
||||
double YMin () { return ymin; }
|
||||
double YMax () { return ymax; }
|
||||
double YRange () { return ymax-ymin; }
|
||||
|
||||
int PointCount () { return numPoints; }
|
||||
void GetPoint (int i, double& x, double& y);
|
||||
|
||||
int EdgeCount () { return numEdges; }
|
||||
void GetEdge (int i, double& x0, double& y0, double& x1, double& y1);
|
||||
|
||||
int TriangleCount () { return numTriangles; }
|
||||
void GetTriangle (int i, double& x0, double& y0, double& x1, double& y1,
|
||||
double& x2, double& y2);
|
||||
|
||||
int Evaluate (double x, double y, T& F);
|
||||
|
||||
private:
|
||||
typedef struct
|
||||
{
|
||||
double x, y;
|
||||
}
|
||||
Vertex;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int vertex[3]; // listed in counterclockwise order
|
||||
|
||||
int adj[3];
|
||||
// adj[0] points to triangle sharing edge (vertex[0],vertex[1])
|
||||
// adj[1] points to triangle sharing edge (vertex[1],vertex[2])
|
||||
// adj[2] points to triangle sharing edge (vertex[2],vertex[0])
|
||||
}
|
||||
Triangle;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int vertex[2];
|
||||
int triangle[2];
|
||||
int index[2];
|
||||
}
|
||||
Edge;
|
||||
|
||||
int numPoints;
|
||||
double** point;
|
||||
double** tmppoint;
|
||||
T* f;
|
||||
|
||||
double xmin, xmax, ymin, ymax;
|
||||
|
||||
|
||||
int numEdges;
|
||||
Edge* edge;
|
||||
|
||||
int numTriangles;
|
||||
Triangle* triangle;
|
||||
|
||||
int Delaunay2D ();
|
||||
void ComputeBarycenter (Vertex& v0, Vertex& v1, Vertex& v2, Vertex& ver,
|
||||
double c[3]);
|
||||
int InTriangle (Vertex& v0, Vertex& v1, Vertex& v2, Vertex& test);
|
||||
};
|
||||
|
||||
#include "linintp2.inl"
|
||||
|
||||
#endif
|
||||
540
simgear/math/linintp2.inl
Normal file
540
simgear/math/linintp2.inl
Normal file
@@ -0,0 +1,540 @@
|
||||
/*
|
||||
WARNING - Do not remove this header.
|
||||
|
||||
This code is a templated version of the 'magic-software' spherical
|
||||
interpolation code by Dave Eberly. The original (un-hacked) code can be
|
||||
obtained from here: http://www.magic-software.com/gr_appr.htm
|
||||
This code is derived from linintp2.h/cpp and sphrintp.h/cpp.
|
||||
|
||||
Dave Eberly says that the conditions for use are:
|
||||
|
||||
* You may distribute the original source code to others at no charge.
|
||||
|
||||
* You may modify the original source code and distribute it to others at
|
||||
no charge. The modified code must be documented to indicate that it is
|
||||
not part of the original package.
|
||||
|
||||
* You may use this code for non-commercial purposes. You may also
|
||||
incorporate this code into commercial packages. However, you may not
|
||||
sell any of your source code which contains my original and/or modified
|
||||
source code. In such a case, you need to factor out my code and freely
|
||||
distribute it.
|
||||
|
||||
* The original code comes with absolutely no warranty and no guarantee is
|
||||
made that the code is bug-free.
|
||||
|
||||
This does not seem incompatible with GPL - so this modified version
|
||||
is hereby placed under GPL along with the rest of FlightGear.
|
||||
|
||||
Christian Mayer
|
||||
*/
|
||||
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include "linintp2.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T>
|
||||
mgcLinInterp2D<T>::mgcLinInterp2D (int _numPoints, double* x, double* y,
|
||||
T* _f)
|
||||
{
|
||||
if ( (numPoints = _numPoints) < 3 )
|
||||
{
|
||||
point = 0;
|
||||
edge = 0;
|
||||
triangle = 0;
|
||||
numTriangles = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
cout << "[ 20%] allocating memory \r";
|
||||
|
||||
point = new double*[numPoints];
|
||||
tmppoint = new double*[numPoints+3];
|
||||
f = new T[numPoints];
|
||||
int i;
|
||||
for (i = 0; i < numPoints; i++)
|
||||
point[i] = new double[2];
|
||||
for (i = 0; i < numPoints+3; i++)
|
||||
tmppoint[i] = new double[2];
|
||||
for (i = 0; i < numPoints; i++)
|
||||
{
|
||||
point[i][0] = tmppoint[i][0] = x[i];
|
||||
point[i][1] = tmppoint[i][1] = y[i];
|
||||
|
||||
f[i] = _f[i];
|
||||
}
|
||||
|
||||
cout << "[ 30%] creating delaunay diagram \r";
|
||||
|
||||
Delaunay2D();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T>
|
||||
mgcLinInterp2D<T>::~mgcLinInterp2D ()
|
||||
{
|
||||
if ( numPoints < 3 )
|
||||
return;
|
||||
|
||||
int i;
|
||||
|
||||
if ( point )
|
||||
{
|
||||
for (i = 0; i < numPoints; i++)
|
||||
delete[] point[i];
|
||||
delete[] point;
|
||||
}
|
||||
if ( tmppoint )
|
||||
{
|
||||
for (i = 0; i < numPoints+3; i++)
|
||||
delete[] tmppoint[i];
|
||||
delete[] tmppoint;
|
||||
}
|
||||
|
||||
delete[] f;
|
||||
delete[] edge;
|
||||
delete[] triangle;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T>
|
||||
void mgcLinInterp2D<T>::ComputeBarycenter (Vertex& v0, Vertex& v1, Vertex& v2,
|
||||
Vertex& ver, double c[3])
|
||||
{
|
||||
double A0 = v0.x-v2.x, B0 = v0.y-v2.y;
|
||||
double A1 = v1.x-v2.x, B1 = v1.y-v2.y;
|
||||
double A2 = ver.x-v2.x, B2 = ver.y-v2.y;
|
||||
|
||||
double m00 = A0*A0+B0*B0, m01 = A0*A1+B0*B1, m11 = A1*A1+B1*B1;
|
||||
double r0 = A2*A0+B2*B0, r1 = A2*A1+B2*B1;
|
||||
double det = m00*m11-m01*m01;
|
||||
|
||||
c[0] = (m11*r0-m01*r1)/det;
|
||||
c[1] = (m00*r1-m01*r0)/det;
|
||||
c[2] = 1-c[0]-c[1];
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T>
|
||||
int mgcLinInterp2D<T>::InTriangle (Vertex& v0, Vertex& v1, Vertex& v2,
|
||||
Vertex& test)
|
||||
{
|
||||
const double eps = 1e-08;
|
||||
double tx, ty, nx, ny;
|
||||
|
||||
// test against normal to first edge
|
||||
tx = test.x - v0.x;
|
||||
ty = test.y - v0.y;
|
||||
nx = v0.y - v1.y;
|
||||
ny = v1.x - v0.x;
|
||||
if ( tx*nx + ty*ny < -eps )
|
||||
return 0;
|
||||
|
||||
// test against normal to second edge
|
||||
tx = test.x - v1.x;
|
||||
ty = test.y - v1.y;
|
||||
nx = v1.y - v2.y;
|
||||
ny = v2.x - v1.x;
|
||||
if ( tx*nx + ty*ny < -eps )
|
||||
return 0;
|
||||
|
||||
// test against normal to third edge
|
||||
tx = test.x - v2.x;
|
||||
ty = test.y - v2.y;
|
||||
nx = v2.y - v0.y;
|
||||
ny = v0.x - v2.x;
|
||||
if ( tx*nx + ty*ny < -eps )
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T>
|
||||
int mgcLinInterp2D<T>::Evaluate (double x, double y, T& F)
|
||||
{
|
||||
Vertex ver = { x, y };
|
||||
// determine which triangle contains the target point
|
||||
|
||||
int i;
|
||||
Vertex v0, v1, v2;
|
||||
for (i = 0; i < numTriangles; i++)
|
||||
{
|
||||
Triangle& t = triangle[i];
|
||||
v0.x = point[t.vertex[0]][0];
|
||||
v0.y = point[t.vertex[0]][1];
|
||||
v1.x = point[t.vertex[1]][0];
|
||||
v1.y = point[t.vertex[1]][1];
|
||||
v2.x = point[t.vertex[2]][0];
|
||||
v2.y = point[t.vertex[2]][1];
|
||||
|
||||
if ( InTriangle(v0,v1,v2,ver) )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( i == numTriangles ) // point is outside interpolation region
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Triangle& t = triangle[i]; // (x,y) is in this triangle
|
||||
|
||||
// compute barycentric coordinates with respect to subtriangle
|
||||
double bary[3];
|
||||
ComputeBarycenter(v0,v1,v2,ver,bary);
|
||||
|
||||
// compute barycentric combination of function values at vertices
|
||||
F = bary[0]*f[t.vertex[0]]+bary[1]*f[t.vertex[1]]+bary[2]*f[t.vertex[2]];
|
||||
|
||||
return 1;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T>
|
||||
int mgcLinInterp2D<T>::Delaunay2D ()
|
||||
{
|
||||
int result;
|
||||
|
||||
const double EPSILON = 1e-12;
|
||||
const int TSIZE = 75;
|
||||
const double RANGE = 10.0;
|
||||
|
||||
xmin = tmppoint[0][0];
|
||||
xmax = xmin;
|
||||
ymin = tmppoint[0][1];
|
||||
ymax = ymin;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < numPoints; i++)
|
||||
{
|
||||
double value = tmppoint[i][0];
|
||||
if ( xmax < value )
|
||||
xmax = value;
|
||||
if ( xmin > value )
|
||||
xmin = value;
|
||||
|
||||
value = tmppoint[i][1];
|
||||
if ( ymax < value )
|
||||
ymax = value;
|
||||
if ( ymin > value )
|
||||
ymin = value;
|
||||
}
|
||||
|
||||
double xrange = xmax-xmin, yrange = ymax-ymin;
|
||||
double maxrange = xrange;
|
||||
if ( maxrange < yrange )
|
||||
maxrange = yrange;
|
||||
|
||||
// need to scale the data later to do a correct triangle count
|
||||
double maxrange2 = maxrange*maxrange;
|
||||
|
||||
// tweak the points by very small random numbers
|
||||
double bgs = EPSILON*maxrange;
|
||||
srand(367);
|
||||
for (i = 0; i < numPoints; i++)
|
||||
{
|
||||
tmppoint[i][0] += bgs*(0.5 - rand()/double(RAND_MAX));
|
||||
tmppoint[i][1] += bgs*(0.5 - rand()/double(RAND_MAX));
|
||||
}
|
||||
|
||||
double wrk[2][3] =
|
||||
{
|
||||
{ 5*RANGE, -RANGE, -RANGE },
|
||||
{ -RANGE, 5*RANGE, -RANGE }
|
||||
};
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
tmppoint[numPoints+i][0] = xmin+xrange*wrk[0][i];
|
||||
tmppoint[numPoints+i][1] = ymin+yrange*wrk[1][i];
|
||||
}
|
||||
|
||||
int i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i11;
|
||||
int nts, ii[3];
|
||||
double xx;
|
||||
|
||||
int tsz = 2*TSIZE;
|
||||
int** tmp = new int*[tsz+1];
|
||||
tmp[0] = new int[2*(tsz+1)];
|
||||
for (i0 = 1; i0 < tsz+1; i0++)
|
||||
tmp[i0] = tmp[0] + 2*i0;
|
||||
i1 = 2*(numPoints + 2);
|
||||
|
||||
int* id = new int[i1];
|
||||
for (i0 = 0; i0 < i1; i0++)
|
||||
id[i0] = i0;
|
||||
|
||||
int** a3s = new int*[i1];
|
||||
a3s[0] = new int[3*i1];
|
||||
for (i0 = 1; i0 < i1; i0++)
|
||||
a3s[i0] = a3s[0] + 3*i0;
|
||||
a3s[0][0] = numPoints;
|
||||
a3s[0][1] = numPoints+1;
|
||||
a3s[0][2] = numPoints+2;
|
||||
|
||||
double** ccr = new double*[i1]; // circumscribed centers and radii
|
||||
ccr[0] = new double[3*i1];
|
||||
for (i0 = 1; i0 < i1; i0++)
|
||||
ccr[i0] = ccr[0] + 3*i0;
|
||||
ccr[0][0] = 0.0;
|
||||
ccr[0][1] = 0.0;
|
||||
ccr[0][2] = FLT_MAX;
|
||||
|
||||
nts = 1; // number of triangles
|
||||
i4 = 1;
|
||||
|
||||
cout << "[ 40%] create triangulation \r";
|
||||
|
||||
// compute triangulation
|
||||
for (i0 = 0; i0 < numPoints; i0++)
|
||||
{
|
||||
i1 = i7 = -1;
|
||||
i9 = 0;
|
||||
for (i11 = 0; i11 < nts; i11++)
|
||||
{
|
||||
i1++;
|
||||
while ( a3s[i1][0] < 0 )
|
||||
i1++;
|
||||
xx = ccr[i1][2];
|
||||
for (i2 = 0; i2 < 2; i2++)
|
||||
{
|
||||
double z = tmppoint[i0][i2]-ccr[i1][i2];
|
||||
xx -= z*z;
|
||||
if ( xx < 0 )
|
||||
goto Corner3;
|
||||
}
|
||||
i9--;
|
||||
i4--;
|
||||
id[i4] = i1;
|
||||
for (i2 = 0; i2 < 3; i2++)
|
||||
{
|
||||
ii[0] = 0;
|
||||
if (ii[0] == i2)
|
||||
ii[0]++;
|
||||
for (i3 = 1; i3 < 2; i3++)
|
||||
{
|
||||
ii[i3] = ii[i3-1] + 1;
|
||||
if (ii[i3] == i2)
|
||||
ii[i3]++;
|
||||
}
|
||||
if ( i7 > 1 )
|
||||
{
|
||||
i8 = i7;
|
||||
for (i3 = 0; i3 <= i8; i3++)
|
||||
{
|
||||
for (i5 = 0; i5 < 2; i5++)
|
||||
if ( a3s[i1][ii[i5]] != tmp[i3][i5] )
|
||||
goto Corner1;
|
||||
for (i6 = 0; i6 < 2; i6++)
|
||||
tmp[i3][i6] = tmp[i8][i6];
|
||||
i7--;
|
||||
goto Corner2;
|
||||
Corner1:;
|
||||
}
|
||||
}
|
||||
if ( ++i7 > tsz )
|
||||
{
|
||||
// temporary storage exceeded, increase TSIZE
|
||||
result = 0;
|
||||
goto ExitDelaunay;
|
||||
}
|
||||
for (i3 = 0; i3 < 2; i3++)
|
||||
tmp[i7][i3] = a3s[i1][ii[i3]];
|
||||
Corner2:;
|
||||
}
|
||||
a3s[i1][0] = -1;
|
||||
Corner3:;
|
||||
}
|
||||
|
||||
for (i1 = 0; i1 <= i7; i1++)
|
||||
{
|
||||
for (i2 = 0; i2 < 2; i2++)
|
||||
for (wrk[i2][2] = 0, i3 = 0; i3 < 2; i3++)
|
||||
{
|
||||
wrk[i2][i3] = tmppoint[tmp[i1][i2]][i3]-tmppoint[i0][i3];
|
||||
wrk[i2][2] +=
|
||||
0.5*wrk[i2][i3]*(tmppoint[tmp[i1][i2]][i3]+
|
||||
tmppoint[i0][i3]);
|
||||
}
|
||||
|
||||
xx = wrk[0][0]*wrk[1][1]-wrk[1][0]*wrk[0][1];
|
||||
ccr[id[i4]][0] = (wrk[0][2]*wrk[1][1]-wrk[1][2]*wrk[0][1])/xx;
|
||||
ccr[id[i4]][1] = (wrk[0][0]*wrk[1][2]-wrk[1][0]*wrk[0][2])/xx;
|
||||
|
||||
for (ccr[id[i4]][2] = 0, i2 = 0; i2 < 2; i2++)
|
||||
{
|
||||
double z = tmppoint[i0][i2]-ccr[id[i4]][i2];
|
||||
ccr[id[i4]][2] += z*z;
|
||||
a3s[id[i4]][i2] = tmp[i1][i2];
|
||||
}
|
||||
|
||||
a3s[id[i4]][2] = i0;
|
||||
i4++;
|
||||
i9++;
|
||||
}
|
||||
nts += i9;
|
||||
}
|
||||
|
||||
// count the number of triangles
|
||||
cout << "[ 50%] count the number of triangles \r";
|
||||
|
||||
numTriangles = 0;
|
||||
i0 = -1;
|
||||
for (i11 = 0; i11 < nts; i11++)
|
||||
{
|
||||
i0++;
|
||||
while ( a3s[i0][0] < 0 )
|
||||
i0++;
|
||||
if ( a3s[i0][0] < numPoints )
|
||||
{
|
||||
for (i1 = 0; i1 < 2; i1++)
|
||||
for (i2 = 0; i2 < 2; i2++)
|
||||
wrk[i1][i2] =
|
||||
tmppoint[a3s[i0][i1]][i2]-tmppoint[a3s[i0][2]][i2];
|
||||
|
||||
if ( fabs(wrk[0][0]*wrk[1][1]-wrk[0][1]*wrk[1][0]) > EPSILON*maxrange2 )
|
||||
numTriangles++;
|
||||
}
|
||||
}
|
||||
|
||||
// create the triangles
|
||||
cout << "[ 60%] create the triangles \r";
|
||||
|
||||
triangle = new Triangle[numTriangles];
|
||||
|
||||
numTriangles = 0;
|
||||
i0 = -1;
|
||||
for (i11 = 0; i11 < nts; i11++)
|
||||
{
|
||||
i0++;
|
||||
while ( a3s[i0][0] < 0 )
|
||||
i0++;
|
||||
if ( a3s[i0][0] < numPoints )
|
||||
{
|
||||
for (i1 = 0; i1 < 2; i1++)
|
||||
for (i2 = 0; i2 < 2; i2++)
|
||||
wrk[i1][i2] =
|
||||
tmppoint[a3s[i0][i1]][i2]-tmppoint[a3s[i0][2]][i2];
|
||||
xx = wrk[0][0]*wrk[1][1]-wrk[0][1]*wrk[1][0];
|
||||
if ( fabs(xx) > EPSILON*maxrange2 )
|
||||
{
|
||||
int delta = xx < 0 ? 1 : 0;
|
||||
Triangle& tri = triangle[numTriangles];
|
||||
tri.vertex[0] = a3s[i0][0];
|
||||
tri.vertex[1] = a3s[i0][1+delta];
|
||||
tri.vertex[2] = a3s[i0][2-delta];
|
||||
tri.adj[0] = -1;
|
||||
tri.adj[1] = -1;
|
||||
tri.adj[2] = -1;
|
||||
numTriangles++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// build edge table
|
||||
cout << "[ 70%] build the edge table \r";
|
||||
|
||||
numEdges = 0;
|
||||
edge = new Edge[3*numTriangles];
|
||||
|
||||
int j, j0, j1;
|
||||
for (i = 0; i < numTriangles; i++)
|
||||
{
|
||||
if ( (i%500) == 0)
|
||||
cout << "[ 7" << 10*i/numTriangles << "%] build the edge table \r";
|
||||
|
||||
Triangle& t = triangle[i];
|
||||
|
||||
for (j0 = 0, j1 = 1; j0 < 3; j0++, j1 = (j1+1)%3)
|
||||
{
|
||||
for (j = 0; j < numEdges; j++)
|
||||
{
|
||||
Edge& e = edge[j];
|
||||
if ( (t.vertex[j0] == e.vertex[0]
|
||||
&& t.vertex[j1] == e.vertex[1])
|
||||
|| (t.vertex[j0] == e.vertex[1]
|
||||
&& t.vertex[j1] == e.vertex[0]) )
|
||||
break;
|
||||
}
|
||||
if ( j == numEdges ) // add edge to table
|
||||
{
|
||||
edge[j].vertex[0] = t.vertex[j0];
|
||||
edge[j].vertex[1] = t.vertex[j1];
|
||||
edge[j].triangle[0] = i;
|
||||
edge[j].index[0] = j0;
|
||||
edge[j].triangle[1] = -1;
|
||||
numEdges++;
|
||||
}
|
||||
else // edge already exists, add triangle to table
|
||||
{
|
||||
edge[j].triangle[1] = i;
|
||||
edge[j].index[1] = j0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// establish links between adjacent triangles
|
||||
cout << "[ 80%] establishing links between adjacent triangles \r";
|
||||
|
||||
for (i = 0; i < numEdges; i++)
|
||||
{
|
||||
if ( edge[i].triangle[1] != -1 )
|
||||
{
|
||||
j0 = edge[i].triangle[0];
|
||||
j1 = edge[i].triangle[1];
|
||||
triangle[j0].adj[edge[i].index[0]] = j1;
|
||||
triangle[j1].adj[edge[i].index[1]] = j0;
|
||||
}
|
||||
}
|
||||
|
||||
result = 1;
|
||||
|
||||
ExitDelaunay:;
|
||||
delete[] tmp[0];
|
||||
delete[] tmp;
|
||||
delete[] id;
|
||||
delete[] a3s[0];
|
||||
delete[] a3s;
|
||||
delete[] ccr[0];
|
||||
delete[] ccr;
|
||||
|
||||
cout << "[ 90%] finsishes delauney triangulation \r";
|
||||
|
||||
return result;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T>
|
||||
void mgcLinInterp2D<T>::GetPoint (int i, double& x, double& y)
|
||||
{
|
||||
// assumes i is valid [can use PointCount() before passing i]
|
||||
x = point[i][0];
|
||||
y = point[i][1];
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T>
|
||||
void mgcLinInterp2D<T>::GetEdge (int i, double& x0, double& y0, double& x1,
|
||||
double& y1)
|
||||
{
|
||||
// assumes i is valid [can use EdgeCount() before passing i]
|
||||
int v0 = edge[i].vertex[0], v1 = edge[i].vertex[1];
|
||||
|
||||
x0 = point[v0][0];
|
||||
y0 = point[v0][1];
|
||||
x1 = point[v1][0];
|
||||
y1 = point[v1][1];
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T>
|
||||
void mgcLinInterp2D<T>::GetTriangle (int i, double& x0, double& y0, double& x1,
|
||||
double& y1, double& x2, double& y2)
|
||||
{
|
||||
// assumes i is valid [can use TriangleCount() before passing i]
|
||||
int v0 = triangle[i].vertex[0];
|
||||
int v1 = triangle[i].vertex[1];
|
||||
int v2 = triangle[i].vertex[2];
|
||||
|
||||
x0 = point[v0][0];
|
||||
y0 = point[v0][1];
|
||||
x1 = point[v1][0];
|
||||
y1 = point[v1][1];
|
||||
x2 = point[v2][0];
|
||||
y2 = point[v2][1];
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
233
simgear/math/mat3.h
Normal file
233
simgear/math/mat3.h
Normal file
@@ -0,0 +1,233 @@
|
||||
/* Copyright 1988, Brown Computer Graphics Group. All Rights Reserved. */
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
Public MAT3 include file
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
#ifndef MAT3_HAS_BEEN_INCLUDED
|
||||
#define MAT3_HAS_BEEN_INCLUDED
|
||||
|
||||
/* ----------------------------- Constants ------------------------------ */
|
||||
|
||||
/*
|
||||
* Make sure the math library .h file is included, in case it wasn't.
|
||||
*/
|
||||
|
||||
#ifndef HUGE
|
||||
#include <math.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <simgear/math/fg_memory.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#define MAT3_DET0 -1 /* Indicates singular mat */
|
||||
#define MAT3_EPSILON 1e-12 /* Close enough to zero */
|
||||
|
||||
#ifdef M_PI
|
||||
# define MAT3_PI M_PI
|
||||
#else
|
||||
# define MAT3_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#define USE_XTRA_MAT3_INLINES
|
||||
|
||||
#if defined(i386)
|
||||
#define USE_X86_ASM
|
||||
#endif
|
||||
|
||||
#if defined(USE_X86_ASM)
|
||||
static __inline__ int FloatToInt(float f)
|
||||
{
|
||||
int r;
|
||||
__asm__ ("fistpl %0" : "=m" (r) : "t" (f) : "st");
|
||||
return r;
|
||||
}
|
||||
#elif defined(__MSC__) && defined(__WIN32__)
|
||||
static __inline int FloatToInt(float f)
|
||||
{
|
||||
int r;
|
||||
_asm {
|
||||
fld f
|
||||
fistp r
|
||||
}
|
||||
return r;
|
||||
}
|
||||
#else
|
||||
#define FloatToInt(F) ((int) ((F) < 0.0f ? (F)-0.5f : (F)+0.5f))
|
||||
#endif
|
||||
|
||||
/* ------------------------------ Types --------------------------------- */
|
||||
|
||||
typedef double MAT3mat[4][4]; /* 4x4 matrix */
|
||||
typedef double MAT3vec[3]; /* Vector */
|
||||
typedef double MAT3hvec[4]; /* Vector with homogeneous coord */
|
||||
|
||||
/* ------------------------------ Macros -------------------------------- */
|
||||
|
||||
extern MAT3mat identityMatrix;
|
||||
|
||||
/* Tests if a number is within EPSILON of zero */
|
||||
#define MAT3_IS_ZERO(N) ((N) < MAT3_EPSILON && (N) > -MAT3_EPSILON)
|
||||
|
||||
/* Sets a vector to the three given values */
|
||||
#define MAT3_SET_VEC(V,X,Y,Z) ((V)[0]=(X), (V)[1]=(Y), (V)[2]=(Z))
|
||||
|
||||
/* Tests a vector for all components close to zero */
|
||||
#define MAT3_IS_ZERO_VEC(V) (MAT3_IS_ZERO((V)[0]) && \
|
||||
MAT3_IS_ZERO((V)[1]) && \
|
||||
MAT3_IS_ZERO((V)[2]))
|
||||
|
||||
/* Dot product of two vectors */
|
||||
#define MAT3_DOT_PRODUCT(V1,V2) \
|
||||
((V1)[0]*(V2)[0] + (V1)[1]*(V2)[1] + (V1)[2]*(V2)[2])
|
||||
|
||||
/* Copy one vector to other */
|
||||
#define MAT3_COPY_VEC(TO,FROM) ((TO)[0] = (FROM)[0], \
|
||||
(TO)[1] = (FROM)[1], \
|
||||
(TO)[2] = (FROM)[2])
|
||||
|
||||
/* Normalize vector to unit length, using TEMP as temporary variable.
|
||||
* TEMP will be zero if vector has zero length */
|
||||
#define MAT3_NORMALIZE_VEC(V,TEMP) \
|
||||
if ((TEMP = sqrt(MAT3_DOT_PRODUCT(V,V))) > MAT3_EPSILON) { \
|
||||
TEMP = 1.0 / TEMP; \
|
||||
MAT3_SCALE_VEC(V,V,TEMP); \
|
||||
} else TEMP = 0.0
|
||||
|
||||
/* Scale vector by given factor, storing result vector in RESULT_V */
|
||||
#define MAT3_SCALE_VEC(RESULT_V,V,SCALE) \
|
||||
MAT3_SET_VEC(RESULT_V, (V)[0]*(SCALE), (V)[1]*(SCALE), (V)[2]*(SCALE))
|
||||
|
||||
/* Adds vectors V1 and V2, storing result in RESULT_V */
|
||||
#define MAT3_ADD_VEC(RESULT_V,V1,V2) \
|
||||
MAT3_SET_VEC(RESULT_V, (V1)[0]+(V2)[0], (V1)[1]+(V2)[1], \
|
||||
(V1)[2]+(V2)[2])
|
||||
|
||||
/* Subtracts vector V2 from V1, storing result in RESULT_V */
|
||||
#define MAT3_SUB_VEC(RESULT_V,V1,V2) \
|
||||
MAT3_SET_VEC(RESULT_V, (V1)[0]-(V2)[0], (V1)[1]-(V2)[1], \
|
||||
(V1)[2]-(V2)[2])
|
||||
|
||||
/* Multiplies vectors V1 and V2, storing result in RESULT_V */
|
||||
#define MAT3_MULT_VEC(RESULT_V,V1,V2) \
|
||||
MAT3_SET_VEC(RESULT_V, (V1)[0]*(V2)[0], (V1)[1]*(V2)[1], \
|
||||
(V1)[2]*(V2)[2])
|
||||
|
||||
/* Sets RESULT_V to the linear combination of V1 and V2, scaled by
|
||||
* SCALE1 and SCALE2, respectively */
|
||||
#define MAT3_LINEAR_COMB(RESULT_V,SCALE1,V1,SCALE2,V2) \
|
||||
MAT3_SET_VEC(RESULT_V, (SCALE1)*(V1)[0] + (SCALE2)*(V2)[0], \
|
||||
(SCALE1)*(V1)[1] + (SCALE2)*(V2)[1], \
|
||||
(SCALE1)*(V1)[2] + (SCALE2)*(V2)[2])
|
||||
|
||||
/* Several of the vector macros are useful for homogeneous-coord vectors */
|
||||
#define MAT3_SET_HVEC(V,X,Y,Z,W) ((V)[0]=(X), (V)[1]=(Y), \
|
||||
(V)[2]=(Z), (V)[3]=(W))
|
||||
|
||||
#define MAT3_COPY_HVEC(TO,FROM) ((TO)[0] = (FROM)[0], \
|
||||
(TO)[1] = (FROM)[1], \
|
||||
(TO)[2] = (FROM)[2], \
|
||||
(TO)[3] = (FROM)[3])
|
||||
|
||||
#define MAT3_SCALE_HVEC(RESULT_V,V,SCALE) \
|
||||
MAT3_SET_HVEC(RESULT_V, (V)[0]*(SCALE), (V)[1]*(SCALE), \
|
||||
(V)[2]*(SCALE), (V)[3]*(SCALE))
|
||||
|
||||
#define MAT3_ADD_HVEC(RESULT_V,V1,V2) \
|
||||
MAT3_SET_HVEC(RESULT_V, (V1)[0]+(V2)[0], (V1)[1]+(V2)[1], \
|
||||
(V1)[2]+(V2)[2], (V1)[3]+(V2)[3])
|
||||
|
||||
#define MAT3_SUB_HVEC(RESULT_V,V1,V2) \
|
||||
MAT3_SET_HVEC(RESULT_V, (V1)[0]-(V2)[0], (V1)[1]-(V2)[1], \
|
||||
(V1)[2]-(V2)[2], (V1)[3]-(V2)[3])
|
||||
|
||||
#define MAT3_MULT_HVEC(RESULT_V,V1,V2) \
|
||||
MAT3_SET_HVEC(RESULT_V, (V1)[0]*(V2)[0], (V1)[1]*(V2)[1], \
|
||||
(V1)[2]*(V2)[2], (V1)[3]*(V2)[3])
|
||||
|
||||
/* ------------------------------ Entries ------------------------------- */
|
||||
|
||||
|
||||
#define MAT3identity(mat) fgmemcpy( mat, identityMatrix, sizeof(MAT3mat) )
|
||||
#define MAT3zero(mat) fgmemzero( mat, sizeof(MAT3mat) )
|
||||
#define MAT3copy(to, from) fgmemcpy( to, from, sizeof(MAT3mat) )
|
||||
|
||||
#if defined( USE_XTRA_MAT3_INLINES )
|
||||
|
||||
# define MAT3mult_vec( result_vec, vec, mat) { \
|
||||
MAT3vec tempvec; \
|
||||
tempvec[0]=vec[0]*mat[0][0]+vec[1]*mat[1][0]+vec[2]*mat[2][0]+mat[3][0]; \
|
||||
tempvec[1]=vec[0]*mat[0][1]+vec[1]*mat[1][1]+vec[2]*mat[2][1]+mat[3][1]; \
|
||||
tempvec[2]=vec[0]*mat[0][2]+vec[1]*mat[1][2]+vec[2]*mat[2][2]+mat[3][2]; \
|
||||
result_vec[0] = tempvec[0]; \
|
||||
result_vec[1] = tempvec[1]; \
|
||||
result_vec[2] = tempvec[2]; \
|
||||
}
|
||||
|
||||
# define MAT3cross_product(result_vec, vec1, vec2) { \
|
||||
MAT3vec tempvec; \
|
||||
tempvec[0] = vec1[1] * vec2[2] - vec1[2] * vec2[1]; \
|
||||
tempvec[1] = vec1[2] * vec2[0] - vec1[0] * vec2[2]; \
|
||||
tempvec[2] = vec1[0] * vec2[1] - vec1[1] * vec2[0]; \
|
||||
result_vec[0] = tempvec[0]; \
|
||||
result_vec[1] = tempvec[1]; \
|
||||
result_vec[2] = tempvec[2]; \
|
||||
}
|
||||
|
||||
# define MAT3mult( result_mat, mat1, mat2) { \
|
||||
register int i, j; \
|
||||
MAT3mat tmp_mat; \
|
||||
for (i = 0; i < 4; i++) \
|
||||
for (j = 0; j < 4; j++) \
|
||||
tmp_mat[i][j] = (mat1[i][0] * mat2[0][j] + \
|
||||
mat1[i][1] * mat2[1][j] + \
|
||||
mat1[i][2] * mat2[2][j] + \
|
||||
mat1[i][3] * mat2[3][j]); \
|
||||
fgmemcpy(result_mat, tmp_mat, sizeof(MAT3mat)); \
|
||||
}
|
||||
|
||||
#else // !defined( USE_XTRA_MAT3_INLINES )
|
||||
|
||||
/* In MAT3mat.c */
|
||||
void MAT3mult(MAT3mat result, MAT3mat, MAT3mat);
|
||||
void MAT3mult_vec(MAT3vec result_vec, MAT3vec vec, MAT3mat mat);
|
||||
void MAT3cross_product(MAT3vec result,MAT3vec,MAT3vec);
|
||||
|
||||
#endif // defined( USE_XTRA_MAT3_INLINES )
|
||||
|
||||
/* In MAT3geom.c */
|
||||
void MAT3direction_matrix (MAT3mat result_mat, MAT3mat mat);
|
||||
int MAT3normal_matrix (MAT3mat result_mat, MAT3mat mat);
|
||||
void MAT3rotate (MAT3mat result_mat, MAT3vec axis, double angle_in_radians);
|
||||
void MAT3translate (MAT3mat result_mat, MAT3vec trans);
|
||||
void MAT3scale (MAT3mat result_mat, MAT3vec scale);
|
||||
void MAT3shear(MAT3mat result_mat, double xshear, double yshear);
|
||||
|
||||
void MAT3transpose (MAT3mat result, MAT3mat);
|
||||
int MAT3invert (MAT3mat result, MAT3mat);
|
||||
void MAT3print (MAT3mat, FILE *fp);
|
||||
void MAT3print_formatted (MAT3mat, FILE *fp,
|
||||
char *title, char *head, char *format, char *tail);
|
||||
int MAT3equal( void );
|
||||
double MAT3trace( void );
|
||||
int MAT3power( void );
|
||||
int MAT3column_reduce( void );
|
||||
int MAT3kernel_basis( void );
|
||||
|
||||
/* In MAT3vec.c */
|
||||
int MAT3mult_hvec (MAT3hvec result_vec, MAT3hvec vec, MAT3mat mat, int normalize);
|
||||
void MAT3perp_vec(MAT3vec result_vec, MAT3vec vec, int is_unit);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* MAT3_HAS_BEEN_INCLUDED */
|
||||
|
||||
56
simgear/math/mat3defs.h
Normal file
56
simgear/math/mat3defs.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/* Copyright 1988, Brown Computer Graphics Group. All Rights Reserved. */
|
||||
|
||||
|
||||
#ifndef _MAT3DEFS_H
|
||||
#define _MAT3DEFS_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
/* #include <Math/mat3err.h> */
|
||||
#include "mat3.h"
|
||||
|
||||
/* ----------------------------- Constants ------------------------------ */
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#define CNULL ((char *) NULL)
|
||||
|
||||
/* ------------------------------ Macros -------------------------------- */
|
||||
|
||||
#define ALLOCN(P,T,N,M) \
|
||||
if ((P = (T *) malloc((unsigned) (N) * sizeof(T))) == NULL) \
|
||||
ERR_ERROR(MAT3_errid, ERR_FATAL, (ERR_ALLOC1, M)); \
|
||||
else
|
||||
|
||||
#define FREE(P) free((char *) (P))
|
||||
|
||||
#define ABS(A) ((A) > 0 ? (A) : -(A))
|
||||
#define MIN(A,B) ((A) < (B) ? (A) : (B))
|
||||
#define MAX(A,B) ((A) > (B) ? (A) : (B))
|
||||
|
||||
#define SWAP(A,B,T) (T = A, A = B, B = T)
|
||||
|
||||
/* Is N within EPS of zero ? */
|
||||
#define IS_ZERO(N,EPS) ((N) < EPS && (N) > -EPS)
|
||||
|
||||
/* Macros for lu routines */
|
||||
#define LU_PERMUTE(p,i,j) { int LU_T; LU_T = p[i]; p[i] = p[j]; p[j] = LU_T; }
|
||||
|
||||
/* ------------------------- Internal Entries ---------------------------- */
|
||||
|
||||
/* ------------------------- Global Variables ---------------------------- */
|
||||
|
||||
/* extern ERRid *MAT3_errid; */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _MAT3DEFS_H */
|
||||
41
simgear/math/mat3err.h
Normal file
41
simgear/math/mat3err.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#ifndef _MAT3ERR_H
|
||||
#define _MAT3ERR_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#include "sph_errtypes.h"
|
||||
|
||||
#ifdef THINK_C
|
||||
/* We hide this from gnu's compiler, which doesn't understand it. */
|
||||
void SPH__error (int errtype, ...);
|
||||
#endif
|
||||
|
||||
|
||||
#define ERR_ERROR(A,B,C) \
|
||||
if (1) {char cstr[256]; sprintf C; SPH__error(ERR_MAT3_PACKAGE, cstr); } else
|
||||
|
||||
|
||||
#define ERR_S cstr,"%s\n"
|
||||
#define ERR_SI cstr,"%s: %d\n"
|
||||
#define ERR_SS cstr,"%s: %s\n"
|
||||
|
||||
#define ERR_SEVERE 0
|
||||
#define ERR_FATAL 0
|
||||
|
||||
#define ERR_ALLOC1 0
|
||||
|
||||
typedef int ERRid;
|
||||
|
||||
#define ERRregister_package(S) 100
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _MAT3ERR_H */
|
||||
341
simgear/math/point3d.hxx
Normal file
341
simgear/math/point3d.hxx
Normal file
@@ -0,0 +1,341 @@
|
||||
// point3d.hxx -- a 3d point class.
|
||||
//
|
||||
// Adapted from algebra3 by Jean-Francois Doue, started October 1998.
|
||||
//
|
||||
// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#ifndef _POINT3D_HXX
|
||||
#define _POINT3D_HXX
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#ifdef FG_MATH_EXCEPTION_CLASH
|
||||
# define exception c_exception
|
||||
#endif
|
||||
|
||||
#ifdef FG_HAVE_STD_INCLUDES
|
||||
# include <iostream>
|
||||
# include <cassert>
|
||||
# include <cmath>
|
||||
#else
|
||||
# include <iostream.h>
|
||||
# include <assert.h>
|
||||
# include <math.h>
|
||||
#endif
|
||||
|
||||
// I don't understand ... <math.h> or <cmath> should be included
|
||||
// already depending on how you defined FG_HAVE_STD_INCLUDES, but I
|
||||
// can go ahead and add this -- CLO
|
||||
#ifdef __MWERKS__
|
||||
FG_USING_NAMESPACE(std);
|
||||
#endif
|
||||
|
||||
#ifndef FG_HAVE_NATIVE_SGI_COMPILERS
|
||||
FG_USING_STD(ostream);
|
||||
FG_USING_STD(istream);
|
||||
#endif
|
||||
|
||||
|
||||
const double fgPoint3_Epsilon = 0.0000001;
|
||||
|
||||
enum {PX, PY, PZ}; // axes
|
||||
|
||||
// Kludge for msvc++ 6.0 - requires forward decls of friend functions.
|
||||
class Point3D;
|
||||
istream& operator>> ( istream&, Point3D& );
|
||||
ostream& operator<< ( ostream&, const Point3D& );
|
||||
Point3D operator- (const Point3D& p); // -p1
|
||||
bool operator== (const Point3D& a, const Point3D& b); // p1 == p2?
|
||||
|
||||
|
||||
///////////////////////////
|
||||
//
|
||||
// 3D Point
|
||||
//
|
||||
///////////////////////////
|
||||
|
||||
class Point3D {
|
||||
|
||||
protected:
|
||||
|
||||
double n[3];
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
Point3D();
|
||||
Point3D(const double x, const double y, const double z);
|
||||
explicit Point3D(const double d);
|
||||
Point3D(const Point3D &p);
|
||||
|
||||
// Assignment operators
|
||||
|
||||
Point3D& operator = ( const Point3D& p ); // assignment of a Point3D
|
||||
Point3D& operator += ( const Point3D& p ); // incrementation by a Point3D
|
||||
Point3D& operator -= ( const Point3D& p ); // decrementation by a Point3D
|
||||
Point3D& operator *= ( const double d ); // multiplication by a constant
|
||||
Point3D& operator /= ( const double d ); // division by a constant
|
||||
|
||||
void setx(const double x);
|
||||
void sety(const double y);
|
||||
void setz(const double z);
|
||||
|
||||
// Queries
|
||||
|
||||
double& operator [] ( int i); // indexing
|
||||
double operator[] (int i) const; // read-only indexing
|
||||
|
||||
inline const double *get_n() const { return n; };
|
||||
double x() const; // cartesian x
|
||||
double y() const; // cartesian y
|
||||
double z() const; // cartesian z
|
||||
|
||||
double lon() const; // polar longitude
|
||||
double lat() const; // polar latitude
|
||||
double radius() const; // polar radius
|
||||
double elev() const; // geodetic elevation (if specifying a surface point)
|
||||
|
||||
// friends
|
||||
friend Point3D operator - (const Point3D& p); // -p1
|
||||
friend bool operator == (const Point3D& a, const Point3D& b); // p1 == p2?
|
||||
friend istream& operator>> ( istream&, Point3D& );
|
||||
friend ostream& operator<< ( ostream&, const Point3D& );
|
||||
|
||||
// Special functions
|
||||
double distance3D(const Point3D& a) const; // distance between
|
||||
double distance3Dsquared(const Point3D& a) const; // distance between ^ 2
|
||||
};
|
||||
|
||||
|
||||
// input from stream
|
||||
inline istream&
|
||||
operator >> ( istream& in, Point3D& p)
|
||||
{
|
||||
char c;
|
||||
|
||||
in >> p.n[PX];
|
||||
|
||||
// read past optional comma
|
||||
while ( in.get(c) ) {
|
||||
if ( (c != ' ') && (c != ',') ) {
|
||||
// push back on the stream
|
||||
in.putback(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
in >> p.n[PY];
|
||||
|
||||
// read past optional comma
|
||||
while ( in.get(c) ) {
|
||||
if ( (c != ' ') && (c != ',') ) {
|
||||
// push back on the stream
|
||||
in.putback(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
in >> p.n[PZ];
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
inline ostream&
|
||||
operator<< ( ostream& out, const Point3D& p )
|
||||
{
|
||||
return out << p.n[PX] << ", " << p.n[PY] << ", " << p.n[PZ];
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
//
|
||||
// Point3D Member functions
|
||||
//
|
||||
///////////////////////////
|
||||
|
||||
// CONSTRUCTORS
|
||||
|
||||
inline Point3D::Point3D() {}
|
||||
|
||||
inline Point3D::Point3D(const double x, const double y, const double z)
|
||||
{
|
||||
n[PX] = x; n[PY] = y; n[PZ] = z;
|
||||
}
|
||||
|
||||
inline Point3D::Point3D(const double d)
|
||||
{
|
||||
n[PX] = n[PY] = n[PZ] = d;
|
||||
}
|
||||
|
||||
inline Point3D::Point3D(const Point3D& p)
|
||||
{
|
||||
n[PX] = p.n[PX]; n[PY] = p.n[PY]; n[PZ] = p.n[PZ];
|
||||
}
|
||||
|
||||
// ASSIGNMENT OPERATORS
|
||||
|
||||
inline Point3D& Point3D::operator = (const Point3D& p)
|
||||
{
|
||||
n[PX] = p.n[PX]; n[PY] = p.n[PY]; n[PZ] = p.n[PZ]; return *this;
|
||||
}
|
||||
|
||||
inline Point3D& Point3D::operator += ( const Point3D& p )
|
||||
{
|
||||
n[PX] += p.n[PX]; n[PY] += p.n[PY]; n[PZ] += p.n[PZ]; return *this;
|
||||
}
|
||||
|
||||
inline Point3D& Point3D::operator -= ( const Point3D& p )
|
||||
{
|
||||
n[PX] -= p.n[PX]; n[PY] -= p.n[PY]; n[PZ] -= p.n[PZ]; return *this;
|
||||
}
|
||||
|
||||
inline Point3D& Point3D::operator *= ( const double d )
|
||||
{
|
||||
n[PX] *= d; n[PY] *= d; n[PZ] *= d; return *this;
|
||||
}
|
||||
|
||||
inline Point3D& Point3D::operator /= ( const double d )
|
||||
{
|
||||
double d_inv = 1./d; n[PX] *= d_inv; n[PY] *= d_inv; n[PZ] *= d_inv;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline void Point3D::setx(const double x) {
|
||||
n[PX] = x;
|
||||
}
|
||||
|
||||
inline void Point3D::sety(const double y) {
|
||||
n[PY] = y;
|
||||
}
|
||||
|
||||
inline void Point3D::setz(const double z) {
|
||||
n[PZ] = z;
|
||||
}
|
||||
|
||||
// QUERIES
|
||||
|
||||
inline double& Point3D::operator [] ( int i)
|
||||
{
|
||||
assert(! (i < PX || i > PZ));
|
||||
return n[i];
|
||||
}
|
||||
|
||||
inline double Point3D::operator [] ( int i) const {
|
||||
assert(! (i < PX || i > PZ));
|
||||
return n[i];
|
||||
}
|
||||
|
||||
|
||||
inline double Point3D::x() const { return n[PX]; }
|
||||
|
||||
inline double Point3D::y() const { return n[PY]; }
|
||||
|
||||
inline double Point3D::z() const { return n[PZ]; }
|
||||
|
||||
inline double Point3D::lon() const { return n[PX]; }
|
||||
|
||||
inline double Point3D::lat() const { return n[PY]; }
|
||||
|
||||
inline double Point3D::radius() const { return n[PZ]; }
|
||||
|
||||
inline double Point3D::elev() const { return n[PZ]; }
|
||||
|
||||
|
||||
// FRIENDS
|
||||
|
||||
inline Point3D operator - (const Point3D& a)
|
||||
{
|
||||
return Point3D(-a.n[PX],-a.n[PY],-a.n[PZ]);
|
||||
}
|
||||
|
||||
inline Point3D operator + (const Point3D& a, const Point3D& b)
|
||||
{
|
||||
return Point3D(a) += b;
|
||||
}
|
||||
|
||||
inline Point3D operator - (const Point3D& a, const Point3D& b)
|
||||
{
|
||||
return Point3D(a) -= b;
|
||||
}
|
||||
|
||||
inline Point3D operator * (const Point3D& a, const double d)
|
||||
{
|
||||
return Point3D(a) *= d;
|
||||
}
|
||||
|
||||
inline Point3D operator * (const double d, const Point3D& a)
|
||||
{
|
||||
return a*d;
|
||||
}
|
||||
|
||||
inline Point3D operator / (const Point3D& a, const double d)
|
||||
{
|
||||
return Point3D(a) *= (1.0 / d );
|
||||
}
|
||||
|
||||
inline bool operator == (const Point3D& a, const Point3D& b)
|
||||
{
|
||||
return
|
||||
fabs(a.n[PX] - b.n[PX]) < fgPoint3_Epsilon &&
|
||||
fabs(a.n[PY] - b.n[PY]) < fgPoint3_Epsilon &&
|
||||
fabs(a.n[PZ] - b.n[PZ]) < fgPoint3_Epsilon;
|
||||
}
|
||||
|
||||
inline bool operator != (const Point3D& a, const Point3D& b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
// Special functions
|
||||
|
||||
inline double
|
||||
Point3D::distance3D(const Point3D& a ) const
|
||||
{
|
||||
double x, y, z;
|
||||
|
||||
x = n[PX] - a.n[PX];
|
||||
y = n[PY] - a.n[PY];
|
||||
z = n[PZ] - a.n[PZ];
|
||||
|
||||
return sqrt(x*x + y*y + z*z);
|
||||
}
|
||||
|
||||
|
||||
inline double
|
||||
Point3D::distance3Dsquared(const Point3D& a ) const
|
||||
{
|
||||
double x, y, z;
|
||||
|
||||
x = n[PX] - a.n[PX];
|
||||
y = n[PY] - a.n[PY];
|
||||
z = n[PZ] - a.n[PZ];
|
||||
|
||||
return(x*x + y*y + z*z);
|
||||
}
|
||||
|
||||
|
||||
#endif // _POINT3D_HXX
|
||||
|
||||
|
||||
61
simgear/math/polar3d.cxx
Normal file
61
simgear/math/polar3d.cxx
Normal file
@@ -0,0 +1,61 @@
|
||||
// polar.cxx -- routines to deal with polar math and transformations
|
||||
//
|
||||
// Written by Curtis Olson, started June 1997.
|
||||
//
|
||||
// Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <simgear/constants.h>
|
||||
|
||||
#include "polar3d.hxx"
|
||||
|
||||
|
||||
// Find the Altitude above the Ellipsoid (WGS84) given the Earth
|
||||
// Centered Cartesian coordinate vector Distances are specified in
|
||||
// meters.
|
||||
double fgGeodAltFromCart(const Point3D& cp)
|
||||
{
|
||||
double t_lat, x_alpha, mu_alpha;
|
||||
double lat_geoc, radius;
|
||||
double result;
|
||||
|
||||
lat_geoc = FG_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
|
||||
{
|
||||
result = radius - 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);
|
||||
if (lat_geoc < 0) {
|
||||
mu_alpha = - mu_alpha;
|
||||
}
|
||||
result = (radius - x_alpha/cos(lat_geoc))*cos(mu_alpha - lat_geoc);
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
101
simgear/math/polar3d.hxx
Normal file
101
simgear/math/polar3d.hxx
Normal file
@@ -0,0 +1,101 @@
|
||||
// polar.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
|
||||
//
|
||||
// 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 _POLAR_HXX
|
||||
#define _POLAR_HXX
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
|
||||
#include <simgear/constants.h>
|
||||
#include <simgear/math/point3d.hxx>
|
||||
|
||||
|
||||
// Find the Altitude above the Ellipsoid (WGS84) given the Earth
|
||||
// Centered Cartesian coordinate vector Distances are specified in
|
||||
// meters.
|
||||
double fgGeodAltFromCart(const Point3D& cp);
|
||||
|
||||
|
||||
// Convert a polar coordinate to a cartesian coordinate. Lon and Lat
|
||||
// must be specified in radians. The FG convention is for distances
|
||||
// to be specified in meters
|
||||
inline Point3D fgPolarToCart3d(const Point3D& p) {
|
||||
double tmp = cos( p.lat() ) * p.radius();
|
||||
|
||||
return Point3D( cos( p.lon() ) * tmp,
|
||||
sin( p.lon() ) * tmp,
|
||||
sin( p.lat() ) * p.radius() );
|
||||
}
|
||||
|
||||
|
||||
// Convert a cartesian coordinate to polar coordinates (lon/lat
|
||||
// specified in radians. Distances are specified in meters.
|
||||
inline Point3D fgCartToPolar3d(const Point3D& cp) {
|
||||
return Point3D( atan2( cp.y(), cp.x() ),
|
||||
FG_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
|
||||
inline Point3D calc_lon_lat( const Point3D& orig, double course, double dist ) {
|
||||
Point3D result;
|
||||
|
||||
// lat=asin(sin(lat1)*cos(d)+cos(lat1)*sin(d)*cos(tc))
|
||||
// IF (cos(lat)=0)
|
||||
// lon=lon1 // endpoint a pole
|
||||
// ELSE
|
||||
// lon=mod(lon1-asin(sin(tc)*sin(d)/cos(lat))+pi,2*pi)-pi
|
||||
// ENDIF
|
||||
|
||||
// printf("calc_lon_lat() offset.theta = %.2f offset.dist = %.2f\n",
|
||||
// offset.theta, offset.dist);
|
||||
|
||||
dist *= METER_TO_NM * NM_TO_RAD;
|
||||
|
||||
result.sety( asin( sin(orig.y()) * cos(dist) +
|
||||
cos(orig.y()) * sin(dist) * cos(course) ) );
|
||||
|
||||
if ( cos(result.y()) < FG_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 );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#endif // _POLAR_HXX
|
||||
|
||||
|
||||
78
simgear/math/sphrintp.h
Normal file
78
simgear/math/sphrintp.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
WARNING - Do not remove this header.
|
||||
|
||||
This code is a templated version of the 'magic-software' spherical
|
||||
interpolation code by Dave Eberly. The original (un-hacked) code can be
|
||||
obtained from here: http://www.magic-software.com/gr_appr.htm
|
||||
This code is derived from linintp2.h/cpp and sphrintp.h/cpp.
|
||||
|
||||
Dave Eberly says that the conditions for use are:
|
||||
|
||||
* You may distribute the original source code to others at no charge.
|
||||
|
||||
* You may modify the original source code and distribute it to others at
|
||||
no charge. The modified code must be documented to indicate that it is
|
||||
not part of the original package.
|
||||
|
||||
* You may use this code for non-commercial purposes. You may also
|
||||
incorporate this code into commercial packages. However, you may not
|
||||
sell any of your source code which contains my original and/or modified
|
||||
source code. In such a case, you need to factor out my code and freely
|
||||
distribute it.
|
||||
|
||||
* The original code comes with absolutely no warranty and no guarantee is
|
||||
made that the code is bug-free.
|
||||
|
||||
This does not seem incompatible with GPL - so this modified version
|
||||
is hereby placed under GPL along with the rest of FlightGear.
|
||||
|
||||
Christian Mayer
|
||||
*/
|
||||
|
||||
#ifndef SPHRINTP_H
|
||||
#define SPHRINTP_H
|
||||
|
||||
#include "linintp2.h"
|
||||
#include <plib/sg.h>
|
||||
|
||||
template<class T>
|
||||
class SphereInterpolate
|
||||
{
|
||||
public:
|
||||
SphereInterpolate (int n, const double* x, const double* y,
|
||||
const double* z, const T* f);
|
||||
SphereInterpolate (int n, const sgVec2* p, const T* f);
|
||||
|
||||
~SphereInterpolate ();
|
||||
|
||||
void GetSphericalCoords (const double x, const double y, const double z,
|
||||
double& thetaAngle, double& phiAngle) const;
|
||||
|
||||
int Evaluate (const double x, const double y, const double z, T& f) const;
|
||||
int Evaluate (const double thetaAngle, const double phiAngle, T& f) const;
|
||||
|
||||
T Evaluate(const sgVec2& p) const
|
||||
{
|
||||
T retval;
|
||||
Evaluate(p[1], p[0], retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
T Evaluate(const sgVec3& p) const
|
||||
{
|
||||
T retval;
|
||||
Evaluate(p[1], p[0], retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
protected:
|
||||
int numPoints;
|
||||
double* theta;
|
||||
double* phi;
|
||||
T* func;
|
||||
mgcLinInterp2D<T>* pInterp;
|
||||
};
|
||||
|
||||
#include "sphrintp.inl"
|
||||
|
||||
#endif
|
||||
172
simgear/math/sphrintp.inl
Normal file
172
simgear/math/sphrintp.inl
Normal file
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
WARNING - Do not remove this header.
|
||||
|
||||
This code is a templated version of the 'magic-software' spherical
|
||||
interpolation code by Dave Eberly. The original (un-hacked) code can be
|
||||
obtained from here: http://www.magic-software.com/gr_appr.htm
|
||||
This code is derived from linintp2.h/cpp and sphrintp.h/cpp.
|
||||
|
||||
Dave Eberly says that the conditions for use are:
|
||||
|
||||
* You may distribute the original source code to others at no charge.
|
||||
|
||||
* You may modify the original source code and distribute it to others at
|
||||
no charge. The modified code must be documented to indicate that it is
|
||||
not part of the original package.
|
||||
|
||||
* You may use this code for non-commercial purposes. You may also
|
||||
incorporate this code into commercial packages. However, you may not
|
||||
sell any of your source code which contains my original and/or modified
|
||||
source code. In such a case, you need to factor out my code and freely
|
||||
distribute it.
|
||||
|
||||
* The original code comes with absolutely no warranty and no guarantee is
|
||||
made that the code is bug-free.
|
||||
|
||||
This does not seem incompatible with GPL - so this modified version
|
||||
is hereby placed under GPL along with the rest of FlightGear.
|
||||
|
||||
Christian Mayer
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include "sphrintp.h"
|
||||
|
||||
static const double PI = 4.0*atan(1.0);
|
||||
static const double TWOPI = 2.0*PI;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T>
|
||||
SphereInterpolate<T>::SphereInterpolate (int n, const double* x,
|
||||
const double* y, const double* z,
|
||||
const T* f)
|
||||
{
|
||||
// Assumes (x[i],y[i],z[i]) is unit length for all 0 <= i < n.
|
||||
// For complete spherical coverage, include the two antipodal points
|
||||
// (0,0,1,f(0,0,1)) and (0,0,-1,f(0,0,-1)) in the data set.
|
||||
|
||||
cout << "Initialising spherical interpolator.\n";
|
||||
cout << "[ 0%] Allocating memory \r";
|
||||
|
||||
theta = new double[3*n];
|
||||
phi = new double[3*n];
|
||||
func = new T[3*n];
|
||||
|
||||
// convert data to spherical coordinates
|
||||
int i;
|
||||
T empty;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
GetSphericalCoords(x[i],y[i],z[i],theta[i],phi[i]);
|
||||
func[i] = f[i];
|
||||
}
|
||||
|
||||
// use periodicity to get wrap-around in the Delaunay triangulation
|
||||
cout << "[ 10%] copying vertices for wrap-around\r";
|
||||
int j, k;
|
||||
for (i = 0, j = n, k = 2*n; i < n; i++, j++, k++)
|
||||
{
|
||||
theta[j] = theta[i]+TWOPI;
|
||||
theta[k] = theta[i]-TWOPI;
|
||||
phi[j] = phi[i];
|
||||
phi[k] = phi[i];
|
||||
func[j] = func[i];
|
||||
func[k] = func[i];
|
||||
}
|
||||
|
||||
pInterp = new mgcLinInterp2D<T>(3*n,theta,phi,func);
|
||||
|
||||
cout << "[100%] Finished initialising spherical interpolator. \n";
|
||||
}
|
||||
|
||||
template<class T>
|
||||
SphereInterpolate<T>::SphereInterpolate (int n, const sgVec2* p, const T* f)
|
||||
{
|
||||
// Assumes (x[i],y[i],z[i]) is unit length for all 0 <= i < n.
|
||||
// For complete spherical coverage, include the two antipodal points
|
||||
// (0,0,1,f(0,0,1)) and (0,0,-1,f(0,0,-1)) in the data set.
|
||||
cout << "Initialising spherical interpolator.\n";
|
||||
cout << "[ 0%] Allocating memory \r";
|
||||
|
||||
theta = new double[3*n];
|
||||
phi = new double[3*n];
|
||||
func = new T[3*n];
|
||||
|
||||
// convert data to spherical coordinates
|
||||
cout << "[ 10%] copying vertices for wrap-around \r";
|
||||
|
||||
int i, j, k;
|
||||
for (i = 0, j = n, k = 2*n; i < n; i++, j++, k++)
|
||||
{
|
||||
phi[i] = p[i][0];
|
||||
theta[i] = p[i][1];
|
||||
func[i] = f[i];
|
||||
|
||||
// use periodicity to get wrap-around in the Delaunay triangulation
|
||||
phi[j] = phi[i];
|
||||
phi[k] = phi[i];
|
||||
theta[j] = theta[i]+TWOPI;
|
||||
theta[k] = theta[i]-TWOPI;
|
||||
func[j] = func[i];
|
||||
func[k] = func[i];
|
||||
}
|
||||
|
||||
pInterp = new mgcLinInterp2D<T>(3*n,theta,phi,func);
|
||||
|
||||
cout << "[100%] Finished initialising spherical interpolator. \n";
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T>
|
||||
SphereInterpolate<T>::~SphereInterpolate ()
|
||||
{
|
||||
delete pInterp;
|
||||
delete[] theta;
|
||||
delete[] phi;
|
||||
delete[] func;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T>
|
||||
void SphereInterpolate<T>::GetSphericalCoords (const double x, const double y, const double z,
|
||||
double& thetaAngle,
|
||||
double& phiAngle) const
|
||||
{
|
||||
// Assumes (x,y,z) is unit length. Returns -PI <= thetaAngle <= PI
|
||||
// and 0 <= phiAngle <= PI.
|
||||
|
||||
if ( z < 1.0f )
|
||||
{
|
||||
if ( z > -1.0f )
|
||||
{
|
||||
thetaAngle = atan2(y,x);
|
||||
phiAngle = acos(z);
|
||||
}
|
||||
else
|
||||
{
|
||||
thetaAngle = -PI;
|
||||
phiAngle = PI;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
thetaAngle = -PI;
|
||||
phiAngle = 0.0f;
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T>
|
||||
int SphereInterpolate<T>::Evaluate (const double x, const double y, const double z, T& f) const
|
||||
{
|
||||
// assumes (x,y,z) is unit length
|
||||
|
||||
double thetaAngle, phiAngle;
|
||||
GetSphericalCoords(x,y,z,thetaAngle,phiAngle);
|
||||
return pInterp->Evaluate(thetaAngle,phiAngle,f);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
template<class T>
|
||||
int SphereInterpolate<T>::Evaluate (const double thetaAngle, const double phiAngle, T& f) const
|
||||
{
|
||||
return pInterp->Evaluate(thetaAngle,phiAngle,f);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
179
simgear/math/vector.cxx
Normal file
179
simgear/math/vector.cxx
Normal file
@@ -0,0 +1,179 @@
|
||||
// vector.cxx -- additional vector routines
|
||||
//
|
||||
// Written by Curtis Olson, started December 1997.
|
||||
//
|
||||
// Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// #include <Include/fg_types.h>
|
||||
|
||||
#include "vector.hxx"
|
||||
|
||||
#include "mat3.h"
|
||||
|
||||
|
||||
// Map a vector onto the plane specified by normal
|
||||
void map_vec_onto_cur_surface_plane(MAT3vec normal, MAT3vec v0, MAT3vec vec,
|
||||
MAT3vec result)
|
||||
{
|
||||
MAT3vec u1, v, tmp;
|
||||
|
||||
// calculate a vector "u1" representing the shortest distance from
|
||||
// the plane specified by normal and v0 to a point specified by
|
||||
// "vec". "u1" represents both the direction and magnitude of
|
||||
// this desired distance.
|
||||
|
||||
// u1 = ( (normal <dot> vec) / (normal <dot> normal) ) * normal
|
||||
|
||||
MAT3_SCALE_VEC( u1,
|
||||
normal,
|
||||
( MAT3_DOT_PRODUCT(normal, vec) /
|
||||
MAT3_DOT_PRODUCT(normal, normal)
|
||||
)
|
||||
);
|
||||
|
||||
// printf(" vec = %.2f, %.2f, %.2f\n", vec[0], vec[1], vec[2]);
|
||||
// printf(" v0 = %.2f, %.2f, %.2f\n", v0[0], v0[1], v0[2]);
|
||||
// printf(" u1 = %.2f, %.2f, %.2f\n", u1[0], u1[1], u1[2]);
|
||||
|
||||
// calculate the vector "v" which is the vector "vec" mapped onto
|
||||
// the plane specified by "normal" and "v0".
|
||||
|
||||
// v = v0 + vec - u1
|
||||
|
||||
MAT3_ADD_VEC(tmp, v0, vec);
|
||||
MAT3_SUB_VEC(v, tmp, u1);
|
||||
// printf(" v = %.2f, %.2f, %.2f\n", v[0], v[1], v[2]);
|
||||
|
||||
// Calculate the vector "result" which is "v" - "v0" which is a
|
||||
// directional vector pointing from v0 towards v
|
||||
|
||||
// result = v - v0
|
||||
|
||||
MAT3_SUB_VEC(result, v, v0);
|
||||
// printf(" result = %.2f, %.2f, %.2f\n",
|
||||
// result[0], result[1], result[2]);
|
||||
}
|
||||
|
||||
|
||||
// Given a point p, and a line through p0 with direction vector d,
|
||||
// find the shortest distance from the point to the line
|
||||
double fgPointLine(MAT3vec p, MAT3vec p0, MAT3vec d) {
|
||||
MAT3vec u, u1, v;
|
||||
double ud, dd, tmp;
|
||||
|
||||
// u = p - p0
|
||||
MAT3_SUB_VEC(u, p, p0);
|
||||
|
||||
// calculate the projection, u1, of u along d.
|
||||
// u1 = ( dot_prod(u, d) / dot_prod(d, d) ) * d;
|
||||
ud = MAT3_DOT_PRODUCT(u, d);
|
||||
dd = MAT3_DOT_PRODUCT(d, d);
|
||||
tmp = ud / dd;
|
||||
|
||||
MAT3_SCALE_VEC(u1, d, tmp);;
|
||||
|
||||
// v = u - u1 = vector from closest point on line, p1, to the
|
||||
// original point, p.
|
||||
MAT3_SUB_VEC(v, u, u1);
|
||||
|
||||
return sqrt(MAT3_DOT_PRODUCT(v, v));
|
||||
}
|
||||
|
||||
|
||||
// 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 fgPointLineSquared(MAT3vec p, MAT3vec p0, MAT3vec d) {
|
||||
MAT3vec u, u1, v;
|
||||
double ud, dd, tmp;
|
||||
|
||||
// u = p - p0
|
||||
MAT3_SUB_VEC(u, p, p0);
|
||||
|
||||
// calculate the projection, u1, of u along d.
|
||||
// u1 = ( dot_prod(u, d) / dot_prod(d, d) ) * d;
|
||||
ud = MAT3_DOT_PRODUCT(u, d);
|
||||
dd = MAT3_DOT_PRODUCT(d, d);
|
||||
tmp = ud / dd;
|
||||
|
||||
MAT3_SCALE_VEC(u1, d, tmp);;
|
||||
|
||||
// v = u - u1 = vector from closest point on line, p1, to the
|
||||
// original point, p.
|
||||
MAT3_SUB_VEC(v, u, u1);
|
||||
|
||||
return ( MAT3_DOT_PRODUCT(v, v) );
|
||||
}
|
||||
|
||||
|
||||
// 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 sgPointLineDistSquared( const sgVec3 p, const sgVec3 p0,
|
||||
const sgVec3 d ) {
|
||||
|
||||
sgVec3 u, u1, v;
|
||||
double ud, dd, tmp;
|
||||
|
||||
// u = p - p0
|
||||
sgSubVec3(u, p, p0);
|
||||
|
||||
// calculate the projection, u1, of u along d.
|
||||
// u1 = ( dot_prod(u, d) / dot_prod(d, d) ) * d;
|
||||
ud = sgScalarProductVec3(u, d);
|
||||
dd = sgScalarProductVec3(d, d);
|
||||
tmp = ud / dd;
|
||||
|
||||
sgScaleVec3(u1, d, tmp);;
|
||||
|
||||
// v = u - u1 = vector from closest point on line, p1, to the
|
||||
// original point, p.
|
||||
sgSubVec3(v, u, u1);
|
||||
|
||||
return ( sgScalarProductVec3(v, v) );
|
||||
}
|
||||
|
||||
|
||||
// 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 sgdPointLineDistSquared( const sgdVec3 p, const sgdVec3 p0,
|
||||
const sgdVec3 d ) {
|
||||
|
||||
sgdVec3 u, u1, v;
|
||||
double ud, dd, tmp;
|
||||
|
||||
// u = p - p0
|
||||
sgdSubVec3(u, p, p0);
|
||||
|
||||
// calculate the projection, u1, of u along d.
|
||||
// u1 = ( dot_prod(u, d) / dot_prod(d, d) ) * d;
|
||||
ud = sgdScalarProductVec3(u, d);
|
||||
dd = sgdScalarProductVec3(d, d);
|
||||
tmp = ud / dd;
|
||||
|
||||
sgdScaleVec3(u1, d, tmp);;
|
||||
|
||||
// v = u - u1 = vector from closest point on line, p1, to the
|
||||
// original point, p.
|
||||
sgdSubVec3(v, u, u1);
|
||||
|
||||
return ( sgdScalarProductVec3(v, v) );
|
||||
}
|
||||
118
simgear/math/vector.hxx
Normal file
118
simgear/math/vector.hxx
Normal file
@@ -0,0 +1,118 @@
|
||||
// vector.hxx -- additional vector routines
|
||||
//
|
||||
// Written by Curtis Olson, started December 1997.
|
||||
//
|
||||
// Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#ifndef _VECTOR_HXX
|
||||
#define _VECTOR_HXX
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <plib/sg.h>
|
||||
|
||||
#include <simgear/math/mat3.h>
|
||||
|
||||
|
||||
// Map a vector onto the plane specified by normal
|
||||
void map_vec_onto_cur_surface_plane( MAT3vec normal,
|
||||
MAT3vec v0,
|
||||
MAT3vec vec,
|
||||
MAT3vec result );
|
||||
|
||||
|
||||
inline void sgmap_vec_onto_cur_surface_plane( sgVec3 normal,
|
||||
sgVec3 v0,
|
||||
sgVec3 vec,
|
||||
sgVec3 result )
|
||||
{
|
||||
sgVec3 u1, v, tmp;
|
||||
|
||||
// calculate a vector "u1" representing the shortest distance from
|
||||
// the plane specified by normal and v0 to a point specified by
|
||||
// "vec". "u1" represents both the direction and magnitude of
|
||||
// this desired distance.
|
||||
|
||||
// u1 = ( (normal <dot> vec) / (normal <dot> normal) ) * normal
|
||||
|
||||
sgScaleVec3( u1,
|
||||
normal,
|
||||
( sgScalarProductVec3(normal, vec) /
|
||||
sgScalarProductVec3(normal, normal)
|
||||
)
|
||||
);
|
||||
|
||||
// printf(" vec = %.2f, %.2f, %.2f\n", vec[0], vec[1], vec[2]);
|
||||
// printf(" v0 = %.2f, %.2f, %.2f\n", v0[0], v0[1], v0[2]);
|
||||
// printf(" u1 = %.2f, %.2f, %.2f\n", u1[0], u1[1], u1[2]);
|
||||
|
||||
// calculate the vector "v" which is the vector "vec" mapped onto
|
||||
// the plane specified by "normal" and "v0".
|
||||
|
||||
// v = v0 + vec - u1
|
||||
|
||||
sgAddVec3(tmp, v0, vec);
|
||||
sgSubVec3(v, tmp, u1);
|
||||
// printf(" v = %.2f, %.2f, %.2f\n", v[0], v[1], v[2]);
|
||||
|
||||
// Calculate the vector "result" which is "v" - "v0" which is a
|
||||
// directional vector pointing from v0 towards v
|
||||
|
||||
// result = v - v0
|
||||
|
||||
sgSubVec3(result, v, v0);
|
||||
// printf(" result = %.2f, %.2f, %.2f\n",
|
||||
// result[0], result[1], result[2]);
|
||||
}
|
||||
|
||||
|
||||
// Given a point p, and a line through p0 with direction vector d,
|
||||
// find the shortest distance from the point to the line
|
||||
double fgPointLine(MAT3vec p, MAT3vec p0, MAT3vec 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
|
||||
double fgPointLineSquared(MAT3vec p, MAT3vec p0, MAT3vec 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
|
||||
double sgPointLineDistSquared( 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
|
||||
double sgdPointLineDistSquared( const sgdVec3 p, const sgdVec3 p0,
|
||||
const sgdVec3 d );
|
||||
|
||||
|
||||
#endif // _VECTOR_HXX
|
||||
|
||||
|
||||
73
simgear/metar/Antoi.cpp
Normal file
73
simgear/metar/Antoi.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
#pragma comment(compiler)
|
||||
#pragma comment(date)
|
||||
#pragma comment(timestamp)
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#pragma title("antoi - char array to integer")
|
||||
#pragma pagesize (80)
|
||||
|
||||
#pragma page(1)
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: antoi */
|
||||
/* Date: Jan 28, 1991 */
|
||||
/* Organization: W/OSO242 - Graphics and Display Section */
|
||||
/* Programmer: Allan Darling */
|
||||
/* Language: C/370 */
|
||||
/* */
|
||||
/* Abstract: This function will convert a character array */
|
||||
/* (string) of length (len) into an integer. */
|
||||
/* The integer is created via a call to the */
|
||||
/* function atoi. This function extends the */
|
||||
/* functionality of atoi by removing the */
|
||||
/* requirement for a sentinal delimited string */
|
||||
/* as input. */
|
||||
/* */
|
||||
/* Input: - Pointer to an array of characters. */
|
||||
/* - Integer indicating the number of character to include */
|
||||
/* in the conversion. */
|
||||
/* */
|
||||
/* Output:- An integer corresponding to the value in the character */
|
||||
/* array or MAXNEG (-2147483648) if the function is */
|
||||
/* unable to acquire system storage. */
|
||||
/* */
|
||||
/* Modification History: */
|
||||
/* None */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
|
||||
int antoi(char * string, int len)
|
||||
{
|
||||
|
||||
/*******************/
|
||||
/* local variables */
|
||||
/*******************/
|
||||
|
||||
char * tmpstr;
|
||||
int i,
|
||||
retval;
|
||||
|
||||
|
||||
/*****************/
|
||||
/* function body */
|
||||
/*****************/
|
||||
|
||||
tmpstr = (char *)malloc((len+1) * sizeof(char));
|
||||
|
||||
if (tmpstr == NULL) return (-2147483648);
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
tmpstr[i] = string[i];
|
||||
|
||||
tmpstr[len] = '\0';
|
||||
|
||||
retval = atoi(tmpstr);
|
||||
|
||||
free(tmpstr);
|
||||
|
||||
return(retval);
|
||||
|
||||
} /* end antoi */
|
||||
|
||||
#pragma page(1)
|
||||
172
simgear/metar/Charcmp.cpp
Normal file
172
simgear/metar/Charcmp.cpp
Normal file
@@ -0,0 +1,172 @@
|
||||
#pragma comment (compiler)
|
||||
//#pragma comment (date)
|
||||
//#pragma comment (timestamp)
|
||||
#pragma pagesize(80)
|
||||
|
||||
#include "Local.h" /* standard header file */
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("charcmp - characters compare with patterns ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: charcmp */
|
||||
/* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
|
||||
/* Date: 12 Dec 1995 */
|
||||
/* Programmer: CINDY L. CHONG */
|
||||
/* Language: C/370 */
|
||||
/* */
|
||||
/* Abstract: This function will compare each character in the */
|
||||
/* string match with each character in the pattern */
|
||||
/* which is made up of characters. The str can */
|
||||
/* be longer than the pattern. */
|
||||
/* */
|
||||
/* External Functions Called: */
|
||||
/* None. */
|
||||
/* */
|
||||
/* Input: str is a pointer to char */
|
||||
/* pattern is a pointer to char */
|
||||
/* */
|
||||
/* Output: Return true if str matches pattern, */
|
||||
/* otherwise, return false */
|
||||
/* */
|
||||
/* Modification History: */
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
bool charcmp(char *str, char *pattern)
|
||||
{
|
||||
|
||||
|
||||
/**********************************************************/
|
||||
/* Loop while str and pattern is not equal to null, then */
|
||||
/* inscreases str and pattern by one */
|
||||
/**********************************************************/
|
||||
|
||||
for (; *pattern != '\0'; pattern++)
|
||||
{
|
||||
if (*str == '\0')
|
||||
return FALSE;
|
||||
|
||||
/************************************************************/
|
||||
/* If pattern match str, then increase str and jump out the */
|
||||
/* case and read next char of the str and pattern */
|
||||
/************************************************************/
|
||||
|
||||
if ( isspace(*pattern) )
|
||||
pattern = nxtalpha(pattern);
|
||||
|
||||
switch( *pattern )
|
||||
{
|
||||
case 'c':
|
||||
if ( !isalnum(*str++) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
if ( !isalpha(*str) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
str++;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
if ( !iscntrl(*str++) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
if ( !isdigit(*str) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
str++;
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
if ( !isgraph(*str++) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
if ( !islower(*str++) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
if ( !isprint(*str++) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 't':
|
||||
if ( !ispunct(*str++) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
if ( !isspace(*str++) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
if ( !isupper(*str++) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 's':
|
||||
if (*str++ != ' ')
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
if ( !isspace(*str) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
while ( isspace(*str) )
|
||||
str++;
|
||||
}
|
||||
break;
|
||||
|
||||
case '\'':
|
||||
pattern++;
|
||||
if (*pattern != *str)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
pattern++;
|
||||
str++;
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
|
||||
} /* end switch */
|
||||
|
||||
} /* end for */
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
2619
simgear/metar/Dcdmetar.cpp
Normal file
2619
simgear/metar/Dcdmetar.cpp
Normal file
File diff suppressed because it is too large
Load Diff
5210
simgear/metar/Dcdmtrmk.cpp
Normal file
5210
simgear/metar/Dcdmtrmk.cpp
Normal file
File diff suppressed because it is too large
Load Diff
544
simgear/metar/Drvmetar.c
Normal file
544
simgear/metar/Drvmetar.c
Normal file
@@ -0,0 +1,544 @@
|
||||
#include "Metar.h"
|
||||
|
||||
#pragma page(1)
|
||||
#pragma subtitle(" ")
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: dRVMETAR */
|
||||
/* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
|
||||
/* Date: 28 Oct 1994 */
|
||||
/* Programmer: CARL MCCALLA */
|
||||
/* Language: C/370 */
|
||||
/* */
|
||||
/* Abstract: DRVMETAR is a main routine that acts a driver */
|
||||
/* for testing the METAR Decoder function. */
|
||||
/* */
|
||||
/* External Functions Called: */
|
||||
/* None. */
|
||||
/* DcdMETAR */
|
||||
/* prtDcdMetar */
|
||||
/* Sec0MTSm */
|
||||
/* Sec1MTSm */
|
||||
/* */
|
||||
/* Input: None */
|
||||
/* */
|
||||
/* Output: None */
|
||||
/* */
|
||||
/* Modification History: */
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
main()
|
||||
{
|
||||
char bltn_prefix[20];
|
||||
static char *string[] =
|
||||
{
|
||||
"KAST 221156Z COR 09005KT 7SM -RA OVC026 09/08 A2996 RMK "
|
||||
"AO2 TNO SLP143 P0007 60047 70109 T00890084 10100 20089 55005",
|
||||
|
||||
"KAST COR 221156Z 09005KT 7SM -RA OVC026 09/08 A2996 RMK "
|
||||
"AO2 TNO SLP143 P0007 60047 70109 T00890084 10100 20089 55005",
|
||||
|
||||
"KAST COR 221156Z 09005KT 1/SM -RA OVC026 09/08 A2996 RMK "
|
||||
"AO2 TNO SLP143 P0007 60047 70109 T00890084 10100 20089 55005",
|
||||
|
||||
"KP88 COR 221156 09005KT 1/SM -RA OVC026 09/08 A2996 RMK "
|
||||
"AO2 TNO SLP143 P0007 60047 70109 T00890084 10100 20089 55005",
|
||||
|
||||
"KP88 COR 221156 09005KT 1/SM -RA OVC026 09/08 A2996 RMK "
|
||||
"AO2 TNO SLP143 P0007 6//// 70109 T00890084 10100 20089 55005",
|
||||
|
||||
NULL,
|
||||
|
||||
|
||||
"EPIT 1755 22015G25KT 1 3/4SM R22L/2700FT R16/1200FT "
|
||||
"R34/1000V1600FT R01L/P6000FT R04RR/900FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB 18/16 A2992 "
|
||||
"RMK 58033 6003/ TWELVE 70125 10039 20029 410840112 "
|
||||
"PCPN 0009 WSHFT 1715 PK WND 2032/1725 "
|
||||
"CIG 20V25 WND 12V25 TWR VIS 2 1/2 "
|
||||
"SFC VIS 1 1/2 VIS 1/2V3/4",
|
||||
|
||||
"KFAR 181154Z 10003KT 1/4SM HZ CLR 16/13 A2988 RMK AO2 "
|
||||
"SLP117 56012 10345 20226 T01610133 $",
|
||||
|
||||
"KFAR 181154Z 10003KT 1/SM HZ CLR 16/13 A2988 RMK AO2 "
|
||||
"SLP117 56012 10345 20226 T01610133 $",
|
||||
|
||||
|
||||
|
||||
|
||||
"RKSS 21009KT 1400 RP2000 // ////// 21/20 1006/2972 NOSIG",
|
||||
|
||||
"RKSS 1200 21009KT 1400 RP2000 // ////// 21/20 1006/2972 NOSIG",
|
||||
|
||||
"RKSS 1130Z 23011KT 1100 R14R/P1500N R14L/P1500N BR SCT010 BKN030 "
|
||||
"BKN080 21/21 Q1006 NOSIG",
|
||||
|
||||
"RKSS 1130Z 23011KT 1100 R14R/P1500 R14L/P1500 BR SCT010 BKN030 "
|
||||
"BKN080 21/21 Q1006 NOSIG",
|
||||
|
||||
NULL,
|
||||
"KFAR 181154Z 10003KT 4SM HZ CLR 16/13 A2988 RMK AO2 "
|
||||
"SLP117 56012 1//// 2//// T01610133 $",
|
||||
|
||||
"CYYE 061300Z 3500KT 15SM BKN005 OVC040 08/08 A3004 RMK "
|
||||
"SF6SC1 VSBY RDCE DUE LO CLD SLP186",
|
||||
|
||||
"CYYE 061300Z 3500KT 15SM BKN005 OVC040 08/08 A3004 RMK "
|
||||
"SF6SC1 VSBY RDCE DUE10 LO CLD SLP186",
|
||||
|
||||
"CYYE 061300Z 3500KT 15SM BKN005 OVC040 08/08 A3004 RMK "
|
||||
"SF6SC1 VSBY RDCE DUE9 LO CLD SLP186",
|
||||
|
||||
"CYYE 061300Z 3500KT 15SM BKN005 OVC040 08/08 A3004 RMK "
|
||||
"SF6SC1 VSBY RDCE FZDZE10 LO CLD SLP186",
|
||||
|
||||
"CYYE 061300Z 3500KT 15SM BKN005 OVC040 08/08 A3004 RMK "
|
||||
"SF6SC1 VSBY RDCE FZDZE9 LO CLD SLP186",
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
"MKJP 1400Z 13011KT 9999 FEW022 30/XX Q1015",
|
||||
"MKJP 1400Z 13011KT 9999 FEW022 M30/XX Q1015",
|
||||
"MKJP 1400Z 13011KT 9999 FEW022 MM/XX Q1015",
|
||||
"MKJP 1400Z 13011KT 9999 FEW022 MM/30 Q1015",
|
||||
"MKJP 1400Z 13011KT 9999 FEW022 MM/M30 Q1015",
|
||||
|
||||
|
||||
|
||||
|
||||
"EGPD 36016G26KT 320V030 9999 FEW015TCU SCT026 BKN045 OVC090 "
|
||||
"SCT120 FEW250 RMK OCNL LTGICCG OHD",
|
||||
|
||||
"EGPD 36016G26KT 320V030 9999 FEW015TCU SCT026 07/01 Q1011 "
|
||||
"RMK TEMPO 8000 -SHRA BKN015 FRQ LTG VC",
|
||||
|
||||
"EGPD 36016G26KT 320V030 9999 FEW015TCU SCT026 07/01 Q1011 "
|
||||
"RMK TEMPO 8000 -SHRA BKN015 LTG DSNT W",
|
||||
|
||||
|
||||
"METAR KLAX 281156Z AUTO VRB100G135KT 130V210 3 1/2SM "
|
||||
"R15L/0500FT R22L/2700FT R16/1200FT R34/1000V1600FT R01L/P6000FT FC "
|
||||
"+TS BLPY FEW/// SCT000 BKN050 SCT150 OVC250 3/M1 A2991 RMK "
|
||||
"TORNADO B13E45 6 NE MOV E A02 PK WND 18515/45 "
|
||||
"WSHFT 1350 FROPA TWR VIS 1 1/2 SFC VIS 1/4 VIS 1/4V1 1/4 "
|
||||
"VIS 2 1/2 RY11 "
|
||||
"DVR/1000V1600FT "
|
||||
"OCNL LTG VCY STN "
|
||||
"RAB1030E1145 FZDZE56 BLPYE57 CIG 1000V1500 CIG 020 RY11 "
|
||||
"PRESFR PRESRR SLP013 FG FEW/// HZ SCT000 VIS NW 2 1/2 GR 3/4 "
|
||||
"VIRGA SE -XRAFG3 CIGE005 BKN014 V OVC "
|
||||
"FU BKN020 NOSPECI LAST 8/365 SNINCR 2/10 4/178 "
|
||||
"933125 98096 P 0125 60225 70565 "
|
||||
"T00261015 10369 21026 "
|
||||
"404800360 52101 VISNO RY05 CHINO RY27 PNO RVRNO "
|
||||
"PWINO FZRANO TSNO $",
|
||||
|
||||
|
||||
"KBOS 251356Z 26011KT 10SM CLR 12/02 A2995 RMK AO2 SC VCNTY "
|
||||
"STN SSE-NNW SCT CI ABV SLP141 T01220023",
|
||||
|
||||
"EFHK 36009KT 340V060 CAVOK 12/M02 Q1013 NOSIG",
|
||||
"EGKK 24011KT 210V300 9999 SCT020 BKN045 12/06 Q1007 NOSIG",
|
||||
"EGPD 31018KT 8000 RA FEW013 BKN021 OVC045 06/04 Q0994 NOSIG",
|
||||
"EKCH 16012KT CAVOK 20/07 Q1006 NOSIG",
|
||||
"ESKN 10014KT 9000 BR SCT100 14/04 Q1010",
|
||||
"LOWW 231450Z 14017KT CAVOK 23/07 Q1010 NOSIG",
|
||||
|
||||
|
||||
"METAR CYCH 171500Z CCA 30017KT 2SM -SN BKN006",
|
||||
|
||||
"METAR CYOW 171500Z CCA 30017KT 2SM -SN BKN006 OVC020 00/M02 "
|
||||
"A2957 RMK S35F4NS1 /S01/ SNW WET SNW MELTG ON GRND CIG 5-7 "
|
||||
"SLP018",
|
||||
|
||||
"KAST 221156Z AUTO 09005KT 7SM -RA OVC026 09/08 A2996 RMK "
|
||||
"AO2 TNO SLP143 P0007 60047 70109 T00890084 10100 20089 55005"
|
||||
" TSB0159E30 TS SE MOV NE",
|
||||
|
||||
"KAST 221156Z AUTO 09005KT 7SM -RA OVC026 09/08 A2996 RMK "
|
||||
"AO2 TNO SLP143 P0007 60047 70109 T00890084 10100 20089 55005"
|
||||
" TSE0159 TS SE",
|
||||
|
||||
"KHVR 1756Z 31007KT 5SM -SN SCT011 BKN024 OVC030 M05/M08 A3056 "
|
||||
"RMK AOA 933004 "
|
||||
"BKN V SCT TNO PCPN 000 $ SLP389 4/015 60002 "
|
||||
"T10501077 11050 21078 51010",
|
||||
|
||||
"SPECI KGFI 041420Z AUTO 18030KT 3 1/2SM RVRNO TS -RA BKN008 OVC060 "
|
||||
"26/22 A2991 RMK A02 RA15TSB20 PRESFR SLP 101 P 0000 T02640218",
|
||||
|
||||
"METAR KCLE 281156Z 170100G135KT 110V180 M1/4SM "
|
||||
"R01L/P6000FT +TSSHRA VCFG "
|
||||
"BKN025 SCT100 OVC200 M26/ A2991 RMK PK WND 18515/45 A02 "
|
||||
"WSHFT 1350 TWR VIS 1 1/2 SFC VIS 1/4 VIS 1/4V1 1/4 "
|
||||
"CIG 1000V1500 PRESFR FRQ LTG CG NW "
|
||||
"RAB1030E1145 FZDZE56 PRESRR SLP135 GS "
|
||||
"T1263 "
|
||||
"VIRGA NW 8/365 4/178 P 0125 60225 7//// 70565 10369 21026 "
|
||||
"404800360 52101 PWINO FZRANO TSNO $",
|
||||
|
||||
"CYQR 161700Z 15015KT 15SM SCT045 SCT090 BKN250 10/03 A2955 "
|
||||
"RMK SC1AC2C11 OB TAKEN H+ 5 DUE AWOS FAILURE SLP027",
|
||||
|
||||
|
||||
|
||||
|
||||
"KPIT 1755Z 22015G25KT 1 3/4SM R22L/2700FT R16/1200FT "
|
||||
"R34/1000V1600FT R01L/P6000FT R04RR/900FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB 18/16 A2992 "
|
||||
"RMK 58033 6003/ TWELVE 70125 10039 20029 410840112 "
|
||||
"PCPN 0009 WSHFT 1715 PK WND 2032/1725 "
|
||||
"CIG 20V25 WND 12V25 TWR VIS 2 1/2 "
|
||||
"SFC VIS 1 1/2 VIS 1V2",
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
"SPECI KGFI 041430Z 18045G56KT M1/4SM R15/0200FT FC +TS VV010 20/18 "
|
||||
"A2900 RMK A02A PK WND 18056/28 RAB15E25TSB20 FCB1430 PRESFR "
|
||||
"SLP 701 P 0254 199/182",
|
||||
|
||||
"SPECI KGFI 041430Z 18045G56KT M1/4SM R15/0200FT FC +TS VV010 20/18 "
|
||||
"A2900 RMK A02A PK WND 18056/28 RAB15E25TSB20 FCB1430 PRESFR "
|
||||
"SLP701 P0254 199/182",
|
||||
|
||||
"KHLN 281156Z AUTO 27005KT 10SM OVC023 07/05 A3011 RMK AOA OVC V "
|
||||
"BKN $ SLP202 60000 70001 T00670050 10122 20061 53003",
|
||||
|
||||
"KPHX 281156Z 12004KT 10SM CLR 15/05 A2996 RMK AOA SLP135 T01500050 "
|
||||
"10250 20150 53006",
|
||||
"KFCA 281156Z 30003KT 10SM CLR 06/02 A3009 RMK AO TNO $ SLP191 "
|
||||
"T00610023 10167 20056 53003",
|
||||
"KAST 281156Z 00000KT 10SM BKN095 09/08 A2997 RMK AOA SLP150 "
|
||||
"T00940084 10161 20094 52005 ",
|
||||
"KHVR 281156Z 03003KT 10SM OVC020 09/07 A3010 RMK AO TNO ZRNO "
|
||||
"$ SLP194 T00940073 10156 20089 51005",
|
||||
"KGGW 281156Z 35006KT 5SM BR OVC010 10/09 A3003 RMK AOA $ SLP177 "
|
||||
"70003 T01000095 10156 20110 53008",
|
||||
"KELY 1153Z AUTO 14004KT 10SM SCT075 01/M01 A3011 RMK AOA TNO ZRNO "
|
||||
"SLP171 70001 T00061011 10139 21006 51005",
|
||||
"KFLG 281156Z 29006KT 10SM CLR 04/M01 A3012 RMK AO TNO SLP147 "
|
||||
"T00391011 21006 51004",
|
||||
"KGTF 281156Z 27005KT 7SM BKN080 04/04 A3010 RMK AOA SLP205 "
|
||||
"T00440045 10117 20039 51006",
|
||||
|
||||
"K13A 1918Z 20011KT 26/M06 RMK AO PKWND 020/RNO 644V264 T02611061",
|
||||
|
||||
"KP88 1919Z 09001KT 14/03 RMK AO / PKWND 002/RNO 158 Z T01440034",
|
||||
|
||||
"K40B 1924Z 29004KT 15/M07 RMK AO PKWND 011/RM MV263 T01501072",
|
||||
|
||||
"KGGW 1756Z 33018KT 10SM OVC015 M03/M06 A3041 RMK AOA SLP338 "
|
||||
"4/007 60002 T10281055 11028 21072 51009",
|
||||
"KPHX 1756Z 130004KT 10SM CLR 18/M03 A3001 RMK AOA SLP154 "
|
||||
"T01781033 10178 20067 58007",
|
||||
"KFCA 1756Z 29005KT 10SM CLR 05/M11 A3049 RMK AOA TNO SLP352 "
|
||||
"T00501111 10050 21044 50004",
|
||||
"KAST 1756Z 01006KT 10SM CLR 11/04 A3047 RMK AOA SLP316 "
|
||||
"T01110045 10111 20000 50002",
|
||||
"KELY 1753Z 34010KT 10SM CLR 01/M07 A3022 RMK AOA TNO ZRNO "
|
||||
"SLP240 T00111066 10011 21078 58007",
|
||||
"KFLG 1756Z 07006KT 10SM CLR 06/M12 A3009 RMK AO TNO ZRNO "
|
||||
"SLP178 T00561122 10061 21100 58005",
|
||||
"KGTF 1756Z 35010KT 1/2SM -SN FG VV09 M06/M08 A3051 RMK AOA "
|
||||
"933004 SFC VSBY 3/4 "
|
||||
"PCPN M SLP393 60010 T10611077 11044 21067 53013",
|
||||
"KHLN 1756Z 35012KT 10SM SCT032 OVC060 M02/M09 A3048 RMK AOA "
|
||||
"SLP369 60000 T10171094 11017 21061 53006",
|
||||
"KAST 1756Z 01006KT 10SM CLR 11/04 A3047 RMK AOA SLP316 61104 "
|
||||
"71235 T01110045 10111 20000 401720056 58002",
|
||||
"METAR KLAX 04281156Z AUTO VRB100G135KT 130V210 3 1/2SM "
|
||||
"R15L/0500FT R22L/2700FT R16/1200FT R34/1000V1600FT R01L/P6000FT FC "
|
||||
"+TS BLPY FEW000 BKN050 SCT150 OVC250 3/M1 A2991 RMK "
|
||||
"TORNADO B13 DSNT NE A02 PK WND 18515/45 "
|
||||
"WSHFT 1350 FROPA TWR VIS 1 1/2 SFC VIS 1/4 VIS 1/4V1 1/4 "
|
||||
"VIS 2 1/2 RY11 OCNL LTG VCY STN "
|
||||
"RAB1030E1145 FZDZE56 BLPYE57 CIG 1000V1500 CIG 020 RY11 "
|
||||
"PRESFR PRESRR SLP013 FG FEW000 VIS NW2 1/2 GR 3/4 "
|
||||
"VIRGA SE -XRAFG3 CIGE005 BKN014 V OVC "
|
||||
"FU BKN020 NOSPECI LAST 8/365 SNINCR 2/10 4/178 "
|
||||
"933125 98096 P 0125 60225 70565 "
|
||||
"T00261015 10369 21026 "
|
||||
"404800360 52101 PWINO FZRANO TSNO $",
|
||||
|
||||
|
||||
|
||||
"METAR KGFI 041356Z AUTO 17012KT 130V210 3 1/2SM R15L/0500FT -RA "
|
||||
"SCT050 OVC110 26/18 A2991 RMK FUNNEL CLOUDS A02 RAB30 "
|
||||
"SLP 101 GR M1/4 VIRGA SCT V BKN P 0010 T02640178",
|
||||
|
||||
"METAR KGFI 041356Z AUTO 05008KT 10SM R15L/P6000FT CLR A2991 "
|
||||
"RMK WATERSPOUTS VCY STN NW A02 SLP 101 10288 20243 52021 $ ",
|
||||
|
||||
"SPECI KGFI 041430Z 18045G56KT M1/4SM R15/0200FT FC +TS VV010 20/18 "
|
||||
"A2900 RMK A02A PK WND 18056/28 OCNL LTG AP "
|
||||
"RAB15E25TSB20 FCB1430 PRESFR "
|
||||
"SLP 701 P 0254 T01990182",
|
||||
|
||||
"KABE 281900Z NIL",
|
||||
|
||||
"METAR KPIT NIL",
|
||||
|
||||
"METAR KCLE 04281156Z 170100G135KT 110V180 M1/4SM "
|
||||
"R01L/P6000FT +TSSHRA VCFG "
|
||||
"BKN025 SCT100 OVC200 M26/ A2991 RMK PK WND 18515/45 A02 "
|
||||
"WSHFT 1350 TWR VIS 1 1/2 SFC VIS 1/4 VIS 1/4V1 1/4 "
|
||||
"CIG 1000V1500 PRESFR FRQ LTG CG NW "
|
||||
"RAB1030E1145 FZDZE56 PRESRR SLP135 GS "
|
||||
"T1263 "
|
||||
"VIRGA NW 8/365 4/178 P 0125 60225 7//// 70565 10369 21026 "
|
||||
"404800360 52101 PWINO FZRANO TSNO $",
|
||||
|
||||
"METAR KPHL 040256Z AUTO 170100G135KT 130V210 1/2SM "
|
||||
"R15L/0500FT R22L/2700FT R16/1200FT R34/1000V1600FT R01L/P6000FT "
|
||||
"FC +TS BKN050 SCT150 OVC250 M26/ A2991 RMK A02 PK WND 185150/1345 "
|
||||
"WSHFT 1350 TWR VIS 1 1/2 SFC VIS 1/4 VIS 1/4V1 1/4 LTG DSNT "
|
||||
"RAB1030E1145 FZDZE56 CIG 1000V1500 PRESFR PRESRR SLP037 GR 2 3/4 "
|
||||
"VIRGA E 8/365 4/178 P 0125 70565 21026 T0263 10369 60225 "
|
||||
"404800360 52101 PWINO FZRANO TSNO $",
|
||||
|
||||
"SPECI KGFI 041420Z AUTO 18030KT 2 1/2SM RVRNO TS -RA BKN008 "
|
||||
"OVC060 25/22 A2991 RMK A02 LTG DSNT W "
|
||||
"RAB15TSB20 PRESFR SLP101 P 0000 "
|
||||
"254/218",
|
||||
|
||||
"METAR KGFI 041356Z AUTO 170100G135KT 130V210 3 1/2SM "
|
||||
"R15L/0500FT R22L/2700FT R16/1200FT R34/1000V1600FT R01L/P6000FT "
|
||||
"FC +TS BKN050 SCT150 OVC250 M26/ A2991 RMK A02 PK WND 185150/1345 "
|
||||
"WSHFT 1350 TWR VIS 1 1/2 SFC VIS 1/4 VIS 1/4V1 1/4 "
|
||||
"RAB1030E1145 FZDZE56 CIG 1000V1500 PRESFR PRESRR SLP997 GR M1/4 "
|
||||
"VIRGA SE 8/365 4/178 P 0125 6//// 60225 70565 T0263 10369 21026 "
|
||||
"404800360 52101 PWINO FZRANO TSNO $",
|
||||
|
||||
|
||||
|
||||
|
||||
"METAR KGFI 041356Z AUTO 170100G135KT 130V210 3 1/2SM "
|
||||
"R15L/0500FT R22L/2700FT R16/1200FT R34/1000V1600FT R01L/P6000FT "
|
||||
"FC +TS BKN050 SCT150 OVC250 M26/ A2991 RMK A02 PK WND 185150/1345 "
|
||||
"WSHFT 1350 TWR VIS 1 1/2 SFC VIS 1/4 VIS 1/4V1 1/4 "
|
||||
"RAB1030E1145 FZDZE56 CIG 1000V1500 PRESFR PRESRR SLP997 GR 25 "
|
||||
"VIRGA 35 8/365 4/178 P 0125 6//// 60225 70565 T0263 10369 21026 "
|
||||
"VIRGA 35 8/365 4/178 P 0125 21026 70565 10369 60225 T0263 21026 "
|
||||
"404800360 52101 PWINO FZRANO TSNO $",
|
||||
|
||||
|
||||
"METAR KGFI 041356Z AUTO 170100G135KT 130V210 3 1/2SM "
|
||||
"R15L/0500FT R22L/2700FT R16/1200FT R34/1000V1600FT R01L/P6000FT "
|
||||
"FC +TS BKN050 SCT150 OVC250 3/M1 A2991 RMK A02 PK WND 18515/45 "
|
||||
"WSHFT 1350 TWR VIS 1 1/2 SFC VIS 1/4 VIS 1/4V1 1/4 "
|
||||
"RAB1030E1145 FZDZE56 CIG 1000V1500 PRESFR PRESRR SLP997 GR 25 "
|
||||
"VIRGA 35 8/365 4/178 P 0125 60225 70565 T00261015 10369 21026 "
|
||||
"404800360 52101 PWINO FZRANO TSNO $",
|
||||
|
||||
"METAR KGFI 041356Z AUTO 170100G135KT 130V210 3 1/2SM "
|
||||
"R15L/0500FT R22L/2700FT R16/1200FT R34/1000V1600FT R01L/P6000FT "
|
||||
"FC +TS BKN050 SCT150 OVC250 3/M1 A2991 RMK A02 PK WND 185150/1345 "
|
||||
"WSHFT 1350 TWR VIS 1 1/2 SFC VIS 1/4 VIS 1/4V1 1/4 "
|
||||
"RAB1030E1145 FZDZE56 CIG 1000V1500 PRESFR PRESRR SLP997 GR 25 "
|
||||
"VIRGA 35 8/365 4/178 P 0125 60225 70565 T00261015 10369 21026 "
|
||||
"404800360 52101 PWINO FZRANO TSNO",
|
||||
|
||||
|
||||
|
||||
"METAR KGFI 041356Z AUTO 05008KT 10SM R15L/P6000FT CLR A2991 RMK "
|
||||
"A02 SLP 101 10288 20243 52021",
|
||||
"SPECI DGFI 041430Z 18045G56KT M1/4SM R15/0200FT FC +TS VV010 20/18 "
|
||||
"M20/M18 A2900 RMK A02A PK WND 18056/28 RAB15E25TSB20 FCB1430 PRESFR "
|
||||
"SLP 701 P 0254 M199/M182",
|
||||
|
||||
"SPECI DGFI 041430Z 18045G56KT M1/4SM R15/0200FT FC +TS VV010 20/18 "
|
||||
"M20/M18 A2900 RMK A02A PK WND 18056/28 RAB15E25TSB20 FCB1430 PRESFR "
|
||||
"SLP 701 P 0254 M199/182",
|
||||
|
||||
"SPECI DGFI 041430Z 18045G56KT M1/4SM R15/0200FT FC +TS VV010 20/18 "
|
||||
"M20/M18 A2900 RMK A02A PK WND 18056/28 RAB15E25TSB20 FCB1430 PRESFR "
|
||||
"SLP 701 P 0254 199/M182",
|
||||
|
||||
"METAR APIT 171755Z AUTO 22015G25KT 1 3/4SM R22L/2700FT R16/1200FT "
|
||||
"R34/1000V1600FT R01L/P6000FT R04RR/900FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB 18/16 A2992 "
|
||||
"RMK 4/369 58033 6003/ TWELVE 70125 10039 20029 410840112 "
|
||||
"PCPN 0009 8/563 WSHFT 1715 PK WND 2032/1725 "
|
||||
"CIG 20V25 WND 12V25 TWR VIS 2 1/2 "
|
||||
"SFC VIS 1 1/2 VIS 1 1/2V2 SLP875 SGB1213E1225",
|
||||
|
||||
"NZWN 1700Z 35030G49KT 320V030 20KM 02 5SC021 7SC046 12/08 "
|
||||
" Q0994.2 TEMPO 6000 RA 5ST012 2CB015 RMK SLP056 "
|
||||
"RAE0123",
|
||||
|
||||
"SPECI APIT 171755Z 22015G25KT 1 3/4SM R22L/2700FT R16/1200FT "
|
||||
"R34/1000V1600FT R01L/P6000FT R04RR/900FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB 18/16 A2992 "
|
||||
"RMK 58033 6003/ TWELVE 70125 8/321 10039 20029 410840112 "
|
||||
"PCPN 0009 WSHFT 1715 PK WND 2032/1725 "
|
||||
"CIG 20V25 WND 12V25 TWR VIS 2 1/2 "
|
||||
"SFC VIS 1 1/2 VIS 1 SLP875 FGB1713",
|
||||
|
||||
"APIT 1755Z 22015G25KT 1 3/4SM R22L/2700FT R16/1200FT "
|
||||
"R34/1000V1600FT R01L/P6000FT R04RR/900FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB 18/16 A2992 "
|
||||
"RMK 58033 6003/ TWELVE 70125 10039 20029 410840112 "
|
||||
"PCPN 0009 WSHFT 1715 PK WND 2032/1725 "
|
||||
"CIG 20V25 WND 12V25 TWR VIS 2 1/2 "
|
||||
"SFC VIS 1 1/2 VIS 1V2 SLP875",
|
||||
|
||||
|
||||
"APIT 1755Z 22015G25KT 1 3/4SM R22L/2700FT R16/1200FT "
|
||||
"R34/1000V1600FT R01L/P6000FT R04RR/900FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB 18/16 A2992 "
|
||||
"RMK 58033 6003/ TWELVE 70125 10039 20029 410840112 "
|
||||
"PCPN 0009 WSHFT 1715 PK WND 2032/1725 "
|
||||
"CIG 20V25 WND 12V25 TWR VIS 2 1/2 "
|
||||
"SFC VIS 1 1/2 VIS 1 1/2V2 1/2 SLP875",
|
||||
|
||||
"APIT 1755Z 22015G25KT 1 3/4SM R22L/2700FT R16/1200FT "
|
||||
"R34/1000V1600FT R01L/P6000FT R04RR/900FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB 18/16 A2992 "
|
||||
"RMK 58033 6003/ TWELVE 70125 10039 20029 410840112 "
|
||||
"PCPN 0009 WSHFT 1715 PK WND 2032/1725 "
|
||||
"CIG 20V25 WND 12V25 TWR VIS 2 1/2 "
|
||||
"SFC VIS 1 1/2 VIS 1V2 1/2 SLP875",
|
||||
|
||||
|
||||
"EGPF 1720Z 00000KT 9999 -SHRA STC014 SCT020CB BNK024 12/09 "
|
||||
"Q1003 NOSIG",
|
||||
|
||||
"NZAA 1700Z 03010KT 30KM 03 5CU022 7SC035 11/07 Q1006.5 NOSIG",
|
||||
"NZWN 1700Z 35030G49KT 320V030 20KM 02 5SC021 7SC046 12/08 "
|
||||
" Q0994.2 TEMPO 6000 RA 5ST012 2CB015 RMK KAUKAU 30050KT",
|
||||
"DGAA 1800Z 22012KT 9999 SCT009 BKN120 25/21 Q1015",
|
||||
"DAAT 1830Z 30010KT CAVOK 29/06 Q1019",
|
||||
|
||||
"GQPP 1800Z 34023KT 3000 DRSA SKC 24/20 Q1011 NSG",
|
||||
"DAAG 1830Z 06006KT 9999 SCT020 25/22 Q1015",
|
||||
"DABB 1830Z 04010KT 9999 SCT030TCU SCT033CB 27/18 Q1017",
|
||||
"DABC 1830Z 00000KT 9999 SCT026TCU SCT036CB 22/18 Q1020 RETS",
|
||||
|
||||
"NZAA 1700Z 03010KT 30KM 03 5CU022 7SC035 11/07 Q1006.5 NOSIG",
|
||||
"NZWN 1700Z 35030G49KT 320V030 20KM 02 5SC021 7SC046 12/08 "
|
||||
" Q0994.2 TEMPO 6000 RA 5ST012 2CB015 RMK K",
|
||||
"NZWN 1700Z 35030G49KT 320V030 20KM 02 5SC021 7SC046 12/08 "
|
||||
" Q0994.2 TEMPO 6000 RA 5ST012 2CB015 RMK KAUKAU 30050KT",
|
||||
"DGAA 1800Z 22012KT 9999 SCT009 BKN120 25/21 Q1015",
|
||||
|
||||
"GFLL 1900Z NIL",
|
||||
|
||||
"GOOY 1800Z 03006G17KT 340V080 6000 TSRA BKN016 BKN030CB "
|
||||
"BKN133 26/23 Q1013 NOSIG",
|
||||
|
||||
"GCXO 1930Z 32018KT 8000 SCT003 SCT007 18/16 Q1019",
|
||||
|
||||
"APIT 1755Z 22015G25KT 1 3/4SM R22L/2700FT R16/1200FT "
|
||||
"R34/1000V1600FT R01L/P6000FT R04RR/900FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB 18/16 A2992 "
|
||||
"RMK 58033 6003/ TWELVE 70125 10039 20029 410840112 "
|
||||
"PCPN 0009 WSHFT 1715 PK WND 2032/1725 "
|
||||
"CIG 20V25 WND 12V25 TWR VIS 2 1/2 "
|
||||
"SFC VIS 1 1/2 VIS 1 1/2V2",
|
||||
|
||||
"BPIT 1755Z 22015G25KT 1 3/4SM R22L/2700FT R16/1200FT "
|
||||
"R34/1000V1600FT R01L/P6000FT R04RR/900FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB 18/16 A2992 "
|
||||
"RMK 58033 6003/ TWELVE 70125 10039 20029 410840112 "
|
||||
"PCPN 0009 WSHFT 1715 PK WND 2032/1725 "
|
||||
"CIG 20V25 WND 12V25 TWR VIS 2 1/2 "
|
||||
"SFC VIS 1 1/2 VIS 1V2",
|
||||
|
||||
"CPIT 1755Z 22015G25KT 1 3/4SM R22L/2700FT R16/1200FT "
|
||||
"R34/1000V1600FT R01L/P6000FT R04RR/900FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB 18/16 A2992 "
|
||||
"RMK 58033 6003/ TWELVE 70125 10039 20029 410840112 "
|
||||
"PCPN 0009 WSHFT 1715 PK WND 2032/1725 "
|
||||
"CIG 20V25 WND 12V25 TWR VIS 2 1/2 "
|
||||
"SFC VIS 1 1/2 VIS 1V2 1/2",
|
||||
|
||||
"DPIT 1755Z 22015G25KT 1 3/4SM R22L/2700FT R16/1200FT "
|
||||
"R34/1000V1600FT R01L/P6000FT R04RR/900FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB 18/16 A2992 "
|
||||
"RMK 58033 6003/ TWELVE 70125 10039 20029 410840112 "
|
||||
"PCPN 0009 WSHFT 1715 PK WND 2032/1725 "
|
||||
"CIG 20V25 WND 12V25 TWR VIS 2 1/2 "
|
||||
"SFC VIS 1 1/2 VIS 1 1/2V2 1/2",
|
||||
|
||||
|
||||
"FPIT 1755Z 22015G25KT 1 3/4SM R22L/2700FT R16/1200FT "
|
||||
"R34/1000V1600FT R01L/P6000FT R04RR/900FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB 18/16 A2992 "
|
||||
"RMK 58033 6003/ TWELVE 70125 10039 20029 410840112 "
|
||||
"PCPN 0009 WSHFT 1715 PK WND 2032/1725 "
|
||||
"CIG 20V25 WND 12V25 TWR VIS 2 1/2 "
|
||||
"SFC VIS 1 1/2 VIS 3/4V2 1/2",
|
||||
|
||||
"GPIT 1755Z 22015G25KT 1 3/4SM R22L/2700FT R16/1200FT "
|
||||
"R34/1000V1600FT R01L/P6000FT R04RR/900FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB 18/16 A2992 "
|
||||
"RMK 58033 6003/ TWELVE 70125 10039 20029 410840112 "
|
||||
"PCPN 0009 WSHFT 1715 PK WND 2032/1725 "
|
||||
"CIG 20V25 WND 12V25 TWR VIS 2 1/2 "
|
||||
"SFC VIS 1 1/2 VIS 3/4V3",
|
||||
|
||||
"KPIT 1935Z 22015G25KT 1 3/4SM R22L/2700FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB M18/M16 A2992",
|
||||
|
||||
"KPIT 1935Z 22015G25KT 1 3/4SM R22L/2700FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB M18/16 A2992",
|
||||
|
||||
"KPIT 1935Z 22015G25KT 1 3/4SM R22L/2700FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB 18/M16 A2992",
|
||||
|
||||
"KPIT 1935Z 22015G25KT 1 3/4SM R22L/2700FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB MM/M16 A2992",
|
||||
|
||||
"KPIT 1935Z 22015G25KT 1 3/4SM R22L/2700FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB MM/16 A2992",
|
||||
|
||||
"KPIT 1935Z 22015G25KT 1 3/4SM R22L/2700FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB M18/MM A2992",
|
||||
|
||||
"KPIT 1935Z 22015G25KT 1 3/4SM R22L/2700FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB 18/MM A2992",
|
||||
|
||||
NULL};
|
||||
|
||||
/***************************/
|
||||
/* DECLARE LOCAL VARIABLES */
|
||||
/***************************/
|
||||
|
||||
Decoded_METAR Metar;
|
||||
Decoded_METAR *Mptr = &Metar;
|
||||
int j,
|
||||
ErReturn;
|
||||
static char *synopRTRN = NULL;
|
||||
|
||||
|
||||
/***************************************************/
|
||||
/* START BODY OF MAIN ROUTINE FOR CALLING DcdMETAR */
|
||||
/***************************************************/
|
||||
|
||||
j = 0;
|
||||
|
||||
while( string[j] != NULL)
|
||||
{
|
||||
/*-- PRINT INPUT METAR REPORT ----------------------------*/
|
||||
printf("INPUT METAR REPORT: %s\n",string[j] );
|
||||
|
||||
/*-- DECODE INPUT REPORT ---------------------------------*/
|
||||
if ( (ErReturn = DcdMETAR( string[ j ], Mptr )) != 0 )
|
||||
printf("DcdMETAR: Error Return Number: %d\n",ErReturn);
|
||||
|
||||
/*-- PRINT DECODED METAR REPORT ELEMENTS -----------------*/
|
||||
prtDMETR( Mptr );
|
||||
|
||||
j++;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
63
simgear/metar/Fracpart.cpp
Normal file
63
simgear/metar/Fracpart.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
#include "Local.h" /* standard header file */
|
||||
#include "Metar.h"
|
||||
|
||||
#pragma subtitle(" ")
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: fracPart */
|
||||
/* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
|
||||
/* Date: 13 Jun 1995 */
|
||||
/* Programmer: CARL MCCALLA */
|
||||
/* Language: C/370 */
|
||||
/* */
|
||||
/* Abstract: Convert a character string fraction into a */
|
||||
/* decimal (floating point) number. */
|
||||
/* */
|
||||
/* External Functions Called: */
|
||||
/* None. */
|
||||
/* */
|
||||
/* Input: string - a pointer to a character string frac- */
|
||||
/* tion. */
|
||||
/* Output: A decimal (floating point) number. */
|
||||
/* */
|
||||
/* Modification History: */
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
float fracPart( char *string )
|
||||
{
|
||||
|
||||
/***************************/
|
||||
/* DECLARE LOCAL VARIABLES */
|
||||
/***************************/
|
||||
|
||||
char buf[ 6 ],
|
||||
*slash;
|
||||
|
||||
float numerator,
|
||||
denominator;
|
||||
|
||||
/*************************/
|
||||
/* START BODY OF ROUTINE */
|
||||
/*************************/
|
||||
|
||||
slash = strchr(string, '/');
|
||||
|
||||
memset(buf , '\0', 6);
|
||||
strncpy( buf, string, slash-string);
|
||||
|
||||
numerator = (float) atoi(buf);
|
||||
|
||||
memset(buf , '\0', 6);
|
||||
strcpy( buf, slash+1);
|
||||
|
||||
denominator = (float) atoi(buf);
|
||||
|
||||
return (numerator/denominator);
|
||||
|
||||
}
|
||||
|
||||
1171
simgear/metar/Local.h
Normal file
1171
simgear/metar/Local.h
Normal file
File diff suppressed because it is too large
Load Diff
12
simgear/metar/Makefile.am
Normal file
12
simgear/metar/Makefile.am
Normal file
@@ -0,0 +1,12 @@
|
||||
includedir = @includedir@/metar
|
||||
|
||||
lib_LIBRARIES = libsgmetar.a
|
||||
|
||||
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 \
|
||||
Prtdmetr.cpp Stspack2.cpp Stspack3.cpp
|
||||
|
||||
INCLUDES += -I$(top_builddir)
|
||||
149
simgear/metar/Metar.dsp
Normal file
149
simgear/metar/Metar.dsp
Normal file
@@ -0,0 +1,149 @@
|
||||
# Microsoft Developer Studio Project File - Name="Metar" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
||||
|
||||
CFG=Metar - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "Metar.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "Metar.mak" CFG="Metar - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "Metar - Win32 Release" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "Metar - Win32 Debug" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "Metar - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD CPP /nologo /G6 /W3 /GX /Zi /O2 /I "..\..\..\lib" /I "..\lib" /I "..\..\lib" /I "..\..\..\..\lib" /I ".." /I "..\.." /I "..\..\.." /I "..\..\..\.." /I "..\include" /I "..\..\include" /I "..\..\..\include" /I "..\..\..\..\include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /FD /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "Metar - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /G6 /W3 /Gm /GX /Zi /Od /I "..\..\..\lib" /I "..\lib" /I "..\..\lib" /I "..\..\..\..\lib" /I ".." /I "..\.." /I "..\..\.." /I "..\..\..\.." /I "..\include" /I "..\..\include" /I "..\..\..\include" /I "..\..\..\..\include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "Metar - Win32 Release"
|
||||
# Name "Metar - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Antoi.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Charcmp.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Dcdmetar.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Dcdmtrmk.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Fracpart.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\MetarReport.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\MetarStation.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Prtdmetr.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Stspack2.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Stspack3.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\LOCAL.H
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\METAR.H
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\MetarReport.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\MetarStation.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
265
simgear/metar/Metar.h
Normal file
265
simgear/metar/Metar.h
Normal file
@@ -0,0 +1,265 @@
|
||||
#ifndef METARX
|
||||
#define METARX
|
||||
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: METAR H */
|
||||
/* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
|
||||
/* Date: 19 Jan 1996 */
|
||||
/* Programmer: CARL MCCALLA */
|
||||
/* Language: C/370 */
|
||||
/* */
|
||||
/* Abstract: METAR Decoder Header File. */
|
||||
/* */
|
||||
/* Modification History: */
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
|
||||
|
||||
#include "Local.h" /* standard header file */
|
||||
|
||||
|
||||
/*********************************************/
|
||||
/* */
|
||||
/* RUNWAY VISUAL RANGE STRUCTURE DECLARATION */
|
||||
/* AND VARIABLE TYPE DEFINITION */
|
||||
/* */
|
||||
/*********************************************/
|
||||
|
||||
typedef struct runway_VisRange {
|
||||
char runway_designator[6];
|
||||
bool vrbl_visRange;
|
||||
bool below_min_RVR;
|
||||
bool above_max_RVR;
|
||||
int visRange;
|
||||
int Max_visRange;
|
||||
int Min_visRange;
|
||||
} Runway_VisRange;
|
||||
|
||||
/***********************************************/
|
||||
/* */
|
||||
/* DISPATCH VISUAL RANGE STRUCTURE DECLARATION */
|
||||
/* AND VARIABLE TYPE DEFINITION */
|
||||
/* */
|
||||
/***********************************************/
|
||||
|
||||
typedef struct dispatch_VisRange {
|
||||
bool vrbl_visRange;
|
||||
bool below_min_DVR;
|
||||
bool above_max_DVR;
|
||||
int visRange;
|
||||
int Max_visRange;
|
||||
int Min_visRange;
|
||||
} Dispatch_VisRange;
|
||||
|
||||
/*****************************************/
|
||||
/* */
|
||||
/* CLOUD CONDITION STRUCTURE DECLARATION */
|
||||
/* AND VARIABLE TYPE DEFINITION */
|
||||
/* */
|
||||
/*****************************************/
|
||||
|
||||
typedef struct cloud_Conditions {
|
||||
char cloud_type[5];
|
||||
char cloud_hgt_char[4];
|
||||
char other_cld_phenom[4];
|
||||
int cloud_hgt_meters;
|
||||
} Cloud_Conditions;
|
||||
|
||||
/*****************************************/
|
||||
/* */
|
||||
/* WIND GROUP DATA STRUCTURE DECLARATION */
|
||||
/* AND VARIABLE TYPE DEFINITION */
|
||||
/* */
|
||||
/*****************************************/
|
||||
|
||||
typedef struct windstruct {
|
||||
char windUnits[ 4 ];
|
||||
bool windVRB;
|
||||
int windDir;
|
||||
int windSpeed;
|
||||
int windGust;
|
||||
} WindStruct;
|
||||
|
||||
/*****************************************/
|
||||
/* */
|
||||
/* RECENT WX GROUP STRUCTURE DECLARATION */
|
||||
/* AND VARIABLE TYPE DEFINITION */
|
||||
/* */
|
||||
/*****************************************/
|
||||
|
||||
typedef struct recent_wx {
|
||||
char Recent_weather[ 5 ];
|
||||
int Bhh;
|
||||
int Bmm;
|
||||
int Ehh;
|
||||
int Emm;
|
||||
} Recent_Wx;
|
||||
|
||||
/***************************************/
|
||||
/* */
|
||||
/* DECODED METAR STRUCTURE DECLARATION */
|
||||
/* AND VARIABLE TYPE DEFINITION */
|
||||
/* */
|
||||
/***************************************/
|
||||
|
||||
typedef struct decoded_METAR {
|
||||
char synoptic_cloud_type[ 6 ];
|
||||
char snow_depth_group[ 6 ];
|
||||
char codeName[ 6 ];
|
||||
char stnid[5];
|
||||
char horiz_vsby[5];
|
||||
char dir_min_horiz_vsby[3];
|
||||
char vsby_Dir[ 3 ];
|
||||
char WxObstruct[10][8];
|
||||
char autoIndicator[5];
|
||||
char VSBY_2ndSite_LOC[10];
|
||||
char SKY_2ndSite_LOC[10];
|
||||
char SKY_2ndSite[10];
|
||||
char SectorVsby_Dir[ 3 ];
|
||||
char ObscurAloft[ 12 ];
|
||||
char ObscurAloftSkyCond[ 12 ];
|
||||
char VrbSkyBelow[ 4 ];
|
||||
char VrbSkyAbove[ 4 ];
|
||||
char LTG_DIR[ 3 ];
|
||||
char CloudLow;
|
||||
char CloudMedium;
|
||||
char CloudHigh;
|
||||
char CIG_2ndSite_LOC[10];
|
||||
char VIRGA_DIR[3];
|
||||
char TornadicType[15];
|
||||
char TornadicLOC[10];
|
||||
char TornadicDIR[4];
|
||||
char TornadicMovDir[3];
|
||||
char CHINO_LOC[6];
|
||||
char VISNO_LOC[6];
|
||||
char PartialObscurationAmt[2][7];
|
||||
char PartialObscurationPhenom[2][12];
|
||||
char SfcObscuration[6][10];
|
||||
char charPrevailVsby[12];
|
||||
char charVertVsby[10];
|
||||
char TS_LOC[3];
|
||||
char TS_MOVMNT[3];
|
||||
|
||||
bool Indeterminant3_6HrPrecip;
|
||||
bool CIGNO;
|
||||
bool SLPNO;
|
||||
bool ACFTMSHP;
|
||||
bool NOSPECI;
|
||||
bool FIRST;
|
||||
bool LAST;
|
||||
bool SunSensorOut;
|
||||
bool AUTO;
|
||||
bool COR;
|
||||
bool NIL_rpt;
|
||||
bool CAVOK;
|
||||
bool RVRNO;
|
||||
bool A_altstng;
|
||||
bool Q_altstng;
|
||||
bool VIRGA;
|
||||
bool VOLCASH;
|
||||
bool GR;
|
||||
bool CHINO;
|
||||
bool VISNO;
|
||||
bool PNO;
|
||||
bool PWINO;
|
||||
bool FZRANO;
|
||||
bool TSNO;
|
||||
bool DollarSign;
|
||||
bool PRESRR;
|
||||
bool PRESFR;
|
||||
bool Wshft_FROPA;
|
||||
bool OCNL_LTG;
|
||||
bool FRQ_LTG;
|
||||
bool CNS_LTG;
|
||||
bool CG_LTG;
|
||||
bool IC_LTG;
|
||||
bool CC_LTG;
|
||||
bool CA_LTG;
|
||||
bool DSNT_LTG;
|
||||
bool AP_LTG;
|
||||
bool VcyStn_LTG;
|
||||
bool OVHD_LTG;
|
||||
bool LightningVCTS;
|
||||
bool LightningTS;
|
||||
|
||||
int TornadicDistance;
|
||||
int ob_hour;
|
||||
int ob_minute;
|
||||
int ob_date;
|
||||
int minWnDir;
|
||||
int maxWnDir;
|
||||
int VertVsby;
|
||||
int temp;
|
||||
int dew_pt_temp;
|
||||
int QFE;
|
||||
int hectoPasc_altstng;
|
||||
int char_prestndcy;
|
||||
int minCeiling;
|
||||
int maxCeiling;
|
||||
int WshfTime_hour;
|
||||
int WshfTime_minute;
|
||||
int min_vrbl_wind_dir;
|
||||
int max_vrbl_wind_dir;
|
||||
int PKWND_dir;
|
||||
int PKWND_speed;
|
||||
int PKWND_hour;
|
||||
int PKWND_minute;
|
||||
int SKY_2ndSite_Meters;
|
||||
int Ceiling;
|
||||
int Estimated_Ceiling;
|
||||
int SNINCR;
|
||||
int SNINCR_TotalDepth;
|
||||
int SunshineDur;
|
||||
int ObscurAloftHgt;
|
||||
int VrbSkyLayerHgt;
|
||||
int Num8thsSkyObscured;
|
||||
int CIG_2ndSite_Meters;
|
||||
int snow_depth;
|
||||
int BTornadicHour;
|
||||
int BTornadicMinute;
|
||||
int ETornadicHour;
|
||||
int ETornadicMinute;
|
||||
|
||||
|
||||
float SectorVsby;
|
||||
float WaterEquivSnow;
|
||||
float VSBY_2ndSite;
|
||||
float prevail_vsbySM;
|
||||
float prevail_vsbyM;
|
||||
float prevail_vsbyKM;
|
||||
float prestndcy;
|
||||
float precip_amt;
|
||||
float precip_24_amt;
|
||||
float maxtemp;
|
||||
float mintemp;
|
||||
float max24temp;
|
||||
float min24temp;
|
||||
float minVsby;
|
||||
float maxVsby;
|
||||
float hourlyPrecip;
|
||||
float TWR_VSBY;
|
||||
float SFC_VSBY;
|
||||
float Temp_2_tenths;
|
||||
float DP_Temp_2_tenths;
|
||||
float SLP;
|
||||
float GR_Size;
|
||||
|
||||
double inches_altstng;
|
||||
|
||||
Runway_VisRange RRVR[12];
|
||||
Dispatch_VisRange DVR;
|
||||
Recent_Wx ReWx[3];
|
||||
WindStruct winData;
|
||||
Cloud_Conditions cldTypHgt[6];
|
||||
|
||||
} Decoded_METAR;
|
||||
|
||||
#define MAXWXSYMBOLS 10 /*-- NOT TO EXCEED 10 PRES. WX GRPS --*/
|
||||
#define MAXTOKENS 500 /*-- RPT NOT TO EXCEED 500 GRPS --*/
|
||||
|
||||
void prtDMETR( Decoded_METAR *Mptr );
|
||||
int DcdMETAR( char *string, Decoded_METAR *Mptr );
|
||||
|
||||
#endif
|
||||
259
simgear/metar/MetarReport.cpp
Normal file
259
simgear/metar/MetarReport.cpp
Normal file
@@ -0,0 +1,259 @@
|
||||
// Metar report implementation class code
|
||||
|
||||
#include "MetarReport.h"
|
||||
#include "Metar.h"
|
||||
|
||||
CMetarReport::CMetarReport(
|
||||
char *s ) :
|
||||
m_DecodedReport( 0 )
|
||||
{
|
||||
m_DecodedReport = new Decoded_METAR;
|
||||
DcdMETAR( s, (Decoded_METAR *)m_DecodedReport );
|
||||
}
|
||||
|
||||
|
||||
CMetarReport::~CMetarReport()
|
||||
{
|
||||
}
|
||||
|
||||
static int DecodeDirChars( char* c )
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
if ( c[0] )
|
||||
{
|
||||
if ( c[0] == 'E' ) r = 90;
|
||||
else if ( c[0] == 'S' ) r = 180;
|
||||
else if ( c[0] == 'W' ) r = 270;
|
||||
|
||||
if ( r == 0 )
|
||||
{
|
||||
if ( c[1] == 'E' ) r = 45;
|
||||
else if ( c[1] == 'W' ) r = 315;
|
||||
}
|
||||
else if ( r = 180 )
|
||||
{
|
||||
if ( c[1] == 'E' ) r = 135;
|
||||
else if ( c[1] == 'W' ) r = 225;
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
char *CMetarReport::StationID()
|
||||
{
|
||||
return ((Decoded_METAR *)m_DecodedReport)->stnid;
|
||||
}
|
||||
|
||||
int CMetarReport::WindDirection()
|
||||
{
|
||||
return ((Decoded_METAR *)m_DecodedReport)->winData.windDir;
|
||||
}
|
||||
|
||||
int CMetarReport::WindSpeed()
|
||||
{
|
||||
return ((Decoded_METAR *)m_DecodedReport)->winData.windSpeed;
|
||||
}
|
||||
|
||||
int CMetarReport::WindGustSpeed()
|
||||
{
|
||||
return ((Decoded_METAR *)m_DecodedReport)->winData.windGust;
|
||||
}
|
||||
|
||||
int CMetarReport::LightningDirection()
|
||||
{
|
||||
return DecodeDirChars( ((Decoded_METAR *)m_DecodedReport)->LTG_DIR );
|
||||
}
|
||||
|
||||
char CMetarReport::CloudLow()
|
||||
{
|
||||
return ((Decoded_METAR *)m_DecodedReport)->CloudLow;
|
||||
}
|
||||
|
||||
char CMetarReport::CloudMedium()
|
||||
{
|
||||
return ((Decoded_METAR *)m_DecodedReport)->CloudMedium;
|
||||
}
|
||||
|
||||
char CMetarReport::CloudHigh()
|
||||
{
|
||||
return ((Decoded_METAR *)m_DecodedReport)->CloudHigh;
|
||||
}
|
||||
|
||||
int CMetarReport::VirgaDirection()
|
||||
{
|
||||
return DecodeDirChars( ((Decoded_METAR *)m_DecodedReport)->VIRGA_DIR );
|
||||
}
|
||||
|
||||
int CMetarReport::TornadicDirection()
|
||||
{
|
||||
return DecodeDirChars( ((Decoded_METAR *)m_DecodedReport)->TornadicDIR );
|
||||
}
|
||||
|
||||
int CMetarReport::TornadicMovementDirection()
|
||||
{
|
||||
return DecodeDirChars( ((Decoded_METAR *)m_DecodedReport)->TornadicMovDir );
|
||||
}
|
||||
|
||||
int CMetarReport::ThunderStormDirection()
|
||||
{
|
||||
return DecodeDirChars( ((Decoded_METAR *)m_DecodedReport)->TS_LOC );
|
||||
}
|
||||
|
||||
int CMetarReport::ThunderStormMovementDirection()
|
||||
{
|
||||
return DecodeDirChars( ((Decoded_METAR *)m_DecodedReport)->TS_MOVMNT );
|
||||
}
|
||||
|
||||
bool CMetarReport::Virga()
|
||||
{
|
||||
return ((Decoded_METAR *)m_DecodedReport)->VIRGA;
|
||||
}
|
||||
|
||||
bool CMetarReport::VolcanicAsh()
|
||||
{
|
||||
return ((Decoded_METAR *)m_DecodedReport)->VOLCASH;
|
||||
}
|
||||
|
||||
bool CMetarReport::Hail()
|
||||
{
|
||||
return ((Decoded_METAR *)m_DecodedReport)->GR;
|
||||
}
|
||||
|
||||
bool CMetarReport::OccationalLightning()
|
||||
{
|
||||
return ((Decoded_METAR *)m_DecodedReport)->OCNL_LTG;
|
||||
}
|
||||
|
||||
bool CMetarReport::FrequentLightning()
|
||||
{
|
||||
return ((Decoded_METAR *)m_DecodedReport)->FRQ_LTG;
|
||||
}
|
||||
|
||||
bool CMetarReport::ContinuousLightning()
|
||||
{
|
||||
return ((Decoded_METAR *)m_DecodedReport)->CNS_LTG;
|
||||
}
|
||||
|
||||
bool CMetarReport::CloudToGroundLightning()
|
||||
{
|
||||
return ((Decoded_METAR *)m_DecodedReport)->CG_LTG;
|
||||
}
|
||||
|
||||
bool CMetarReport::InterCloudLightning()
|
||||
{
|
||||
return ((Decoded_METAR *)m_DecodedReport)->IC_LTG;
|
||||
}
|
||||
|
||||
bool CMetarReport::CloudToCloudLightning()
|
||||
{
|
||||
return ((Decoded_METAR *)m_DecodedReport)->CC_LTG;
|
||||
}
|
||||
|
||||
bool CMetarReport::CloudToAirLightning()
|
||||
{
|
||||
return ((Decoded_METAR *)m_DecodedReport)->CA_LTG;
|
||||
}
|
||||
|
||||
bool CMetarReport::DistantLightning()
|
||||
{
|
||||
return ((Decoded_METAR *)m_DecodedReport)->DSNT_LTG;
|
||||
}
|
||||
|
||||
bool CMetarReport::AirportLightning()
|
||||
{
|
||||
return ((Decoded_METAR *)m_DecodedReport)->AP_LTG;
|
||||
}
|
||||
|
||||
bool CMetarReport::VicinityLightning()
|
||||
{
|
||||
return ((Decoded_METAR *)m_DecodedReport)->VcyStn_LTG;
|
||||
}
|
||||
|
||||
bool CMetarReport::OverheadLightning()
|
||||
{
|
||||
return ((Decoded_METAR *)m_DecodedReport)->OVHD_LTG;
|
||||
}
|
||||
|
||||
int CMetarReport::Temperature()
|
||||
{
|
||||
return ((Decoded_METAR *)m_DecodedReport)->temp;
|
||||
}
|
||||
|
||||
int CMetarReport::DewpointTemperature()
|
||||
{
|
||||
return ((Decoded_METAR *)m_DecodedReport)->dew_pt_temp;
|
||||
}
|
||||
|
||||
int CMetarReport::VerticalVisibility() // Meters
|
||||
{
|
||||
return ((Decoded_METAR *)m_DecodedReport)->VertVsby;
|
||||
}
|
||||
|
||||
int CMetarReport::Ceiling()
|
||||
{
|
||||
return FEET_TO_METER * ((Decoded_METAR *)m_DecodedReport)->Ceiling;
|
||||
}
|
||||
|
||||
int CMetarReport::EstimatedCeiling()
|
||||
{
|
||||
return FEET_TO_METER * ((Decoded_METAR *)m_DecodedReport)->Estimated_Ceiling;
|
||||
}
|
||||
|
||||
int CMetarReport::VariableSkyLayerHeight()
|
||||
{
|
||||
return FEET_TO_METER * ((Decoded_METAR *)m_DecodedReport)->VrbSkyLayerHgt;
|
||||
}
|
||||
|
||||
int CMetarReport::SnowDepthInches()
|
||||
{
|
||||
return ((Decoded_METAR *)m_DecodedReport)->snow_depth;
|
||||
}
|
||||
|
||||
|
||||
std::ostream&
|
||||
operator << ( ostream& out, CMetarReport& p )
|
||||
{
|
||||
return out
|
||||
<< "StationID " << p.StationID()
|
||||
<< " WindDirection " << p.WindDirection()
|
||||
<< " WindSpeed " << p.WindSpeed()
|
||||
<< " WindGustSpeed " << p.WindGustSpeed() << std::endl
|
||||
<< "CloudLow " << p.CloudLow()
|
||||
<< " CloudMedium " << p.CloudMedium()
|
||||
<< " CloudHigh " << p.CloudHigh() << std::endl
|
||||
<< "TornadicDirection " << p.TornadicDirection()
|
||||
<< " TornadicMovementDirection " << p.TornadicMovementDirection() << std::endl
|
||||
<< "ThunderStormDirection " << p.ThunderStormDirection()
|
||||
<< " ThunderStormMovementDirection " << p.ThunderStormMovementDirection() << std::endl
|
||||
<< "Virga " << p.Virga()
|
||||
<< " VirgaDirection " << p.VirgaDirection() << std::endl
|
||||
<< "VolcanicAsh " << p.VolcanicAsh() << std::endl
|
||||
<< "Hail " << p.Hail() << std::endl
|
||||
<< "LightningDirection " << p.LightningDirection()
|
||||
<< " OccationalLightning " << p.OccationalLightning()
|
||||
<< " FrequentLightning " << p.FrequentLightning()
|
||||
<< " ContinuousLightning " << p.ContinuousLightning() << std::endl
|
||||
<< "CloudToGroundLightning " << p.CloudToGroundLightning()
|
||||
<< " InterCloudLightning " << p.InterCloudLightning()
|
||||
<< " CloudToCloudLightning " << p.CloudToCloudLightning()
|
||||
<< " CloudToAirLightning " << p.CloudToAirLightning() << std::endl
|
||||
<< "DistantLightning " << p.DistantLightning()
|
||||
<< " AirportLightning " << p.AirportLightning()
|
||||
<< " VicinityLightning " << p.VicinityLightning()
|
||||
<< " OverheadLightning " << p.OverheadLightning() << std::endl
|
||||
<< "VerticalVisibility " << p.VerticalVisibility() << std::endl // Meters
|
||||
<< "Temperature " << p.Temperature()
|
||||
<< " DewpointTemperature " << p.DewpointTemperature() << std::endl
|
||||
<< "Ceiling " << p.Ceiling()
|
||||
<< " EstimatedCeiling " << p.EstimatedCeiling()
|
||||
<< " VariableSkyLayerHeight " << p.VariableSkyLayerHeight() << std::endl
|
||||
<< "SnowDepthInches " << p.SnowDepthInches() << std::endl
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
void CMetarReport::dump()
|
||||
{
|
||||
prtDMETR( (Decoded_METAR *)m_DecodedReport );
|
||||
}
|
||||
111
simgear/metar/MetarReport.h
Normal file
111
simgear/metar/MetarReport.h
Normal file
@@ -0,0 +1,111 @@
|
||||
// Class encapulating the metar report information
|
||||
//
|
||||
// Individual METAR reports are found in this directory:
|
||||
// ftp://weather.noaa.gov/data/observations/metar/stations
|
||||
//
|
||||
|
||||
#ifndef _MetarReport_
|
||||
#define _MetarReport_
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <Math/point3d.hxx>
|
||||
#include <Math/polar3d.hxx>
|
||||
|
||||
class CMetarReport
|
||||
{
|
||||
// Typedefs, enumerations
|
||||
|
||||
// Attributes
|
||||
private:
|
||||
void *m_DecodedReport;
|
||||
// A void pointer which is cast to the correct type in the cpp file.
|
||||
// I don't want the ugly metar structure and header files dragged into
|
||||
// every report user program file.
|
||||
// Probably should be a smart pointer if copy constructor and assignment
|
||||
// is allowed.
|
||||
|
||||
// Operations
|
||||
|
||||
public:
|
||||
CMetarReport(
|
||||
char *s );
|
||||
// Constructor
|
||||
|
||||
~CMetarReport();
|
||||
// Destructor
|
||||
|
||||
char *StationID();
|
||||
|
||||
// Directions in degrees
|
||||
// Speed in knots
|
||||
// Altitude in meters
|
||||
// Temperature in centigrade
|
||||
|
||||
int WindDirection();
|
||||
int WindSpeed();
|
||||
int WindGustSpeed();
|
||||
|
||||
// Add cloud more cloud info...
|
||||
// Cloud code characters...
|
||||
char CloudLow();
|
||||
char CloudMedium();
|
||||
char CloudHigh();
|
||||
|
||||
bool Virga();
|
||||
int VirgaDirection();
|
||||
|
||||
int TornadicDirection();
|
||||
int TornadicMovementDirection();
|
||||
|
||||
int ThunderStormDirection();
|
||||
int ThunderStormMovementDirection();
|
||||
|
||||
bool VolcanicAsh();
|
||||
bool Hail();
|
||||
|
||||
int LightningDirection();
|
||||
bool OccationalLightning();
|
||||
bool FrequentLightning();
|
||||
bool ContinuousLightning();
|
||||
bool Lightning()
|
||||
{
|
||||
return OccationalLightning() || FrequentLightning() || ContinuousLightning();
|
||||
}
|
||||
|
||||
bool CloudToGroundLightning();
|
||||
bool InterCloudLightning();
|
||||
bool CloudToCloudLightning();
|
||||
bool CloudToAirLightning();
|
||||
|
||||
bool DistantLightning();
|
||||
bool AirportLightning();
|
||||
bool OverheadLightning();
|
||||
bool VicinityLightning();
|
||||
|
||||
int Temperature();
|
||||
int DewpointTemperature();
|
||||
|
||||
int VerticalVisibility();
|
||||
int Ceiling();
|
||||
int EstimatedCeiling();
|
||||
int VariableSkyLayerHeight();
|
||||
|
||||
int SnowDepthInches();
|
||||
|
||||
void dump();
|
||||
|
||||
private:
|
||||
CMetarReport(
|
||||
const CMetarReport &rNewObj );
|
||||
// Copy constructor. Not implemented.
|
||||
|
||||
CMetarReport &operator =(
|
||||
const CMetarReport &rObj );
|
||||
// Assignment operator. Not implemented.
|
||||
};
|
||||
|
||||
std::ostream& operator << ( std::ostream&, CMetarReport& );
|
||||
|
||||
#endif
|
||||
231
simgear/metar/MetarStation.cpp
Normal file
231
simgear/metar/MetarStation.cpp
Normal file
@@ -0,0 +1,231 @@
|
||||
// Metar station implementation code
|
||||
|
||||
#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>
|
||||
#endif
|
||||
#include <Misc/fgpath.hxx>
|
||||
|
||||
|
||||
std::vector< CMetarStation *> METAR_Stations;
|
||||
|
||||
int CMetarStation::initialized( CMetarStation::initialize() );
|
||||
|
||||
std::string CMetarStation::tempName;
|
||||
|
||||
|
||||
double CMetarStation::decodeDMS( char *b )
|
||||
{
|
||||
double r = 0;
|
||||
double m = 0;
|
||||
double s = 0;
|
||||
if ( *b )
|
||||
{
|
||||
// Degrees
|
||||
r = (*b - '0') * 10.0; b++;
|
||||
r += (*b - '0'); b++;
|
||||
if ( *b != '-' )
|
||||
{
|
||||
r *= 10;
|
||||
r += (*b - '0'); b++;
|
||||
}
|
||||
b++;
|
||||
// Minutes
|
||||
m = (*b - '0') * 10.0; b++;
|
||||
m += (*b - '0'); b++;
|
||||
r += m/60.0;
|
||||
if ( *b == '-' )
|
||||
{
|
||||
// Seconds
|
||||
b++;
|
||||
s = (*b - '0') * 10.0; b++;
|
||||
s += (*b - '0'); b++;
|
||||
}
|
||||
r += s/3600.0;
|
||||
// Direction (E W N S)
|
||||
if ( *b == 'W' || *b == 'S' ) r = -r;
|
||||
}
|
||||
return r * DEG_TO_RAD;
|
||||
}
|
||||
|
||||
|
||||
CMetarStation::CMetarStation(
|
||||
char *s )
|
||||
{
|
||||
char *t;
|
||||
t = strchr( s, ';' ); *t = 0; t++;
|
||||
m_ID = s;
|
||||
s = t; t = strchr( s, ';' ); *t = 0; t++;
|
||||
m_number = atoi( s ) * 1000;
|
||||
s = t; t = strchr( s, ';' ); *t = 0; t++;
|
||||
m_number += atoi( s );
|
||||
s = t; t = strchr( s, ';' ); *t = 0; t++;
|
||||
m_name = s;
|
||||
s = t; t = strchr( s, ';' ); *t = 0; t++;
|
||||
m_state = s;
|
||||
s = t; t = strchr( s, ';' ); *t = 0; t++;
|
||||
m_country = s;
|
||||
s = t; t = strchr( s, ';' ); *t = 0; t++;
|
||||
m_region = atoi( s );
|
||||
s = t; t = strchr( s, ';' ); *t = 0; t++;
|
||||
double latitude = decodeDMS( s );
|
||||
s = t; t = strchr( s, ';' ); *t = 0; t++;
|
||||
double longitude = decodeDMS( s );
|
||||
s = t; t = strchr( s, ';' ); *t = 0; t++;
|
||||
double ulatitude = decodeDMS( s );
|
||||
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;
|
||||
s = t; t = strchr( s, ';' ); *t = 0; t++;
|
||||
double ualtitude = atoi( s ) * FEET_TO_METER;
|
||||
Point3D p( longitude, latitude, altitude+EQUATORIAL_RADIUS_M );
|
||||
m_locationPolar = p;
|
||||
m_locationCart = fgPolarToCart3d( p );
|
||||
Point3D up( ulongitude, ulatitude, ualtitude+EQUATORIAL_RADIUS_M );
|
||||
m_upperLocationPolar = up;
|
||||
m_upperLocationCart = fgPolarToCart3d( 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()
|
||||
{
|
||||
// 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" );
|
||||
#else
|
||||
FGPath weatherPath( current_options.get_fg_root() );
|
||||
#endif
|
||||
|
||||
weatherPath.append( "Weather/MetarStations" );
|
||||
// Open the metar station list
|
||||
FILE *f = fopen( weatherPath.c_str(), "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;
|
||||
m = new CMetarStation( buf );
|
||||
//m->dump();
|
||||
METAR_Stations.push_back( m );
|
||||
}
|
||||
|
||||
// Close the list
|
||||
fclose( f );
|
||||
std::cout << METAR_Stations.size() << " Metar stations" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Could not open MetarStations file " << std::endl;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int CMetarStation::sameName( CMetarStation *m )
|
||||
{
|
||||
return m->m_ID == tempName;
|
||||
}
|
||||
|
||||
|
||||
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 )
|
||||
{
|
||||
double dist = s->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;
|
||||
}
|
||||
|
||||
|
||||
void CMetarStation::for_each( void f( CMetarStation *s ) )
|
||||
{
|
||||
std::for_each( METAR_Stations.begin(), METAR_Stations.end(), f );
|
||||
}
|
||||
|
||||
|
||||
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&
|
||||
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;
|
||||
}
|
||||
|
||||
87
simgear/metar/MetarStation.h
Normal file
87
simgear/metar/MetarStation.h
Normal file
@@ -0,0 +1,87 @@
|
||||
// Class encapulating the metar station information
|
||||
//
|
||||
// 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 <vector>
|
||||
#include <Math/point3d.hxx>
|
||||
#include <Math/polar3d.hxx>
|
||||
//using namespace std;
|
||||
|
||||
class CMetarStation
|
||||
{
|
||||
// Attributes
|
||||
private:
|
||||
std::string m_ID;
|
||||
unsigned long m_number;
|
||||
std::string m_name;
|
||||
std::string m_state;
|
||||
std::string m_country;
|
||||
int m_region;
|
||||
Point3D m_locationPolar;
|
||||
Point3D m_upperLocationPolar;
|
||||
Point3D m_locationCart;
|
||||
Point3D m_upperLocationCart;
|
||||
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 );
|
||||
// Constructor
|
||||
|
||||
~CMetarStation()
|
||||
{
|
||||
}
|
||||
// Destructor
|
||||
|
||||
public:
|
||||
std::string &ID() { return m_ID; }
|
||||
unsigned long number() { return m_number; }
|
||||
std::string &name() { return m_name; }
|
||||
std::string &state() { return m_state; }
|
||||
std::string &country() { return m_country; }
|
||||
int region() { return m_region; }
|
||||
Point3D &locationPolar() { return m_locationPolar; }
|
||||
Point3D &upperLocationPolar() { return m_upperLocationPolar; }
|
||||
Point3D &locationCart() { return m_locationCart; }
|
||||
Point3D &upperLocationCart() { return m_upperLocationCart; }
|
||||
char pFlag() { return m_pFlag; }
|
||||
// Get attributes
|
||||
|
||||
friend std::ostream& operator << ( std::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(
|
||||
const CMetarStation &rNewObj );
|
||||
// Copy constructor. Not implemented.
|
||||
|
||||
CMetarStation &operator =(
|
||||
const CMetarStation &rObj );
|
||||
// Assignment operator. Not implemented.
|
||||
|
||||
static int initialize();
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
549
simgear/metar/MetarTest/MetarLibTest.cpp
Normal file
549
simgear/metar/MetarTest/MetarLibTest.cpp
Normal file
@@ -0,0 +1,549 @@
|
||||
// Metar Library test
|
||||
|
||||
#include <iostream>
|
||||
#include "../MetarReport.h"
|
||||
#include "../MetarStation.h"
|
||||
#include <GL/glut.h>
|
||||
|
||||
static char *report[] =
|
||||
{
|
||||
"KAST 221156Z COR 09005KT 7SM -RA OVC026 09/08 A2996 RMK "
|
||||
"AO2 TNO SLP143 P0007 60047 70109 T00890084 10100 20089 55005",
|
||||
|
||||
"KAST COR 221156Z 09005KT 7SM -RA OVC026 09/08 A2996 RMK "
|
||||
"AO2 TNO SLP143 P0007 60047 70109 T00890084 10100 20089 55005",
|
||||
|
||||
"KAST COR 221156Z 09005KT 1/SM -RA OVC026 09/08 A2996 RMK "
|
||||
"AO2 TNO SLP143 P0007 60047 70109 T00890084 10100 20089 55005",
|
||||
|
||||
"KP88 COR 221156 09005KT 1/SM -RA OVC026 09/08 A2996 RMK "
|
||||
"AO2 TNO SLP143 P0007 60047 70109 T00890084 10100 20089 55005",
|
||||
|
||||
"KP88 COR 221156 09005KT 1/SM -RA OVC026 09/08 A2996 RMK "
|
||||
"AO2 TNO SLP143 P0007 6//// 70109 T00890084 10100 20089 55005",
|
||||
|
||||
|
||||
"EPIT 1755 22015G25KT 1 3/4SM R22L/2700FT R16/1200FT "
|
||||
"R34/1000V1600FT R01L/P6000FT R04RR/900FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB 18/16 A2992 "
|
||||
"RMK 58033 6003/ TWELVE 70125 10039 20029 410840112 "
|
||||
"PCPN 0009 WSHFT 1715 PK WND 2032/1725 "
|
||||
"CIG 20V25 WND 12V25 TWR VIS 2 1/2 "
|
||||
"SFC VIS 1 1/2 VIS 1/2V3/4",
|
||||
|
||||
"KFAR 181154Z 10003KT 1/4SM HZ CLR 16/13 A2988 RMK AO2 "
|
||||
"SLP117 56012 10345 20226 T01610133 $",
|
||||
|
||||
"KFAR 181154Z 10003KT 1/SM HZ CLR 16/13 A2988 RMK AO2 "
|
||||
"SLP117 56012 10345 20226 T01610133 $",
|
||||
|
||||
"RKSS 21009KT 1400 RP2000 // ////// 21/20 1006/2972 NOSIG",
|
||||
|
||||
"RKSS 1200 21009KT 1400 RP2000 // ////// 21/20 1006/2972 NOSIG",
|
||||
|
||||
"RKSS 1130Z 23011KT 1100 R14R/P1500N R14L/P1500N BR SCT010 BKN030 "
|
||||
"BKN080 21/21 Q1006 NOSIG",
|
||||
|
||||
"RKSS 1130Z 23011KT 1100 R14R/P1500 R14L/P1500 BR SCT010 BKN030 "
|
||||
"BKN080 21/21 Q1006 NOSIG",
|
||||
|
||||
"KFAR 181154Z 10003KT 4SM HZ CLR 16/13 A2988 RMK AO2 "
|
||||
"SLP117 56012 1//// 2//// T01610133 $",
|
||||
|
||||
"CYYE 061300Z 3500KT 15SM BKN005 OVC040 08/08 A3004 RMK "
|
||||
"SF6SC1 VSBY RDCE DUE LO CLD SLP186",
|
||||
|
||||
"CYYE 061300Z 3500KT 15SM BKN005 OVC040 08/08 A3004 RMK "
|
||||
"SF6SC1 VSBY RDCE DUE10 LO CLD SLP186",
|
||||
|
||||
"CYYE 061300Z 3500KT 15SM BKN005 OVC040 08/08 A3004 RMK "
|
||||
"SF6SC1 VSBY RDCE DUE9 LO CLD SLP186",
|
||||
|
||||
"CYYE 061300Z 3500KT 15SM BKN005 OVC040 08/08 A3004 RMK "
|
||||
"SF6SC1 VSBY RDCE FZDZE10 LO CLD SLP186",
|
||||
|
||||
"CYYE 061300Z 3500KT 15SM BKN005 OVC040 08/08 A3004 RMK "
|
||||
"SF6SC1 VSBY RDCE FZDZE9 LO CLD SLP186",
|
||||
|
||||
"MKJP 1400Z 13011KT 9999 FEW022 30/XX Q1015",
|
||||
"MKJP 1400Z 13011KT 9999 FEW022 M30/XX Q1015",
|
||||
"MKJP 1400Z 13011KT 9999 FEW022 MM/XX Q1015",
|
||||
"MKJP 1400Z 13011KT 9999 FEW022 MM/30 Q1015",
|
||||
"MKJP 1400Z 13011KT 9999 FEW022 MM/M30 Q1015",
|
||||
|
||||
"EGPD 36016G26KT 320V030 9999 FEW015TCU SCT026 BKN045 OVC090 "
|
||||
"SCT120 FEW250 RMK OCNL LTGICCG OHD",
|
||||
|
||||
"EGPD 36016G26KT 320V030 9999 FEW015TCU SCT026 07/01 Q1011 "
|
||||
"RMK TEMPO 8000 -SHRA BKN015 FRQ LTG VC",
|
||||
|
||||
"EGPD 36016G26KT 320V030 9999 FEW015TCU SCT026 07/01 Q1011 "
|
||||
"RMK TEMPO 8000 -SHRA BKN015 LTG DSNT W",
|
||||
|
||||
"METAR KLAX 281156Z AUTO VRB100G135KT 130V210 3 1/2SM "
|
||||
"R15L/0500FT R22L/2700FT R16/1200FT R34/1000V1600FT R01L/P6000FT FC "
|
||||
"+TS BLPY FEW/// SCT000 BKN050 SCT150 OVC250 3/M1 A2991 RMK "
|
||||
"TORNADO B13E45 6 NE MOV E A02 PK WND 18515/45 "
|
||||
"WSHFT 1350 FROPA TWR VIS 1 1/2 SFC VIS 1/4 VIS 1/4V1 1/4 "
|
||||
"VIS 2 1/2 RY11 "
|
||||
"DVR/1000V1600FT "
|
||||
"OCNL LTG VCY STN "
|
||||
"RAB1030E1145 FZDZE56 BLPYE57 CIG 1000V1500 CIG 020 RY11 "
|
||||
"PRESFR PRESRR SLP013 FG FEW/// HZ SCT000 VIS NW 2 1/2 GR 3/4 "
|
||||
"VIRGA SE -XRAFG3 CIGE005 BKN014 V OVC "
|
||||
"FU BKN020 NOSPECI LAST 8/365 SNINCR 2/10 4/178 "
|
||||
"933125 98096 P 0125 60225 70565 "
|
||||
"T00261015 10369 21026 "
|
||||
"404800360 52101 VISNO RY05 CHINO RY27 PNO RVRNO "
|
||||
"PWINO FZRANO TSNO $",
|
||||
|
||||
"KBOS 251356Z 26011KT 10SM CLR 12/02 A2995 RMK AO2 SC VCNTY "
|
||||
"STN SSE-NNW SCT CI ABV SLP141 T01220023",
|
||||
|
||||
"EFHK 36009KT 340V060 CAVOK 12/M02 Q1013 NOSIG",
|
||||
"EGKK 24011KT 210V300 9999 SCT020 BKN045 12/06 Q1007 NOSIG",
|
||||
"EGPD 31018KT 8000 RA FEW013 BKN021 OVC045 06/04 Q0994 NOSIG",
|
||||
"EKCH 16012KT CAVOK 20/07 Q1006 NOSIG",
|
||||
"ESKN 10014KT 9000 BR SCT100 14/04 Q1010",
|
||||
"LOWW 231450Z 14017KT CAVOK 23/07 Q1010 NOSIG",
|
||||
|
||||
"METAR CYCH 171500Z CCA 30017KT 2SM -SN BKN006",
|
||||
|
||||
"METAR CYOW 171500Z CCA 30017KT 2SM -SN BKN006 OVC020 00/M02 "
|
||||
"A2957 RMK S35F4NS1 /S01/ SNW WET SNW MELTG ON GRND CIG 5-7 "
|
||||
"SLP018",
|
||||
|
||||
"KAST 221156Z AUTO 09005KT 7SM -RA OVC026 09/08 A2996 RMK "
|
||||
"AO2 TNO SLP143 P0007 60047 70109 T00890084 10100 20089 55005"
|
||||
" TSB0159E30 TS SE MOV NE",
|
||||
|
||||
"KAST 221156Z AUTO 09005KT 7SM -RA OVC026 09/08 A2996 RMK "
|
||||
"AO2 TNO SLP143 P0007 60047 70109 T00890084 10100 20089 55005"
|
||||
" TSE0159 TS SE",
|
||||
|
||||
"KHVR 1756Z 31007KT 5SM -SN SCT011 BKN024 OVC030 M05/M08 A3056 "
|
||||
"RMK AOA 933004 "
|
||||
"BKN V SCT TNO PCPN 000 $ SLP389 4/015 60002 "
|
||||
"T10501077 11050 21078 51010",
|
||||
|
||||
"SPECI KGFI 041420Z AUTO 18030KT 3 1/2SM RVRNO TS -RA BKN008 OVC060 "
|
||||
"26/22 A2991 RMK A02 RA15TSB20 PRESFR SLP 101 P 0000 T02640218",
|
||||
|
||||
"METAR KCLE 281156Z 170100G135KT 110V180 M1/4SM "
|
||||
"R01L/P6000FT +TSSHRA VCFG "
|
||||
"BKN025 SCT100 OVC200 M26/ A2991 RMK PK WND 18515/45 A02 "
|
||||
"WSHFT 1350 TWR VIS 1 1/2 SFC VIS 1/4 VIS 1/4V1 1/4 "
|
||||
"CIG 1000V1500 PRESFR FRQ LTG CG NW "
|
||||
"RAB1030E1145 FZDZE56 PRESRR SLP135 GS "
|
||||
"T1263 "
|
||||
"VIRGA NW 8/365 4/178 P 0125 60225 7//// 70565 10369 21026 "
|
||||
"404800360 52101 PWINO FZRANO TSNO $",
|
||||
|
||||
"CYQR 161700Z 15015KT 15SM SCT045 SCT090 BKN250 10/03 A2955 "
|
||||
"RMK SC1AC2C11 OB TAKEN H+ 5 DUE AWOS FAILURE SLP027",
|
||||
|
||||
"KPIT 1755Z 22015G25KT 1 3/4SM R22L/2700FT R16/1200FT "
|
||||
"R34/1000V1600FT R01L/P6000FT R04RR/900FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB 18/16 A2992 "
|
||||
"RMK 58033 6003/ TWELVE 70125 10039 20029 410840112 "
|
||||
"PCPN 0009 WSHFT 1715 PK WND 2032/1725 "
|
||||
"CIG 20V25 WND 12V25 TWR VIS 2 1/2 "
|
||||
"SFC VIS 1 1/2 VIS 1V2",
|
||||
|
||||
"SPECI KGFI 041430Z 18045G56KT M1/4SM R15/0200FT FC +TS VV010 20/18 "
|
||||
"A2900 RMK A02A PK WND 18056/28 RAB15E25TSB20 FCB1430 PRESFR "
|
||||
"SLP 701 P 0254 199/182",
|
||||
|
||||
"SPECI KGFI 041430Z 18045G56KT M1/4SM R15/0200FT FC +TS VV010 20/18 "
|
||||
"A2900 RMK A02A PK WND 18056/28 RAB15E25TSB20 FCB1430 PRESFR "
|
||||
"SLP701 P0254 199/182",
|
||||
|
||||
"KHLN 281156Z AUTO 27005KT 10SM OVC023 07/05 A3011 RMK AOA OVC V "
|
||||
"BKN $ SLP202 60000 70001 T00670050 10122 20061 53003",
|
||||
|
||||
"KPHX 281156Z 12004KT 10SM CLR 15/05 A2996 RMK AOA SLP135 T01500050 "
|
||||
"10250 20150 53006",
|
||||
"KFCA 281156Z 30003KT 10SM CLR 06/02 A3009 RMK AO TNO $ SLP191 "
|
||||
"T00610023 10167 20056 53003",
|
||||
"KAST 281156Z 00000KT 10SM BKN095 09/08 A2997 RMK AOA SLP150 "
|
||||
"T00940084 10161 20094 52005 ",
|
||||
"KHVR 281156Z 03003KT 10SM OVC020 09/07 A3010 RMK AO TNO ZRNO "
|
||||
"$ SLP194 T00940073 10156 20089 51005",
|
||||
"KGGW 281156Z 35006KT 5SM BR OVC010 10/09 A3003 RMK AOA $ SLP177 "
|
||||
"70003 T01000095 10156 20110 53008",
|
||||
"KELY 1153Z AUTO 14004KT 10SM SCT075 01/M01 A3011 RMK AOA TNO ZRNO "
|
||||
"SLP171 70001 T00061011 10139 21006 51005",
|
||||
"KFLG 281156Z 29006KT 10SM CLR 04/M01 A3012 RMK AO TNO SLP147 "
|
||||
"T00391011 21006 51004",
|
||||
"KGTF 281156Z 27005KT 7SM BKN080 04/04 A3010 RMK AOA SLP205 "
|
||||
"T00440045 10117 20039 51006",
|
||||
|
||||
"K13A 1918Z 20011KT 26/M06 RMK AO PKWND 020/RNO 644V264 T02611061",
|
||||
|
||||
"KP88 1919Z 09001KT 14/03 RMK AO / PKWND 002/RNO 158 Z T01440034",
|
||||
|
||||
"K40B 1924Z 29004KT 15/M07 RMK AO PKWND 011/RM MV263 T01501072",
|
||||
|
||||
"KGGW 1756Z 33018KT 10SM OVC015 M03/M06 A3041 RMK AOA SLP338 "
|
||||
"4/007 60002 T10281055 11028 21072 51009",
|
||||
"KPHX 1756Z 130004KT 10SM CLR 18/M03 A3001 RMK AOA SLP154 "
|
||||
"T01781033 10178 20067 58007",
|
||||
"KFCA 1756Z 29005KT 10SM CLR 05/M11 A3049 RMK AOA TNO SLP352 "
|
||||
"T00501111 10050 21044 50004",
|
||||
"KAST 1756Z 01006KT 10SM CLR 11/04 A3047 RMK AOA SLP316 "
|
||||
"T01110045 10111 20000 50002",
|
||||
"KELY 1753Z 34010KT 10SM CLR 01/M07 A3022 RMK AOA TNO ZRNO "
|
||||
"SLP240 T00111066 10011 21078 58007",
|
||||
"KFLG 1756Z 07006KT 10SM CLR 06/M12 A3009 RMK AO TNO ZRNO "
|
||||
"SLP178 T00561122 10061 21100 58005",
|
||||
"KGTF 1756Z 35010KT 1/2SM -SN FG VV09 M06/M08 A3051 RMK AOA "
|
||||
"933004 SFC VSBY 3/4 "
|
||||
"PCPN M SLP393 60010 T10611077 11044 21067 53013",
|
||||
"KHLN 1756Z 35012KT 10SM SCT032 OVC060 M02/M09 A3048 RMK AOA "
|
||||
"SLP369 60000 T10171094 11017 21061 53006",
|
||||
"KAST 1756Z 01006KT 10SM CLR 11/04 A3047 RMK AOA SLP316 61104 "
|
||||
"71235 T01110045 10111 20000 401720056 58002",
|
||||
"METAR KLAX 04281156Z AUTO VRB100G135KT 130V210 3 1/2SM "
|
||||
"R15L/0500FT R22L/2700FT R16/1200FT R34/1000V1600FT R01L/P6000FT FC "
|
||||
"+TS BLPY FEW000 BKN050 SCT150 OVC250 3/M1 A2991 RMK "
|
||||
"TORNADO B13 DSNT NE A02 PK WND 18515/45 "
|
||||
"WSHFT 1350 FROPA TWR VIS 1 1/2 SFC VIS 1/4 VIS 1/4V1 1/4 "
|
||||
"VIS 2 1/2 RY11 OCNL LTG VCY STN "
|
||||
"RAB1030E1145 FZDZE56 BLPYE57 CIG 1000V1500 CIG 020 RY11 "
|
||||
"PRESFR PRESRR SLP013 FG FEW000 VIS NW2 1/2 GR 3/4 "
|
||||
"VIRGA SE -XRAFG3 CIGE005 BKN014 V OVC "
|
||||
"FU BKN020 NOSPECI LAST 8/365 SNINCR 2/10 4/178 "
|
||||
"933125 98096 P 0125 60225 70565 "
|
||||
"T00261015 10369 21026 "
|
||||
"404800360 52101 PWINO FZRANO TSNO $",
|
||||
|
||||
"METAR KGFI 041356Z AUTO 17012KT 130V210 3 1/2SM R15L/0500FT -RA "
|
||||
"SCT050 OVC110 26/18 A2991 RMK FUNNEL CLOUDS A02 RAB30 "
|
||||
"SLP 101 GR M1/4 VIRGA SCT V BKN P 0010 T02640178",
|
||||
|
||||
"METAR KGFI 041356Z AUTO 05008KT 10SM R15L/P6000FT CLR A2991 "
|
||||
"RMK WATERSPOUTS VCY STN NW A02 SLP 101 10288 20243 52021 $ ",
|
||||
|
||||
"SPECI KGFI 041430Z 18045G56KT M1/4SM R15/0200FT FC +TS VV010 20/18 "
|
||||
"A2900 RMK A02A PK WND 18056/28 OCNL LTG AP "
|
||||
"RAB15E25TSB20 FCB1430 PRESFR "
|
||||
"SLP 701 P 0254 T01990182",
|
||||
|
||||
"KABE 281900Z NIL",
|
||||
|
||||
"METAR KPIT NIL",
|
||||
|
||||
"METAR KCLE 04281156Z 170100G135KT 110V180 M1/4SM "
|
||||
"R01L/P6000FT +TSSHRA VCFG "
|
||||
"BKN025 SCT100 OVC200 M26/ A2991 RMK PK WND 18515/45 A02 "
|
||||
"WSHFT 1350 TWR VIS 1 1/2 SFC VIS 1/4 VIS 1/4V1 1/4 "
|
||||
"CIG 1000V1500 PRESFR FRQ LTG CG NW "
|
||||
"RAB1030E1145 FZDZE56 PRESRR SLP135 GS "
|
||||
"T1263 "
|
||||
"VIRGA NW 8/365 4/178 P 0125 60225 7//// 70565 10369 21026 "
|
||||
"404800360 52101 PWINO FZRANO TSNO $",
|
||||
|
||||
"METAR KPHL 040256Z AUTO 170100G135KT 130V210 1/2SM "
|
||||
"R15L/0500FT R22L/2700FT R16/1200FT R34/1000V1600FT R01L/P6000FT "
|
||||
"FC +TS BKN050 SCT150 OVC250 M26/ A2991 RMK A02 PK WND 185150/1345 "
|
||||
"WSHFT 1350 TWR VIS 1 1/2 SFC VIS 1/4 VIS 1/4V1 1/4 LTG DSNT "
|
||||
"RAB1030E1145 FZDZE56 CIG 1000V1500 PRESFR PRESRR SLP037 GR 2 3/4 "
|
||||
"VIRGA E 8/365 4/178 P 0125 70565 21026 T0263 10369 60225 "
|
||||
"404800360 52101 PWINO FZRANO TSNO $",
|
||||
|
||||
"SPECI KGFI 041420Z AUTO 18030KT 2 1/2SM RVRNO TS -RA BKN008 "
|
||||
"OVC060 25/22 A2991 RMK A02 LTG DSNT W "
|
||||
"RAB15TSB20 PRESFR SLP101 P 0000 "
|
||||
"254/218",
|
||||
|
||||
"METAR KGFI 041356Z AUTO 170100G135KT 130V210 3 1/2SM "
|
||||
"R15L/0500FT R22L/2700FT R16/1200FT R34/1000V1600FT R01L/P6000FT "
|
||||
"FC +TS BKN050 SCT150 OVC250 M26/ A2991 RMK A02 PK WND 185150/1345 "
|
||||
"WSHFT 1350 TWR VIS 1 1/2 SFC VIS 1/4 VIS 1/4V1 1/4 "
|
||||
"RAB1030E1145 FZDZE56 CIG 1000V1500 PRESFR PRESRR SLP997 GR M1/4 "
|
||||
"VIRGA SE 8/365 4/178 P 0125 6//// 60225 70565 T0263 10369 21026 "
|
||||
"404800360 52101 PWINO FZRANO TSNO $",
|
||||
|
||||
"METAR KGFI 041356Z AUTO 170100G135KT 130V210 3 1/2SM "
|
||||
"R15L/0500FT R22L/2700FT R16/1200FT R34/1000V1600FT R01L/P6000FT "
|
||||
"FC +TS BKN050 SCT150 OVC250 M26/ A2991 RMK A02 PK WND 185150/1345 "
|
||||
"WSHFT 1350 TWR VIS 1 1/2 SFC VIS 1/4 VIS 1/4V1 1/4 "
|
||||
"RAB1030E1145 FZDZE56 CIG 1000V1500 PRESFR PRESRR SLP997 GR 25 "
|
||||
"VIRGA 35 8/365 4/178 P 0125 6//// 60225 70565 T0263 10369 21026 "
|
||||
"VIRGA 35 8/365 4/178 P 0125 21026 70565 10369 60225 T0263 21026 "
|
||||
"404800360 52101 PWINO FZRANO TSNO $",
|
||||
|
||||
"METAR KGFI 041356Z AUTO 170100G135KT 130V210 3 1/2SM "
|
||||
"R15L/0500FT R22L/2700FT R16/1200FT R34/1000V1600FT R01L/P6000FT "
|
||||
"FC +TS BKN050 SCT150 OVC250 3/M1 A2991 RMK A02 PK WND 18515/45 "
|
||||
"WSHFT 1350 TWR VIS 1 1/2 SFC VIS 1/4 VIS 1/4V1 1/4 "
|
||||
"RAB1030E1145 FZDZE56 CIG 1000V1500 PRESFR PRESRR SLP997 GR 25 "
|
||||
"VIRGA 35 8/365 4/178 P 0125 60225 70565 T00261015 10369 21026 "
|
||||
"404800360 52101 PWINO FZRANO TSNO $",
|
||||
|
||||
"METAR KGFI 041356Z AUTO 170100G135KT 130V210 3 1/2SM "
|
||||
"R15L/0500FT R22L/2700FT R16/1200FT R34/1000V1600FT R01L/P6000FT "
|
||||
"FC +TS BKN050 SCT150 OVC250 3/M1 A2991 RMK A02 PK WND 185150/1345 "
|
||||
"WSHFT 1350 TWR VIS 1 1/2 SFC VIS 1/4 VIS 1/4V1 1/4 "
|
||||
"RAB1030E1145 FZDZE56 CIG 1000V1500 PRESFR PRESRR SLP997 GR 25 "
|
||||
"VIRGA 35 8/365 4/178 P 0125 60225 70565 T00261015 10369 21026 "
|
||||
"404800360 52101 PWINO FZRANO TSNO",
|
||||
|
||||
"METAR KGFI 041356Z AUTO 05008KT 10SM R15L/P6000FT CLR A2991 RMK "
|
||||
"A02 SLP 101 10288 20243 52021",
|
||||
"SPECI DGFI 041430Z 18045G56KT M1/4SM R15/0200FT FC +TS VV010 20/18 "
|
||||
"M20/M18 A2900 RMK A02A PK WND 18056/28 RAB15E25TSB20 FCB1430 PRESFR "
|
||||
"SLP 701 P 0254 M199/M182",
|
||||
|
||||
"SPECI DGFI 041430Z 18045G56KT M1/4SM R15/0200FT FC +TS VV010 20/18 "
|
||||
"M20/M18 A2900 RMK A02A PK WND 18056/28 RAB15E25TSB20 FCB1430 PRESFR "
|
||||
"SLP 701 P 0254 M199/182",
|
||||
|
||||
"SPECI DGFI 041430Z 18045G56KT M1/4SM R15/0200FT FC +TS VV010 20/18 "
|
||||
"M20/M18 A2900 RMK A02A PK WND 18056/28 RAB15E25TSB20 FCB1430 PRESFR "
|
||||
"SLP 701 P 0254 199/M182",
|
||||
|
||||
"METAR APIT 171755Z AUTO 22015G25KT 1 3/4SM R22L/2700FT R16/1200FT "
|
||||
"R34/1000V1600FT R01L/P6000FT R04RR/900FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB 18/16 A2992 "
|
||||
"RMK 4/369 58033 6003/ TWELVE 70125 10039 20029 410840112 "
|
||||
"PCPN 0009 8/563 WSHFT 1715 PK WND 2032/1725 "
|
||||
"CIG 20V25 WND 12V25 TWR VIS 2 1/2 "
|
||||
"SFC VIS 1 1/2 VIS 1 1/2V2 SLP875 SGB1213E1225",
|
||||
|
||||
"NZWN 1700Z 35030G49KT 320V030 20KM 02 5SC021 7SC046 12/08 "
|
||||
" Q0994.2 TEMPO 6000 RA 5ST012 2CB015 RMK SLP056 "
|
||||
"RAE0123",
|
||||
|
||||
"SPECI APIT 171755Z 22015G25KT 1 3/4SM R22L/2700FT R16/1200FT "
|
||||
"R34/1000V1600FT R01L/P6000FT R04RR/900FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB 18/16 A2992 "
|
||||
"RMK 58033 6003/ TWELVE 70125 8/321 10039 20029 410840112 "
|
||||
"PCPN 0009 WSHFT 1715 PK WND 2032/1725 "
|
||||
"CIG 20V25 WND 12V25 TWR VIS 2 1/2 "
|
||||
"SFC VIS 1 1/2 VIS 1 SLP875 FGB1713",
|
||||
|
||||
"APIT 1755Z 22015G25KT 1 3/4SM R22L/2700FT R16/1200FT "
|
||||
"R34/1000V1600FT R01L/P6000FT R04RR/900FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB 18/16 A2992 "
|
||||
"RMK 58033 6003/ TWELVE 70125 10039 20029 410840112 "
|
||||
"PCPN 0009 WSHFT 1715 PK WND 2032/1725 "
|
||||
"CIG 20V25 WND 12V25 TWR VIS 2 1/2 "
|
||||
"SFC VIS 1 1/2 VIS 1V2 SLP875",
|
||||
|
||||
"APIT 1755Z 22015G25KT 1 3/4SM R22L/2700FT R16/1200FT "
|
||||
"R34/1000V1600FT R01L/P6000FT R04RR/900FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB 18/16 A2992 "
|
||||
"RMK 58033 6003/ TWELVE 70125 10039 20029 410840112 "
|
||||
"PCPN 0009 WSHFT 1715 PK WND 2032/1725 "
|
||||
"CIG 20V25 WND 12V25 TWR VIS 2 1/2 "
|
||||
"SFC VIS 1 1/2 VIS 1 1/2V2 1/2 SLP875",
|
||||
|
||||
"APIT 1755Z 22015G25KT 1 3/4SM R22L/2700FT R16/1200FT "
|
||||
"R34/1000V1600FT R01L/P6000FT R04RR/900FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB 18/16 A2992 "
|
||||
"RMK 58033 6003/ TWELVE 70125 10039 20029 410840112 "
|
||||
"PCPN 0009 WSHFT 1715 PK WND 2032/1725 "
|
||||
"CIG 20V25 WND 12V25 TWR VIS 2 1/2 "
|
||||
"SFC VIS 1 1/2 VIS 1V2 1/2 SLP875",
|
||||
|
||||
"EGPF 1720Z 00000KT 9999 -SHRA STC014 SCT020CB BNK024 12/09 "
|
||||
"Q1003 NOSIG",
|
||||
|
||||
"NZAA 1700Z 03010KT 30KM 03 5CU022 7SC035 11/07 Q1006.5 NOSIG",
|
||||
"NZWN 1700Z 35030G49KT 320V030 20KM 02 5SC021 7SC046 12/08 "
|
||||
" Q0994.2 TEMPO 6000 RA 5ST012 2CB015 RMK KAUKAU 30050KT",
|
||||
"DGAA 1800Z 22012KT 9999 SCT009 BKN120 25/21 Q1015",
|
||||
"DAAT 1830Z 30010KT CAVOK 29/06 Q1019",
|
||||
|
||||
"GQPP 1800Z 34023KT 3000 DRSA SKC 24/20 Q1011 NSG",
|
||||
"DAAG 1830Z 06006KT 9999 SCT020 25/22 Q1015",
|
||||
"DABB 1830Z 04010KT 9999 SCT030TCU SCT033CB 27/18 Q1017",
|
||||
"DABC 1830Z 00000KT 9999 SCT026TCU SCT036CB 22/18 Q1020 RETS",
|
||||
|
||||
"NZAA 1700Z 03010KT 30KM 03 5CU022 7SC035 11/07 Q1006.5 NOSIG",
|
||||
"NZWN 1700Z 35030G49KT 320V030 20KM 02 5SC021 7SC046 12/08 "
|
||||
" Q0994.2 TEMPO 6000 RA 5ST012 2CB015 RMK K",
|
||||
"NZWN 1700Z 35030G49KT 320V030 20KM 02 5SC021 7SC046 12/08 "
|
||||
" Q0994.2 TEMPO 6000 RA 5ST012 2CB015 RMK KAUKAU 30050KT",
|
||||
"DGAA 1800Z 22012KT 9999 SCT009 BKN120 25/21 Q1015",
|
||||
|
||||
"GFLL 1900Z NIL",
|
||||
|
||||
"GOOY 1800Z 03006G17KT 340V080 6000 TSRA BKN016 BKN030CB "
|
||||
"BKN133 26/23 Q1013 NOSIG",
|
||||
|
||||
"GCXO 1930Z 32018KT 8000 SCT003 SCT007 18/16 Q1019",
|
||||
|
||||
"APIT 1755Z 22015G25KT 1 3/4SM R22L/2700FT R16/1200FT "
|
||||
"R34/1000V1600FT R01L/P6000FT R04RR/900FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB 18/16 A2992 "
|
||||
"RMK 58033 6003/ TWELVE 70125 10039 20029 410840112 "
|
||||
"PCPN 0009 WSHFT 1715 PK WND 2032/1725 "
|
||||
"CIG 20V25 WND 12V25 TWR VIS 2 1/2 "
|
||||
"SFC VIS 1 1/2 VIS 1 1/2V2",
|
||||
|
||||
"BPIT 1755Z 22015G25KT 1 3/4SM R22L/2700FT R16/1200FT "
|
||||
"R34/1000V1600FT R01L/P6000FT R04RR/900FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB 18/16 A2992 "
|
||||
"RMK 58033 6003/ TWELVE 70125 10039 20029 410840112 "
|
||||
"PCPN 0009 WSHFT 1715 PK WND 2032/1725 "
|
||||
"CIG 20V25 WND 12V25 TWR VIS 2 1/2 "
|
||||
"SFC VIS 1 1/2 VIS 1V2",
|
||||
|
||||
"CPIT 1755Z 22015G25KT 1 3/4SM R22L/2700FT R16/1200FT "
|
||||
"R34/1000V1600FT R01L/P6000FT R04RR/900FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB 18/16 A2992 "
|
||||
"RMK 58033 6003/ TWELVE 70125 10039 20029 410840112 "
|
||||
"PCPN 0009 WSHFT 1715 PK WND 2032/1725 "
|
||||
"CIG 20V25 WND 12V25 TWR VIS 2 1/2 "
|
||||
"SFC VIS 1 1/2 VIS 1V2 1/2",
|
||||
|
||||
"DPIT 1755Z 22015G25KT 1 3/4SM R22L/2700FT R16/1200FT "
|
||||
"R34/1000V1600FT R01L/P6000FT R04RR/900FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB 18/16 A2992 "
|
||||
"RMK 58033 6003/ TWELVE 70125 10039 20029 410840112 "
|
||||
"PCPN 0009 WSHFT 1715 PK WND 2032/1725 "
|
||||
"CIG 20V25 WND 12V25 TWR VIS 2 1/2 "
|
||||
"SFC VIS 1 1/2 VIS 1 1/2V2 1/2",
|
||||
|
||||
"FPIT 1755Z 22015G25KT 1 3/4SM R22L/2700FT R16/1200FT "
|
||||
"R34/1000V1600FT R01L/P6000FT R04RR/900FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB 18/16 A2992 "
|
||||
"RMK 58033 6003/ TWELVE 70125 10039 20029 410840112 "
|
||||
"PCPN 0009 WSHFT 1715 PK WND 2032/1725 "
|
||||
"CIG 20V25 WND 12V25 TWR VIS 2 1/2 "
|
||||
"SFC VIS 1 1/2 VIS 3/4V2 1/2",
|
||||
|
||||
"GPIT 1755Z 22015G25KT 1 3/4SM R22L/2700FT R16/1200FT "
|
||||
"R34/1000V1600FT R01L/P6000FT R04RR/900FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB 18/16 A2992 "
|
||||
"RMK 58033 6003/ TWELVE 70125 10039 20029 410840112 "
|
||||
"PCPN 0009 WSHFT 1715 PK WND 2032/1725 "
|
||||
"CIG 20V25 WND 12V25 TWR VIS 2 1/2 "
|
||||
"SFC VIS 1 1/2 VIS 3/4V3",
|
||||
|
||||
"KPIT 1935Z 22015G25KT 1 3/4SM R22L/2700FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB M18/M16 A2992",
|
||||
|
||||
"KPIT 1935Z 22015G25KT 1 3/4SM R22L/2700FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB M18/16 A2992",
|
||||
|
||||
"KPIT 1935Z 22015G25KT 1 3/4SM R22L/2700FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB 18/M16 A2992",
|
||||
|
||||
"KPIT 1935Z 22015G25KT 1 3/4SM R22L/2700FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB MM/M16 A2992",
|
||||
|
||||
"KPIT 1935Z 22015G25KT 1 3/4SM R22L/2700FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB MM/16 A2992",
|
||||
|
||||
"KPIT 1935Z 22015G25KT 1 3/4SM R22L/2700FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB M18/MM A2992",
|
||||
|
||||
"KPIT 1935Z 22015G25KT 1 3/4SM R22L/2700FT "
|
||||
"TSRA -DZ FG +SNPE SCT005 BKN010 OVC250CB 18/MM A2992",
|
||||
|
||||
NULL};
|
||||
|
||||
|
||||
void dispMetarStation( CMetarStation *s )
|
||||
{
|
||||
glPointSize( 2.0 );
|
||||
glColor3d(1.0,1.0,0.0);
|
||||
glVertex3d( s->locationCart().x()/1000.0, s->locationCart().y()/1000.0, s->locationCart().z()/1000.0 );
|
||||
}
|
||||
|
||||
static int ii = 0;
|
||||
|
||||
void
|
||||
display(void)
|
||||
{
|
||||
glPushMatrix();
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glRotatef((ii%360), 1.0, 0.0, 0.0);
|
||||
glRotatef((ii%360), 0.0, 1.0, 0.0);
|
||||
glRotatef((ii%360), 0.0, 0.0, 1.0);
|
||||
glBegin( GL_POINTS );
|
||||
CMetarStation::for_each( dispMetarStation );
|
||||
glEnd();
|
||||
glColor3d(0.0, 0.0, 1.0);
|
||||
glutWireSphere(EARTH_RAD,32,16);
|
||||
glutSwapBuffers();
|
||||
ii++;
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
idle(void)
|
||||
{
|
||||
// std::cout << "Idle" << std::endl;
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
init(void)
|
||||
{
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
gluPerspective( 50.0, 1.0, 1.0, 40000.0);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
gluLookAt(0.0, -19000.0, 0.0,
|
||||
0.0, 0.0, 0.0,
|
||||
0.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
|
||||
void testMetarStation(int argc,
|
||||
char **argv )
|
||||
{
|
||||
std::cout << "Display all Metar Stations" << std::endl;
|
||||
glutInit(&argc, argv);
|
||||
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
|
||||
glutCreateWindow("Metar Stations");
|
||||
glutDisplayFunc(display);
|
||||
glutIdleFunc(idle);
|
||||
init();
|
||||
glutMainLoop();
|
||||
}
|
||||
|
||||
void testMetarReport()
|
||||
{
|
||||
std::cout << "Decode some Metar reports" << std::endl;
|
||||
int i = 0;
|
||||
while ( report[i] )
|
||||
{
|
||||
std::cout << i << ": " << report[i] << std::endl;
|
||||
|
||||
CMetarReport dr( report[i] );
|
||||
|
||||
//dr.dump();
|
||||
std::cout << dr << std::endl;
|
||||
|
||||
CMetarStation *ms = CMetarStation::find( dr.StationID() );
|
||||
if ( ms )
|
||||
{
|
||||
std::cout << *ms << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "No corresponding METAR station found" << std::endl;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(
|
||||
int argc,
|
||||
char **argv )
|
||||
{
|
||||
std::cout << "Metar subsystem test" << std::endl;
|
||||
|
||||
testMetarReport();
|
||||
testMetarStation( argc, argv );
|
||||
return 0;
|
||||
}
|
||||
100
simgear/metar/MetarTest/MetarLibTest.dsp
Normal file
100
simgear/metar/MetarTest/MetarLibTest.dsp
Normal file
@@ -0,0 +1,100 @@
|
||||
# Microsoft Developer Studio Project File - Name="MetarLibTest" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||
|
||||
CFG=MetarLibTest - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "MetarLibTest.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "MetarLibTest.mak" CFG="MetarLibTest - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "MetarLibTest - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE "MetarLibTest - Win32 Debug" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "MetarLibTest - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /Zi /O2 /I "..\..\..\lib" /I "..\lib" /I "..\..\lib" /I "..\..\..\..\lib" /I ".." /I "..\.." /I "..\..\.." /I "..\..\..\.." /I "..\include" /I "..\..\include" /I "..\..\..\include" /I "..\..\..\..\include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
|
||||
!ELSEIF "$(CFG)" == "MetarLibTest - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /GX /Zi /Od /I "..\..\..\lib" /I "..\lib" /I "..\..\lib" /I "..\..\..\..\lib" /I ".." /I "..\.." /I "..\..\.." /I "..\..\..\.." /I "..\include" /I "..\..\include" /I "..\..\..\include" /I "..\..\..\..\include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "MetarLibTest - Win32 Release"
|
||||
# Name "MetarLibTest - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\MetarLibTest.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
95
simgear/metar/MetarTest/MetarTest.dsw
Normal file
95
simgear/metar/MetarTest/MetarTest.dsw
Normal file
@@ -0,0 +1,95 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "LibMisc"=..\..\..\..\Win32\Workspace\LibMisc\LibMisc.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "Metar"=..\Metar.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "MetarLibTest"=.\MetarLibTest.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Metar
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name MetarLib
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name glut
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name LibMisc
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "MetarTest"=.\MetarTest.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name Metar
|
||||
End Project Dependency
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name MetarLib
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "glut"=..\..\..\..\..\glut\glut.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
590
simgear/metar/Prtdmetr.cpp
Normal file
590
simgear/metar/Prtdmetr.cpp
Normal file
@@ -0,0 +1,590 @@
|
||||
#include "Local.h" /* standard header file */
|
||||
#include "Metar.h"
|
||||
#pragma page(1)
|
||||
#pragma subtitle("subtitle - description ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: prtDMETR */
|
||||
/* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
|
||||
/* Date: 15 Sep 1994 */
|
||||
/* Programmer: CARL MCCALLA */
|
||||
/* Language: C/370 */
|
||||
/* */
|
||||
/* Abstract: prtDMETR prints, in order of the ASOS METAR */
|
||||
/* format, all non-initialized members of the structure */
|
||||
/* addressed by the Decoded_METAR pointer. */
|
||||
/* */
|
||||
/* External Functions Called: */
|
||||
/* None. */
|
||||
/* */
|
||||
/* Input: Mptr - ptr to a decoded_METAR structure. */
|
||||
/* */
|
||||
/* Output: NONE */
|
||||
/* */
|
||||
/* Modification History: */
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
void prtDMETR( Decoded_METAR *Mptr )
|
||||
{
|
||||
|
||||
/***************************/
|
||||
/* DECLARE LOCAL VARIABLES */
|
||||
/***************************/
|
||||
|
||||
int i;
|
||||
|
||||
/*************************/
|
||||
/* START BODY OF ROUTINE */
|
||||
/*************************/
|
||||
|
||||
printf("\n\n\n/*******************************************/\n");
|
||||
printf("/* THE DECODED METAR REPORT FOLLOWS */\n");
|
||||
printf("/*******************************************/\n\n");
|
||||
|
||||
if( Mptr->codeName[ 0 ] != '\0' )
|
||||
printf("REPORT CODE NAME : %s\n",Mptr->codeName);
|
||||
|
||||
if( Mptr->stnid[ 0 ] != '\0' )
|
||||
printf("STATION ID : %s\n",Mptr->stnid);
|
||||
|
||||
if( Mptr->ob_date != MAXINT )
|
||||
printf("OBSERVATION DAY : %d\n",Mptr->ob_date);
|
||||
|
||||
if( Mptr->ob_hour != MAXINT )
|
||||
printf("OBSERVATION HOUR : %d\n",Mptr->ob_hour);
|
||||
|
||||
if( Mptr->ob_minute != MAXINT )
|
||||
printf("OBSERVATION MINUTE : %d\n",Mptr->ob_minute);
|
||||
|
||||
if( Mptr->NIL_rpt )
|
||||
printf("NIL REPORT : TRUE\n");
|
||||
|
||||
if( Mptr->AUTO )
|
||||
printf("AUTO REPORT : TRUE\n");
|
||||
|
||||
if( Mptr->COR )
|
||||
printf("CORRECTED REPORT : TRUE\n");
|
||||
|
||||
if( Mptr->winData.windVRB )
|
||||
printf("WIND DIRECTION VRB : TRUE\n");
|
||||
|
||||
if( Mptr->winData.windDir != MAXINT )
|
||||
printf("WIND DIRECTION : %d\n",Mptr->winData.windDir);
|
||||
|
||||
if( Mptr->winData.windSpeed != MAXINT )
|
||||
printf("WIND SPEED : %d\n",Mptr->winData.windSpeed);
|
||||
|
||||
if( Mptr->winData.windGust != MAXINT )
|
||||
printf("WIND GUST : %d\n",Mptr->winData.windGust);
|
||||
|
||||
if( Mptr->winData.windUnits[ 0 ] != '\0' )
|
||||
printf("WIND UNITS : %s\n",Mptr->winData.windUnits);
|
||||
|
||||
if( Mptr->minWnDir != MAXINT )
|
||||
printf("MIN WIND DIRECTION : %d\n",Mptr->minWnDir);
|
||||
|
||||
if( Mptr->maxWnDir != MAXINT )
|
||||
printf("MAX WIND DIRECTION : %d\n",Mptr->maxWnDir);
|
||||
|
||||
if( Mptr->prevail_vsbyM != (float) MAXINT )
|
||||
printf("PREVAIL VSBY (M) : %f\n",Mptr->prevail_vsbyM);
|
||||
|
||||
if( Mptr->prevail_vsbyKM != (float) MAXINT )
|
||||
printf("PREVAIL VSBY (KM) : %f\n",Mptr->prevail_vsbyKM);
|
||||
|
||||
if( Mptr->prevail_vsbySM != (float) MAXINT )
|
||||
printf("PREVAIL VSBY (SM) : %.3f\n",Mptr->prevail_vsbySM);
|
||||
|
||||
if( Mptr->charPrevailVsby[0] != '\0' )
|
||||
printf("PREVAIL VSBY (CHAR) : %s\n",Mptr->charPrevailVsby);
|
||||
|
||||
if( Mptr->vsby_Dir[ 0 ] != '\0' )
|
||||
printf("VISIBILITY DIRECTION: %s\n",Mptr->vsby_Dir);
|
||||
|
||||
if( Mptr->RVRNO )
|
||||
printf("RVRNO : TRUE\n");
|
||||
|
||||
for ( i = 0; i < 12; i++ )
|
||||
{
|
||||
if( Mptr->RRVR[i].runway_designator[0] != '\0' )
|
||||
printf("RUNWAY DESIGNATOR : %s\n",
|
||||
Mptr->RRVR[i].runway_designator);
|
||||
|
||||
if( Mptr->RRVR[i].visRange != MAXINT )
|
||||
printf("R_WAY VIS RANGE (FT): %d\n",
|
||||
Mptr->RRVR[i].visRange);
|
||||
|
||||
if( Mptr->RRVR[i].vrbl_visRange )
|
||||
printf("VRBL VISUAL RANGE : TRUE\n");
|
||||
|
||||
if( Mptr->RRVR[i].below_min_RVR )
|
||||
printf("BELOW MIN RVR : TRUE\n");
|
||||
|
||||
if( Mptr->RRVR[i].above_max_RVR )
|
||||
printf("ABOVE MAX RVR : TRUE\n");
|
||||
|
||||
if( Mptr->RRVR[i].Max_visRange != MAXINT )
|
||||
printf("MX R_WAY VISRNG (FT): %d\n",
|
||||
Mptr->RRVR[i].Max_visRange);
|
||||
|
||||
if( Mptr->RRVR[i].Min_visRange != MAXINT )
|
||||
printf("MN R_WAY VISRNG (FT): %d\n",
|
||||
Mptr->RRVR[i].Min_visRange);
|
||||
|
||||
}
|
||||
|
||||
|
||||
if( Mptr->DVR.visRange != MAXINT )
|
||||
printf("DISPATCH VIS RANGE : %d\n",
|
||||
Mptr->DVR.visRange);
|
||||
|
||||
if( Mptr->DVR.vrbl_visRange )
|
||||
printf("VRBL DISPATCH VISRNG: TRUE\n");
|
||||
|
||||
if( Mptr->DVR.below_min_DVR )
|
||||
printf("BELOW MIN DVR : TRUE\n");
|
||||
|
||||
if( Mptr->DVR.above_max_DVR )
|
||||
printf("ABOVE MAX DVR : TRUE\n");
|
||||
|
||||
if( Mptr->DVR.Max_visRange != MAXINT )
|
||||
printf("MX DSPAT VISRNG (FT): %d\n",
|
||||
Mptr->DVR.Max_visRange);
|
||||
|
||||
if( Mptr->DVR.Min_visRange != MAXINT )
|
||||
printf("MN DSPAT VISRNG (FT): %d\n",
|
||||
Mptr->DVR.Min_visRange);
|
||||
|
||||
|
||||
i = 0;
|
||||
while ( Mptr->WxObstruct[i][0] != '\0' && i < MAXWXSYMBOLS )
|
||||
{
|
||||
printf("WX/OBSTRUCT VISION : %s\n",
|
||||
Mptr->WxObstruct[i] );
|
||||
i++;
|
||||
}
|
||||
|
||||
if( Mptr->PartialObscurationAmt[0][0] != '\0' )
|
||||
printf("OBSCURATION AMOUNT : %s\n",
|
||||
&(Mptr->PartialObscurationAmt[0][0]));
|
||||
|
||||
if( Mptr->PartialObscurationPhenom[0][0] != '\0' )
|
||||
printf("OBSCURATION PHENOM : %s\n",
|
||||
&(Mptr->PartialObscurationPhenom[0][0]));
|
||||
|
||||
|
||||
if( Mptr->PartialObscurationAmt[1][0] != '\0' )
|
||||
printf("OBSCURATION AMOUNT : %s\n",
|
||||
&(Mptr->PartialObscurationAmt[1][0]));
|
||||
|
||||
if( Mptr->PartialObscurationPhenom[1][0] != '\0' )
|
||||
printf("OBSCURATION PHENOM : %s\n",
|
||||
&(Mptr->PartialObscurationPhenom[1][0]));
|
||||
|
||||
i = 0;
|
||||
while ( Mptr->cldTypHgt[ i ].cloud_type[0] != '\0' &&
|
||||
i < 6 )
|
||||
{
|
||||
if( Mptr->cldTypHgt[ i ].cloud_type[0] != '\0' )
|
||||
printf("CLOUD COVER : %s\n",
|
||||
Mptr->cldTypHgt[ i ].cloud_type);
|
||||
|
||||
if( Mptr->cldTypHgt[ i ].cloud_hgt_char[0] != '\0' )
|
||||
printf("CLOUD HGT (CHARAC.) : %s\n",
|
||||
Mptr->cldTypHgt[ i ].cloud_hgt_char);
|
||||
|
||||
if( Mptr->cldTypHgt[ i ].cloud_hgt_meters != MAXINT)
|
||||
printf("CLOUD HGT (METERS) : %d\n",
|
||||
Mptr->cldTypHgt[ i ].cloud_hgt_meters);
|
||||
|
||||
if( Mptr->cldTypHgt[ i ].other_cld_phenom[0] != '\0' )
|
||||
printf("OTHER CLOUD PHENOM : %s\n",
|
||||
Mptr->cldTypHgt[ i ].other_cld_phenom);
|
||||
|
||||
i++;
|
||||
|
||||
}
|
||||
|
||||
if( Mptr->temp != MAXINT )
|
||||
printf("TEMP. (CELSIUS) : %d\n", Mptr->temp);
|
||||
|
||||
if( Mptr->dew_pt_temp != MAXINT )
|
||||
printf("D.P. TEMP. (CELSIUS): %d\n", Mptr->dew_pt_temp);
|
||||
|
||||
if( Mptr->A_altstng )
|
||||
printf("ALTIMETER (INCHES) : %.2f\n",
|
||||
Mptr->inches_altstng );
|
||||
|
||||
if( Mptr->Q_altstng )
|
||||
printf("ALTIMETER (PASCALS) : %d\n",
|
||||
Mptr->hectoPasc_altstng );
|
||||
|
||||
if( Mptr->TornadicType[0] != '\0' )
|
||||
printf("TORNADIC ACTVTY TYPE: %s\n",
|
||||
Mptr->TornadicType );
|
||||
|
||||
if( Mptr->BTornadicHour != MAXINT )
|
||||
printf("TORN. ACTVTY BEGHOUR: %d\n",
|
||||
Mptr->BTornadicHour );
|
||||
|
||||
if( Mptr->BTornadicMinute != MAXINT )
|
||||
printf("TORN. ACTVTY BEGMIN : %d\n",
|
||||
Mptr->BTornadicMinute );
|
||||
|
||||
if( Mptr->ETornadicHour != MAXINT )
|
||||
printf("TORN. ACTVTY ENDHOUR: %d\n",
|
||||
Mptr->ETornadicHour );
|
||||
|
||||
if( Mptr->ETornadicMinute != MAXINT )
|
||||
printf("TORN. ACTVTY ENDMIN : %d\n",
|
||||
Mptr->ETornadicMinute );
|
||||
|
||||
if( Mptr->TornadicDistance != MAXINT )
|
||||
printf("TORN. DIST. FROM STN: %d\n",
|
||||
Mptr->TornadicDistance );
|
||||
|
||||
if( Mptr->TornadicLOC[0] != '\0' )
|
||||
printf("TORNADIC LOCATION : %s\n",
|
||||
Mptr->TornadicLOC );
|
||||
|
||||
if( Mptr->TornadicDIR[0] != '\0' )
|
||||
printf("TORNAD. DIR FROM STN: %s\n",
|
||||
Mptr->TornadicDIR );
|
||||
|
||||
if( Mptr->TornadicMovDir[0] != '\0' )
|
||||
printf("TORNADO DIR OF MOVM.: %s\n",
|
||||
Mptr->TornadicMovDir );
|
||||
|
||||
|
||||
if( Mptr->autoIndicator[0] != '\0' )
|
||||
printf("AUTO INDICATOR : %s\n",
|
||||
Mptr->autoIndicator);
|
||||
|
||||
if( Mptr->PKWND_dir != MAXINT )
|
||||
printf("PEAK WIND DIRECTION : %d\n",Mptr->PKWND_dir);
|
||||
if( Mptr->PKWND_speed != MAXINT )
|
||||
printf("PEAK WIND SPEED : %d\n",Mptr->PKWND_speed);
|
||||
if( Mptr->PKWND_hour != MAXINT )
|
||||
printf("PEAK WIND HOUR : %d\n",Mptr->PKWND_hour);
|
||||
if( Mptr->PKWND_minute != MAXINT )
|
||||
printf("PEAK WIND MINUTE : %d\n",Mptr->PKWND_minute);
|
||||
|
||||
if( Mptr->WshfTime_hour != MAXINT )
|
||||
printf("HOUR OF WIND SHIFT : %d\n",Mptr->WshfTime_hour);
|
||||
if( Mptr->WshfTime_minute != MAXINT )
|
||||
printf("MINUTE OF WIND SHIFT: %d\n",Mptr->WshfTime_minute);
|
||||
if( Mptr->Wshft_FROPA != FALSE )
|
||||
printf("FROPA ASSOC. W/WSHFT: TRUE\n");
|
||||
|
||||
if( Mptr->TWR_VSBY != (float) MAXINT )
|
||||
printf("TOWER VISIBILITY : %.2f\n",Mptr->TWR_VSBY);
|
||||
if( Mptr->SFC_VSBY != (float) MAXINT )
|
||||
printf("SURFACE VISIBILITY : %.2f\n",Mptr->SFC_VSBY);
|
||||
|
||||
if( Mptr->minVsby != (float) MAXINT )
|
||||
printf("MIN VRBL_VIS (SM) : %.4f\n",Mptr->minVsby);
|
||||
if( Mptr->maxVsby != (float) MAXINT )
|
||||
printf("MAX VRBL_VIS (SM) : %.4f\n",Mptr->maxVsby);
|
||||
|
||||
if( Mptr->VSBY_2ndSite != (float) MAXINT )
|
||||
printf("VSBY_2ndSite (SM) : %.4f\n",Mptr->VSBY_2ndSite);
|
||||
if( Mptr->VSBY_2ndSite_LOC[0] != '\0' )
|
||||
printf("VSBY_2ndSite LOC. : %s\n",
|
||||
Mptr->VSBY_2ndSite_LOC);
|
||||
|
||||
|
||||
if( Mptr->OCNL_LTG )
|
||||
printf("OCCASSIONAL LTG : TRUE\n");
|
||||
|
||||
if( Mptr->FRQ_LTG )
|
||||
printf("FREQUENT LIGHTNING : TRUE\n");
|
||||
|
||||
if( Mptr->CNS_LTG )
|
||||
printf("CONTINUOUS LTG : TRUE\n");
|
||||
|
||||
if( Mptr->CG_LTG )
|
||||
printf("CLOUD-GROUND LTG : TRUE\n");
|
||||
|
||||
if( Mptr->IC_LTG )
|
||||
printf("IN-CLOUD LIGHTNING : TRUE\n");
|
||||
|
||||
if( Mptr->CC_LTG )
|
||||
printf("CLD-CLD LIGHTNING : TRUE\n");
|
||||
|
||||
if( Mptr->CA_LTG )
|
||||
printf("CLOUD-AIR LIGHTNING : TRUE\n");
|
||||
|
||||
if( Mptr->AP_LTG )
|
||||
printf("LIGHTNING AT AIRPORT: TRUE\n");
|
||||
|
||||
if( Mptr->OVHD_LTG )
|
||||
printf("LIGHTNING OVERHEAD : TRUE\n");
|
||||
|
||||
if( Mptr->DSNT_LTG )
|
||||
printf("DISTANT LIGHTNING : TRUE\n");
|
||||
|
||||
if( Mptr->LightningVCTS )
|
||||
printf("L'NING W/I 5-10(ALP): TRUE\n");
|
||||
|
||||
if( Mptr->LightningTS )
|
||||
printf("L'NING W/I 5 (ALP) : TRUE\n");
|
||||
|
||||
if( Mptr->VcyStn_LTG )
|
||||
printf("VCY STN LIGHTNING : TRUE\n");
|
||||
|
||||
if( Mptr->LTG_DIR[0] != '\0' )
|
||||
printf("DIREC. OF LIGHTNING : %s\n", Mptr->LTG_DIR);
|
||||
|
||||
|
||||
|
||||
i = 0;
|
||||
while( i < 3 && Mptr->ReWx[ i ].Recent_weather[0] != '\0' )
|
||||
{
|
||||
printf("RECENT WEATHER : %s",
|
||||
Mptr->ReWx[i].Recent_weather);
|
||||
|
||||
if( Mptr->ReWx[i].Bhh != MAXINT )
|
||||
printf(" BEG_hh = %d",Mptr->ReWx[i].Bhh);
|
||||
if( Mptr->ReWx[i].Bmm != MAXINT )
|
||||
printf(" BEG_mm = %d",Mptr->ReWx[i].Bmm);
|
||||
|
||||
if( Mptr->ReWx[i].Ehh != MAXINT )
|
||||
printf(" END_hh = %d",Mptr->ReWx[i].Ehh);
|
||||
if( Mptr->ReWx[i].Emm != MAXINT )
|
||||
printf(" END_mm = %d",Mptr->ReWx[i].Emm);
|
||||
|
||||
printf("\n");
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
if( Mptr->minCeiling != MAXINT )
|
||||
printf("MIN VRBL_CIG (FT) : %d\n",Mptr->minCeiling);
|
||||
if( Mptr->maxCeiling != MAXINT )
|
||||
printf("MAX VRBL_CIG (FT)) : %d\n",Mptr->maxCeiling);
|
||||
|
||||
if( Mptr->CIG_2ndSite_Meters != MAXINT )
|
||||
printf("CIG2ndSite (FT) : %d\n",Mptr->CIG_2ndSite_Meters);
|
||||
if( Mptr->CIG_2ndSite_LOC[0] != '\0' )
|
||||
printf("CIG @ 2nd Site LOC. : %s\n",Mptr->CIG_2ndSite_LOC);
|
||||
|
||||
if( Mptr->PRESFR )
|
||||
printf("PRESFR : TRUE\n");
|
||||
if( Mptr->PRESRR )
|
||||
printf("PRESRR : TRUE\n");
|
||||
|
||||
if( Mptr->SLPNO )
|
||||
printf("SLPNO : TRUE\n");
|
||||
|
||||
if( Mptr->SLP != (float) MAXINT )
|
||||
printf("SLP (hPa) : %.1f\n", Mptr->SLP);
|
||||
|
||||
if( Mptr->SectorVsby != (float) MAXINT )
|
||||
printf("SECTOR VSBY (MILES) : %.2f\n", Mptr->SectorVsby );
|
||||
|
||||
if( Mptr->SectorVsby_Dir[ 0 ] != '\0' )
|
||||
printf("SECTOR VSBY OCTANT : %s\n", Mptr->SectorVsby_Dir );
|
||||
|
||||
if( Mptr->TS_LOC[ 0 ] != '\0' )
|
||||
printf("THUNDERSTORM LOCAT. : %s\n", Mptr->TS_LOC );
|
||||
|
||||
if( Mptr->TS_MOVMNT[ 0 ] != '\0' )
|
||||
printf("THUNDERSTORM MOVMNT.: %s\n", Mptr->TS_MOVMNT);
|
||||
|
||||
if( Mptr->GR )
|
||||
printf("GR (HAILSTONES) : TRUE\n");
|
||||
|
||||
if( Mptr->GR_Size != (float) MAXINT )
|
||||
printf("HLSTO SIZE (INCHES) : %.3f\n",Mptr->GR_Size);
|
||||
|
||||
if( Mptr->VIRGA )
|
||||
printf("VIRGA : TRUE\n");
|
||||
|
||||
if( Mptr->VIRGA_DIR[0] != '\0' )
|
||||
printf("DIR OF VIRGA FRM STN: %s\n", Mptr->VIRGA_DIR);
|
||||
|
||||
for( i = 0; i < 6; i++ ) {
|
||||
if( Mptr->SfcObscuration[i][0] != '\0' )
|
||||
printf("SfcObscuration : %s\n",
|
||||
&(Mptr->SfcObscuration[i][0]) );
|
||||
}
|
||||
|
||||
if( Mptr->Num8thsSkyObscured != MAXINT )
|
||||
printf("8ths of SkyObscured : %d\n",Mptr->Num8thsSkyObscured);
|
||||
|
||||
if( Mptr->CIGNO )
|
||||
printf("CIGNO : TRUE\n");
|
||||
|
||||
if( Mptr->Ceiling != MAXINT )
|
||||
printf("Ceiling (ft) : %d\n",Mptr->Ceiling);
|
||||
|
||||
if( Mptr->Estimated_Ceiling != MAXINT )
|
||||
printf("Estimated CIG (ft) : %d\n",Mptr->Estimated_Ceiling);
|
||||
|
||||
if( Mptr->VrbSkyBelow[0] != '\0' )
|
||||
printf("VRB SKY COND BELOW : %s\n",Mptr->VrbSkyBelow);
|
||||
|
||||
if( Mptr->VrbSkyAbove[0] != '\0' )
|
||||
printf("VRB SKY COND ABOVE : %s\n",Mptr->VrbSkyAbove);
|
||||
|
||||
if( Mptr->VrbSkyLayerHgt != MAXINT )
|
||||
printf("VRBSKY COND HGT (FT): %d\n",Mptr->VrbSkyLayerHgt);
|
||||
|
||||
if( Mptr->ObscurAloftHgt != MAXINT )
|
||||
printf("Hgt Obscur Aloft(ft): %d\n",Mptr->ObscurAloftHgt);
|
||||
|
||||
if( Mptr->ObscurAloft[0] != '\0' )
|
||||
printf("Obscur Phenom Aloft : %s\n",Mptr->ObscurAloft);
|
||||
|
||||
if( Mptr->ObscurAloftSkyCond[0] != '\0' )
|
||||
printf("Obscur ALOFT SKYCOND: %s\n",Mptr->ObscurAloftSkyCond);
|
||||
|
||||
|
||||
if( Mptr->NOSPECI )
|
||||
printf("NOSPECI : TRUE\n");
|
||||
|
||||
if( Mptr->LAST )
|
||||
printf("LAST : TRUE\n");
|
||||
|
||||
if( Mptr->synoptic_cloud_type[ 0 ] != '\0' )
|
||||
printf("SYNOPTIC CLOUD GROUP: %s\n",Mptr->synoptic_cloud_type);
|
||||
|
||||
if( Mptr->CloudLow != '\0' )
|
||||
printf("LOW CLOUD CODE : %c\n",Mptr->CloudLow);
|
||||
|
||||
if( Mptr->CloudMedium != '\0' )
|
||||
printf("MEDIUM CLOUD CODE : %c\n",Mptr->CloudMedium);
|
||||
|
||||
if( Mptr->CloudHigh != '\0' )
|
||||
printf("HIGH CLOUD CODE : %c\n",Mptr->CloudHigh);
|
||||
|
||||
if( Mptr->SNINCR != MAXINT )
|
||||
printf("SNINCR (INCHES) : %d\n",Mptr->SNINCR);
|
||||
|
||||
if( Mptr->SNINCR_TotalDepth != MAXINT )
|
||||
printf("SNINCR(TOT. INCHES) : %d\n",Mptr->SNINCR_TotalDepth);
|
||||
|
||||
if( Mptr->snow_depth_group[ 0 ] != '\0' )
|
||||
printf("SNOW DEPTH GROUP : %s\n",Mptr->snow_depth_group);
|
||||
|
||||
if( Mptr->snow_depth != MAXINT )
|
||||
printf("SNOW DEPTH (INCHES) : %d\n",Mptr->snow_depth);
|
||||
|
||||
if( Mptr->WaterEquivSnow != (float) MAXINT )
|
||||
printf("H2O EquivSno(inches): %.2f\n",Mptr->WaterEquivSnow);
|
||||
|
||||
if( Mptr->SunshineDur != MAXINT )
|
||||
printf("SUNSHINE (MINUTES) : %d\n",Mptr->SunshineDur);
|
||||
|
||||
if( Mptr->SunSensorOut )
|
||||
printf("SUN SENSOR OUT : TRUE\n");
|
||||
|
||||
if( Mptr->hourlyPrecip != (float) MAXINT )
|
||||
printf("HRLY PRECIP (INCHES): %.2f\n",Mptr->hourlyPrecip);
|
||||
|
||||
if( Mptr->precip_amt != (float) MAXINT)
|
||||
printf("3/6HR PRCIP (INCHES): %.2f\n",
|
||||
Mptr->precip_amt);
|
||||
|
||||
if( Mptr->Indeterminant3_6HrPrecip )
|
||||
printf("INDTRMN 3/6HR PRECIP: TRUE\n");
|
||||
|
||||
if( Mptr->precip_24_amt != (float) MAXINT)
|
||||
printf("24HR PRECIP (INCHES): %.2f\n",
|
||||
Mptr->precip_24_amt);
|
||||
|
||||
if( Mptr->Temp_2_tenths != (float) MAXINT )
|
||||
printf("TMP2TENTHS (CELSIUS): %.1f\n",Mptr->Temp_2_tenths);
|
||||
|
||||
if( Mptr->DP_Temp_2_tenths != (float) MAXINT )
|
||||
printf("DPT2TENTHS (CELSIUS): %.1f\n",Mptr->DP_Temp_2_tenths);
|
||||
|
||||
if( Mptr->maxtemp != (float) MAXINT)
|
||||
printf("MAX TEMP (CELSIUS) : %.1f\n",
|
||||
Mptr->maxtemp);
|
||||
|
||||
if( Mptr->mintemp != (float) MAXINT)
|
||||
printf("MIN TEMP (CELSIUS) : %.1f\n",
|
||||
Mptr->mintemp);
|
||||
|
||||
if( Mptr->max24temp != (float) MAXINT)
|
||||
printf("24HrMAXTMP (CELSIUS): %.1f\n",
|
||||
Mptr->max24temp);
|
||||
|
||||
if( Mptr->min24temp != (float) MAXINT)
|
||||
printf("24HrMINTMP (CELSIUS): %.1f\n",
|
||||
Mptr->min24temp);
|
||||
|
||||
if( Mptr->char_prestndcy != MAXINT)
|
||||
printf("CHAR PRESS TENDENCY : %d\n",
|
||||
Mptr->char_prestndcy );
|
||||
|
||||
if( Mptr->prestndcy != (float) MAXINT)
|
||||
printf("PRES. TENDENCY (hPa): %.1f\n",
|
||||
Mptr->prestndcy );
|
||||
|
||||
if( Mptr->PWINO )
|
||||
printf("PWINO : TRUE\n");
|
||||
|
||||
if( Mptr->PNO )
|
||||
printf("PNO : TRUE\n");
|
||||
|
||||
if( Mptr->CHINO )
|
||||
printf("CHINO : TRUE\n");
|
||||
|
||||
if( Mptr->CHINO_LOC[0] != '\0' )
|
||||
printf("CHINO_LOC : %s\n",Mptr->CHINO_LOC);
|
||||
|
||||
if( Mptr->VISNO )
|
||||
printf("VISNO : TRUE\n");
|
||||
|
||||
if( Mptr->VISNO_LOC[0] != '\0' )
|
||||
printf("VISNO_LOC : %s\n",Mptr->VISNO_LOC);
|
||||
|
||||
if( Mptr->FZRANO )
|
||||
printf("FZRANO : TRUE\n");
|
||||
|
||||
if( Mptr->TSNO )
|
||||
printf("TSNO : TRUE\n");
|
||||
|
||||
if( Mptr->DollarSign)
|
||||
printf("DOLLAR $IGN INDCATR : TRUE\n");
|
||||
|
||||
if( Mptr->horiz_vsby[ 0 ] != '\0' )
|
||||
printf("HORIZ VISIBILITY : %s\n",Mptr->horiz_vsby);
|
||||
|
||||
if( Mptr->dir_min_horiz_vsby[ 0 ] != '\0' )
|
||||
printf("DIR MIN HORIZ VSBY : %s\n",Mptr->dir_min_horiz_vsby);
|
||||
|
||||
if( Mptr->CAVOK )
|
||||
printf("CAVOK : TRUE\n");
|
||||
|
||||
|
||||
if( Mptr->VertVsby != MAXINT )
|
||||
printf("Vert. Vsby (meters) : %d\n",
|
||||
Mptr->VertVsby );
|
||||
|
||||
if( Mptr->charVertVsby[0] != '\0' )
|
||||
printf("Vert. Vsby (CHAR) : %s\n",
|
||||
Mptr->charVertVsby );
|
||||
|
||||
if( Mptr->QFE != MAXINT )
|
||||
printf("QFE : %d\n", Mptr->QFE);
|
||||
|
||||
if( Mptr->VOLCASH )
|
||||
printf("VOLCANIC ASH : TRUE\n");
|
||||
|
||||
if( Mptr->min_vrbl_wind_dir != MAXINT )
|
||||
printf("MIN VRBL WIND DIR : %d\n",Mptr->min_vrbl_wind_dir);
|
||||
if( Mptr->max_vrbl_wind_dir != MAXINT )
|
||||
printf("MAX VRBL WIND DIR : %d\n",Mptr->max_vrbl_wind_dir);
|
||||
|
||||
|
||||
printf("\n\n\n");
|
||||
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
69
simgear/metar/README.Metar
Normal file
69
simgear/metar/README.Metar
Normal file
@@ -0,0 +1,69 @@
|
||||
There are 2 classes: CMetarStation (MetarStation.h) and CMetarReport
|
||||
(MetarReport.h). These classes provide mechanisms to get information
|
||||
about meteorological data reporting stations and about the reports
|
||||
themselves. These stations and reports are known as METAR. See
|
||||
http://tgsv5.nws.noaa.gov/oso/oso1/oso12/metar.htm for information
|
||||
from the USA perspective. Quoting from that site:
|
||||
|
||||
On 1 July 1996, the international standard code for hourly and special
|
||||
surface weather observations, METAR/SPECI, took effect.
|
||||
The METAR acronym roughly translates from the French as Aviation
|
||||
Routine Weather Report . A special report, SPECI, is merely a METAR
|
||||
formatted report which is issued on a non-routine basis as dictated by
|
||||
changing meteorological conditions. The SPECI acronym roughly translates as
|
||||
|
||||
Aviation Selected Special Weather Report . Meanwhile, the international
|
||||
standard code format for terminal forecasts issued for airports, TAF,
|
||||
also took effect. The acronym translates to Aerodrome Forecast.
|
||||
|
||||
This implementation ignores the SPECI and TAF acronyms, calling the
|
||||
entire system METAR.
|
||||
|
||||
The class CMetarStation is implemented by MetarStation.h and
|
||||
MetarStation.cpp. It decodes a text file containing information about
|
||||
individual METAR reporting stations and builds a static database of that
|
||||
information during static construction of the class. There are static
|
||||
member methods to find individual stations, and member functions to
|
||||
extract individual station attributes. The information about METAR
|
||||
stations probably has some overlap with FGFS airport information. That
|
||||
needs to be investigated. The 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 instead of
|
||||
nsd_cccc.
|
||||
The current implementation does not look for updates to this file on the
|
||||
internet.
|
||||
|
||||
The class CMetarReport is implemented by MetarReport.h and MetarReport.cpp.
|
||||
It encapsulates the decoding software written by Carl McCalla at -
|
||||
NOAA/National Weather Service
|
||||
1325 East-West Highway
|
||||
SSMC2, W/OSO242, Station 5114
|
||||
Silver Spring, Maryland 20910
|
||||
Work: (301) 713-0882, Ext 115
|
||||
FAX: (301) 608-0911
|
||||
E-Mail Address: cmccalla@smtpgate.ssmc.noaa.gov
|
||||
http://www.nws.noaa.gov/software/
|
||||
This software generally sucks and the CMetarReport class attempts to clean
|
||||
up some of that suckiness. A CMetarReport object is created with an ASCII
|
||||
string as a construction parameter. The string contains a METAR report.
|
||||
There
|
||||
are member methods to extract selected information from a report by calling
|
||||
the McCalla software. Additional information can be selected by adding new
|
||||
member methods as needed. Certainly the methods currently implemented are
|
||||
not sufficient. METAR reports are available via the internet. In the USA,
|
||||
NOAA provides individual METAR reports in this directory:
|
||||
ftp://weather.noaa.gov/data/observations/metar/stations
|
||||
Other sources are available as well. The current implementation does not
|
||||
look for reports on the internet.
|
||||
|
||||
There is a test program in the MetarTest subdirectory. It requires that a
|
||||
#define be changed in the MetarStation.cpp file. Add #define TESTPROG to
|
||||
the code or -D TESTPROG to the compilation. This is necessary because the
|
||||
FGFS options class is coupled tightly to code that shouldn't be pulled into
|
||||
the test program. The test program will decode many METAR reports and
|
||||
display
|
||||
them to the screen, then it will plot all the METAR reporting stations on a
|
||||
tumbling globe.
|
||||
|
||||
211
simgear/metar/Stspack2.cpp
Normal file
211
simgear/metar/Stspack2.cpp
Normal file
@@ -0,0 +1,211 @@
|
||||
#pragma comment (compiler)
|
||||
//#pragma comment (date)
|
||||
//#pragma comment (timestamp)
|
||||
#pragma pagesize(80)
|
||||
|
||||
#include "Local.h" /* standard header file */
|
||||
|
||||
#pragma page(1)
|
||||
#pragma subtitle(" ")
|
||||
#pragma subtitle("stspack2 - Local string test functions ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: stspack2 */
|
||||
/* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
|
||||
/* Date: 05 Oct 1992 */
|
||||
/* Programmer: ALLAN DARLING */
|
||||
/* Language: C/2 */
|
||||
/* */
|
||||
/* Abstract: The stspack2 package contains functions to */
|
||||
/* perform the isalnum through isxdigit functions */
|
||||
/* on strings. The functions come in four forms: */
|
||||
/* those that test NULL delimited strings and are */
|
||||
/* named in the form sxxxxxxx, those that test at */
|
||||
/* most n characters and are named in the form */
|
||||
/* nxxxxxxx, those that search forward in a string */
|
||||
/* and are named in the form nxtyyyyy, and those */
|
||||
/* that search backward in a string and are named */
|
||||
/* in the form lstyyyyy. */
|
||||
/* */
|
||||
/* The xxxxxxx is the name of the test applied to */
|
||||
/* each character in the string, such as isalpha, */
|
||||
/* thus a function to test a NULL delimited string */
|
||||
/* an return a nonzero value if all characters in */
|
||||
/* the string are digits is named sisdigit. */
|
||||
/* */
|
||||
/* The yyyyy is the name of the test applied to */
|
||||
/* characters in a string, minus the 'is' prefix. */
|
||||
/* Thus a function to find the next digit in a NULL */
|
||||
/* delimited string and return a pointer to it is */
|
||||
/* named nxtdigit. */
|
||||
/* */
|
||||
/* The only exception to the naming rule is for the */
|
||||
/* functions that test for hexadecimal digits. */
|
||||
/* These are named sisxdigi, nisxdigi, nxtxdigi, */
|
||||
/* and lstxdigi because of the eight character */
|
||||
/* function name limitation. */
|
||||
/* */
|
||||
/* The nxxxxxxx class of functions will test up to */
|
||||
/* n characters or the first NULL character */
|
||||
/* encountered, whichever comes first. For all */
|
||||
/* classes of functions, the string sentinal is */
|
||||
/* not included in the test. */
|
||||
/* */
|
||||
/* External Functions Called: */
|
||||
/* isalnum, isalpha, iscntrl, isdigit, isgraph, */
|
||||
/* islower, isprint, ispunct, isspace, isupper, */
|
||||
/* isxdigit. */
|
||||
/* */
|
||||
/* Input: For sxxxxxxx class functions, a pointer to a */
|
||||
/* NULL delimited character string. */
|
||||
/* */
|
||||
/* For nxtyyyyy class functions, a pointer to a */
|
||||
/* NULL delimited character string. */
|
||||
/* */
|
||||
/* for nxxxxxxx class functions, a pointer to a */
|
||||
/* character array, and a positive, nonzero integer.*/
|
||||
/* */
|
||||
/* for lstyyyyy class functions, a pointer to a */
|
||||
/* character array, and a positive, nonzero integer.*/
|
||||
/* */
|
||||
/* Output: A nonzero value if the test is true for all */
|
||||
/* characters in the string, a zero value otherwise.*/
|
||||
/* */
|
||||
/* Modification History: */
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
|
||||
int nisalnum(char *s, int n) {
|
||||
|
||||
for (; *s && n; s++, n--)
|
||||
|
||||
if (!isalnum(*s))
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
|
||||
} /* end nisalnum */
|
||||
|
||||
|
||||
int nisalpha(char *s, int n) {
|
||||
|
||||
for (; *s && n; s++, n--)
|
||||
|
||||
if (!isalpha(*s))
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
|
||||
} /* end nisalpha */
|
||||
|
||||
|
||||
int niscntrl(char *s, int n) {
|
||||
|
||||
for (; *s && n; s++, n--)
|
||||
|
||||
if (!iscntrl(*s))
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
|
||||
} /* end niscntrl */
|
||||
|
||||
|
||||
int nisdigit(char *s, int n) {
|
||||
|
||||
for (; *s && n; s++, n--)
|
||||
|
||||
if (!isdigit(*s))
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
|
||||
} /* end nisdigit */
|
||||
|
||||
|
||||
int nisgraph(char *s, int n) {
|
||||
|
||||
for (; *s && n; s++, n--)
|
||||
|
||||
if (!isgraph(*s))
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
|
||||
} /* end nisgraph */
|
||||
|
||||
|
||||
int nislower(char *s, int n) {
|
||||
|
||||
for (; *s && n; s++, n--)
|
||||
|
||||
if (!islower(*s))
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
|
||||
} /* end nislower */
|
||||
|
||||
|
||||
int nisprint(char *s, int n) {
|
||||
|
||||
for (; *s && n; s++, n--)
|
||||
|
||||
if (!isprint(*s))
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
|
||||
} /* end nisprint */
|
||||
|
||||
|
||||
int nispunct(char *s, int n) {
|
||||
|
||||
for (; *s && n; s++, n--)
|
||||
|
||||
if (!ispunct(*s))
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
|
||||
} /* end nispunct */
|
||||
|
||||
|
||||
int nisspace(char *s, int n) {
|
||||
|
||||
for (; *s && n; s++, n--)
|
||||
|
||||
if (!isspace(*s))
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
|
||||
} /* end nisspace */
|
||||
|
||||
|
||||
int nisupper(char *s, int n) {
|
||||
|
||||
for (; *s && n; s++, n--)
|
||||
|
||||
if (!isupper(*s))
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
|
||||
} /* end nisupper */
|
||||
|
||||
|
||||
int nisxdigi(char *s, int n) {
|
||||
|
||||
for (; *s && n; s++, n--)
|
||||
|
||||
if (!isxdigit(*s))
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
|
||||
} /* end nisxdigi */
|
||||
|
||||
#pragma page(1)
|
||||
211
simgear/metar/Stspack3.cpp
Normal file
211
simgear/metar/Stspack3.cpp
Normal file
@@ -0,0 +1,211 @@
|
||||
#pragma comment (compiler)
|
||||
//#pragma comment (date)
|
||||
//#pragma comment (timestamp)
|
||||
#pragma pagesize(80)
|
||||
|
||||
#include "Local.h" /* standard header file */
|
||||
|
||||
#pragma page(1)
|
||||
#pragma subtitle(" ")
|
||||
#pragma subtitle("stspack3 - Local string test functions ")
|
||||
/********************************************************************/
|
||||
/* */
|
||||
/* Title: stspack3 */
|
||||
/* Organization: W/OSO242 - GRAPHICS AND DISPLAY SECTION */
|
||||
/* Date: 05 Oct 1992 */
|
||||
/* Programmer: ALLAN DARLING */
|
||||
/* Language: C/2 */
|
||||
/* */
|
||||
/* Abstract: The stspack3 package contains functions to */
|
||||
/* perform the isalnum through isxdigit functions */
|
||||
/* on strings. The functions come in four forms: */
|
||||
/* those that test NULL delimited strings and are */
|
||||
/* named in the form sxxxxxxx, those that test at */
|
||||
/* most n characters and are named in the form */
|
||||
/* nxxxxxxx, those that search forward in a string */
|
||||
/* and are named in the form nxtyyyyy, and those */
|
||||
/* that search backward in a string and are named */
|
||||
/* in the form lstyyyyy. */
|
||||
/* */
|
||||
/* The xxxxxxx is the name of the test applied to */
|
||||
/* each character in the string, such as isalpha, */
|
||||
/* thus a function to test a NULL delimited string */
|
||||
/* an return a nonzero value if all characters in */
|
||||
/* the string are digits is named sisdigit. */
|
||||
/* */
|
||||
/* The yyyyy is the name of the test applied to */
|
||||
/* characters in a string, minus the 'is' prefix. */
|
||||
/* Thus a function to find the next digit in a NULL */
|
||||
/* delimited string and return a pointer to it is */
|
||||
/* named nxtdigit. */
|
||||
/* */
|
||||
/* The only exception to the naming rule is for the */
|
||||
/* functions that test for hexadecimal digits. */
|
||||
/* These are named sisxdigi, nisxdigi, nxtxdigi, */
|
||||
/* and lstxdigi because of the eight character */
|
||||
/* function name limitation. */
|
||||
/* */
|
||||
/* The nxxxxxxx class of functions will test up to */
|
||||
/* n characters or the first NULL character */
|
||||
/* encountered, whichever comes first. For all */
|
||||
/* classes of functions, the string sentinal is */
|
||||
/* not included in the test. */
|
||||
/* */
|
||||
/* External Functions Called: */
|
||||
/* isalnum, isalpha, iscntrl, isdigit, isgraph, */
|
||||
/* islower, isprint, ispunct, isspace, isupper, */
|
||||
/* isxdigit. */
|
||||
/* */
|
||||
/* Input: For sxxxxxxx class functions, a pointer to a */
|
||||
/* NULL delimited character string. */
|
||||
/* */
|
||||
/* For nxtyyyyy class functions, a pointer to a */
|
||||
/* NULL delimited character string. */
|
||||
/* */
|
||||
/* for nxxxxxxx class functions, a pointer to a */
|
||||
/* character array, and a positive, nonzero integer.*/
|
||||
/* */
|
||||
/* for lstyyyyy class functions, a pointer to a */
|
||||
/* character array, and a positive, nonzero integer.*/
|
||||
/* */
|
||||
/* Output: A nonzero value if the test is true for all */
|
||||
/* characters in the string, a zero value otherwise.*/
|
||||
/* */
|
||||
/* Modification History: */
|
||||
/* None. */
|
||||
/* */
|
||||
/********************************************************************/
|
||||
#pragma page(1)
|
||||
char *nxtalnum(char *s) {
|
||||
|
||||
for (; !isalnum(*s) && *s; s++) ;
|
||||
|
||||
if (*s)
|
||||
return (s);
|
||||
else
|
||||
return (NULL);
|
||||
|
||||
} /* end nxtalnum */
|
||||
|
||||
|
||||
char *nxtalpha(char *s) {
|
||||
|
||||
for (; !isalpha(*s) && *s; s++) ;
|
||||
|
||||
if (*s)
|
||||
return (s);
|
||||
else
|
||||
return (NULL);
|
||||
|
||||
} /* end nxtalpha */
|
||||
|
||||
|
||||
char *nxtcntrl(char *s) {
|
||||
|
||||
for (; !iscntrl(*s) && *s; s++) ;
|
||||
|
||||
if (*s)
|
||||
return (s);
|
||||
else
|
||||
return (NULL);
|
||||
|
||||
} /* end nxtcntrl */
|
||||
|
||||
|
||||
char *nxtdigit(char *s) {
|
||||
|
||||
for (; !isdigit(*s) && *s; s++) ;
|
||||
|
||||
if (*s)
|
||||
return (s);
|
||||
else
|
||||
return (NULL);
|
||||
|
||||
} /* end nxtdigit */
|
||||
|
||||
|
||||
char *nxtgraph(char *s) {
|
||||
|
||||
for (; !isgraph(*s) && *s; s++) ;
|
||||
|
||||
if (*s)
|
||||
return (s);
|
||||
else
|
||||
return (NULL);
|
||||
|
||||
} /* end nxtgraph */
|
||||
|
||||
|
||||
char *nxtlower(char *s) {
|
||||
|
||||
for (; !islower(*s) && *s; s++) ;
|
||||
|
||||
if (*s)
|
||||
return (s);
|
||||
else
|
||||
return (NULL);
|
||||
|
||||
} /* end nxtlower */
|
||||
|
||||
|
||||
char *nxtprint(char *s) {
|
||||
|
||||
for (; !isprint(*s) && *s; s++) ;
|
||||
|
||||
if (*s)
|
||||
return (s);
|
||||
else
|
||||
return (NULL);
|
||||
|
||||
} /* end nxtprint */
|
||||
|
||||
|
||||
char *nxtpunct(char *s) {
|
||||
|
||||
for (; !ispunct(*s) && *s; s++) ;
|
||||
|
||||
if (*s)
|
||||
return (s);
|
||||
else
|
||||
return (NULL);
|
||||
|
||||
} /* end nxtpunct */
|
||||
|
||||
|
||||
char *nxtspace(char *s) {
|
||||
|
||||
for (; !isspace(*s) && *s; s++) ;
|
||||
|
||||
if (*s)
|
||||
return (s);
|
||||
else
|
||||
return (NULL);
|
||||
|
||||
} /* end nxtspace */
|
||||
|
||||
|
||||
char *nxtupper(char *s) {
|
||||
|
||||
for (; !isupper(*s) && *s; s++) ;
|
||||
|
||||
if (*s)
|
||||
return (s);
|
||||
else
|
||||
return (NULL);
|
||||
|
||||
} /* end nxtupper */
|
||||
|
||||
|
||||
char *nxtxdigi(char *s) {
|
||||
|
||||
for (; !isxdigit(*s) && *s; s++) ;
|
||||
|
||||
if (*s)
|
||||
return (s);
|
||||
else
|
||||
return (NULL);
|
||||
|
||||
} /* end nxtxdigi */
|
||||
|
||||
|
||||
#pragma page(1)
|
||||
26
simgear/misc/Makefile.am
Normal file
26
simgear/misc/Makefile.am
Normal file
@@ -0,0 +1,26 @@
|
||||
includedir = @includedir@/misc
|
||||
|
||||
if HAVE_ZLIB
|
||||
ZLIB_INCL =
|
||||
else
|
||||
ZLIB_INCL = -I$(top_builddir)/zlib
|
||||
endif
|
||||
|
||||
lib_LIBRARIES = libsgmisc.a
|
||||
|
||||
include_HEADERS = \
|
||||
fgpath.hxx \
|
||||
fgstream.hxx \
|
||||
stopwatch.hxx \
|
||||
strutils.hxx \
|
||||
texcoord.hxx \
|
||||
zfstream.hxx
|
||||
|
||||
libsgmisc_a_SOURCES = \
|
||||
fgpath.cxx \
|
||||
fgstream.cxx \
|
||||
strutils.cxx \
|
||||
texcoord.cxx \
|
||||
zfstream.cxx
|
||||
|
||||
INCLUDES += -I$(top_builddir)/src
|
||||
101
simgear/misc/fgpath.cxx
Normal file
101
simgear/misc/fgpath.cxx
Normal file
@@ -0,0 +1,101 @@
|
||||
//
|
||||
// fgpath.cxx -- 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 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 "fgpath.hxx"
|
||||
|
||||
|
||||
// If Unix, replace all ":" with "/". If MacOS, replace all "/" with
|
||||
// ":" it should go without saying that neither of these characters
|
||||
// should be used in file or directory names. In windoze, allow the
|
||||
// second character to be a ":" for things like c:\foo\bar
|
||||
|
||||
static string fix_path( const string path ) {
|
||||
string result = path;
|
||||
|
||||
for ( int i = 0; i < (int)path.size(); ++i ) {
|
||||
#if defined( WIN32 )
|
||||
// for windoze, don't replace the ":" for the second character
|
||||
if ( i == 1 ) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if ( result[i] == FG_BAD_PATH_SEP ) {
|
||||
result[i] = FG_PATH_SEP;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// default constructor
|
||||
FGPath::FGPath() {
|
||||
path = "";
|
||||
}
|
||||
|
||||
|
||||
// create a path based on "path"
|
||||
FGPath::FGPath( const string p ) {
|
||||
set( p );
|
||||
}
|
||||
|
||||
|
||||
// destructor
|
||||
FGPath::~FGPath() {
|
||||
}
|
||||
|
||||
|
||||
// set path
|
||||
void FGPath::set( const string p ) {
|
||||
path = fix_path( p );
|
||||
}
|
||||
|
||||
|
||||
// append another piece to the existing path
|
||||
void FGPath::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;
|
||||
}
|
||||
path += part;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// concatenate a string to the end of the path without inserting a
|
||||
// path separator
|
||||
void FGPath::concat( const string p ) {
|
||||
string part = fix_path( p );
|
||||
|
||||
if ( path.size() == 0 ) {
|
||||
path = part;
|
||||
} else {
|
||||
path += part;
|
||||
}
|
||||
}
|
||||
85
simgear/misc/fgpath.hxx
Normal file
85
simgear/misc/fgpath.hxx
Normal file
@@ -0,0 +1,85 @@
|
||||
//
|
||||
// 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 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 _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 MACOS
|
||||
# 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
|
||||
|
||||
|
||||
158
simgear/misc/fgstream.cxx
Normal file
158
simgear/misc/fgstream.cxx
Normal file
@@ -0,0 +1,158 @@
|
||||
// zlib input file stream wrapper.
|
||||
//
|
||||
// Written by Bernie Bright, 1998
|
||||
//
|
||||
// Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
#include <ctype.h> // isspace()
|
||||
|
||||
#include "fgstream.hxx"
|
||||
|
||||
fg_gzifstream::fg_gzifstream()
|
||||
: istream(&gzbuf)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Open a possibly gzipped file for reading.
|
||||
//
|
||||
fg_gzifstream::fg_gzifstream( const string& name, ios_openmode io_mode )
|
||||
: istream(&gzbuf)
|
||||
{
|
||||
this->open( name, io_mode );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Attach a stream to an already opened file descriptor.
|
||||
//
|
||||
fg_gzifstream::fg_gzifstream( int fd, ios_openmode io_mode )
|
||||
: istream(&gzbuf)
|
||||
{
|
||||
gzbuf.attach( fd, io_mode );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Open a possibly gzipped file for reading.
|
||||
// If the initial open fails and the filename has a ".gz" extension then
|
||||
// remove the extension and try again.
|
||||
// If the initial open fails and the filename doesn't have a ".gz" extension
|
||||
// then append ".gz" and try again.
|
||||
//
|
||||
void
|
||||
fg_gzifstream::open( const string& name, ios_openmode io_mode )
|
||||
{
|
||||
gzbuf.open( name.c_str(), io_mode );
|
||||
if ( ! gzbuf.is_open() )
|
||||
{
|
||||
string s = name;
|
||||
if ( s.substr( s.length() - 3, 3 ) == ".gz" )
|
||||
{
|
||||
// remove ".gz" suffix
|
||||
s.replace( s.length() - 3, 3, "" );
|
||||
// s.erase( s.length() - 3, 3 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Append ".gz" suffix
|
||||
s += ".gz";
|
||||
}
|
||||
|
||||
// Try again.
|
||||
gzbuf.open( s.c_str(), io_mode );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fg_gzifstream::attach( int fd, ios_openmode io_mode )
|
||||
{
|
||||
gzbuf.attach( fd, io_mode );
|
||||
}
|
||||
|
||||
//
|
||||
// Manipulators
|
||||
//
|
||||
|
||||
istream&
|
||||
skipeol( istream& in )
|
||||
{
|
||||
char c = '\0';
|
||||
// skip to end of line.
|
||||
|
||||
#ifdef __MWERKS__
|
||||
while ( in.get(c) && c != '\0' ) {
|
||||
#else
|
||||
while ( in.get(c) ) {
|
||||
#endif
|
||||
if ( (c == '\n') || (c == '\r') ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
istream&
|
||||
skipws( istream& in ) {
|
||||
char c;
|
||||
#ifdef __MWERKS__
|
||||
while ( in.get(c) && c != '\0' ) {
|
||||
#else
|
||||
while ( in.get(c) ) {
|
||||
#endif
|
||||
|
||||
#ifdef __MWERKS__
|
||||
if ( ! isspace( c ) && c != '\n' ) {
|
||||
#else
|
||||
if ( ! isspace( c ) ) {
|
||||
#endif
|
||||
// put pack the non-space character
|
||||
in.putback(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
istream&
|
||||
skipcomment( istream& in )
|
||||
{
|
||||
while ( in )
|
||||
{
|
||||
// skip whitespace
|
||||
#ifdef __MWERKS__
|
||||
in >> ::skipws;
|
||||
#else
|
||||
in >> skipws;
|
||||
#endif
|
||||
|
||||
char c;
|
||||
if ( in.get( c ) && c != '#' )
|
||||
{
|
||||
// not a comment
|
||||
in.putback(c);
|
||||
break;
|
||||
}
|
||||
in >> skipeol;
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
102
simgear/misc/fgstream.hxx
Normal file
102
simgear/misc/fgstream.hxx
Normal file
@@ -0,0 +1,102 @@
|
||||
// zlib input file stream wrapper.
|
||||
//
|
||||
// Written by Bernie Bright, 1998
|
||||
//
|
||||
// Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
#ifndef _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 */
|
||||
|
||||
121
simgear/misc/stopwatch.hxx
Normal file
121
simgear/misc/stopwatch.hxx
Normal file
@@ -0,0 +1,121 @@
|
||||
/***************************************************************************
|
||||
* stopwatch.hxx Timer class, for use in benchmarking
|
||||
*
|
||||
* Based on blitz/Timer.h
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 1997,1998 Todd Veldhuizen <tveldhui@seurat.uwaterloo.ca>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
// It will need to be rewritten for Windows, NT, Mac.
|
||||
// NEEDS_WORK
|
||||
|
||||
#ifndef _STOPWATCH_HXX
|
||||
#define _STOPWATCH_HXX
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) && ! defined(HAVE_GETRUSAGE)
|
||||
# define HAVE_GETRUSAGE
|
||||
#endif
|
||||
|
||||
#if defined( WIN32 ) && defined( HAVE_GETRUSAGE )
|
||||
# undef HAVE_GETRUSAGE
|
||||
#endif // WIN32
|
||||
|
||||
#if defined( HAVE_GETRUSAGE )
|
||||
# if defined( __FreeBSD__ )
|
||||
# include <sys/types.h>
|
||||
# endif
|
||||
# include <sys/time.h>
|
||||
# include <sys/resource.h>
|
||||
# include <unistd.h>
|
||||
#elif defined( WIN32 )
|
||||
# include <windows.h>
|
||||
#else
|
||||
# include <time.h>
|
||||
#endif
|
||||
|
||||
class StopWatch {
|
||||
|
||||
public:
|
||||
StopWatch()
|
||||
{
|
||||
// state_ = uninitialized;
|
||||
}
|
||||
|
||||
void start()
|
||||
{
|
||||
// state_ = running;
|
||||
t1_ = systemTime();
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
t2_ = systemTime();
|
||||
// BZPRECONDITION(state_ == running);
|
||||
// state_ = stopped;
|
||||
}
|
||||
|
||||
double elapsedSeconds()
|
||||
{
|
||||
// BZPRECONDITION(state_ == stopped);
|
||||
return t2_ - t1_;
|
||||
}
|
||||
|
||||
private:
|
||||
StopWatch(StopWatch&) { }
|
||||
void operator=(StopWatch&) { }
|
||||
|
||||
double systemTime()
|
||||
{
|
||||
#if defined( HAVE_GETRUSAGE )
|
||||
getrusage(RUSAGE_SELF, &resourceUsage_);
|
||||
double seconds = resourceUsage_.ru_utime.tv_sec
|
||||
+ resourceUsage_.ru_stime.tv_sec;
|
||||
double micros = resourceUsage_.ru_utime.tv_usec
|
||||
+ resourceUsage_.ru_stime.tv_usec;
|
||||
return seconds + micros/1.0e6;
|
||||
#elif defined( WIN32 )
|
||||
return double(GetTickCount()) * double(1e-3);
|
||||
#else
|
||||
return clock() / (double) CLOCKS_PER_SEC;
|
||||
#endif
|
||||
}
|
||||
|
||||
// enum { uninitialized, running, stopped } state_;
|
||||
|
||||
#if defined( HAVE_GETRUSAGE )
|
||||
struct rusage resourceUsage_;
|
||||
#endif
|
||||
|
||||
double t1_, t2_;
|
||||
};
|
||||
|
||||
#endif // _STOPWATCH_HXX
|
||||
|
||||
71
simgear/misc/strutils.cxx
Normal file
71
simgear/misc/strutils.cxx
Normal file
@@ -0,0 +1,71 @@
|
||||
// String utilities.
|
||||
//
|
||||
// Written by Bernie Bright, 1998
|
||||
//
|
||||
// Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "strutils.hxx"
|
||||
|
||||
const string whitespace = " \n\r\t";
|
||||
|
||||
//
|
||||
string
|
||||
trimleft( const string& s, const string& trimmings )
|
||||
{
|
||||
string result;
|
||||
string::size_type pos = s.find_first_not_of( trimmings );
|
||||
if ( pos != string::npos )
|
||||
{
|
||||
result.assign( s.substr( pos ) );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
string
|
||||
trimright( const string& s, const string& trimmings )
|
||||
{
|
||||
string result;
|
||||
|
||||
string::size_type pos = s.find_last_not_of( trimmings );
|
||||
if ( pos == string::npos )
|
||||
{
|
||||
// Not found, return the original string.
|
||||
result = s;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.assign( s.substr( 0, pos+1 ) );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
string
|
||||
trim( const string& s, const string& trimmings )
|
||||
{
|
||||
return trimright( trimleft( s, trimmings ), trimmings );
|
||||
}
|
||||
|
||||
65
simgear/misc/strutils.hxx
Normal file
65
simgear/misc/strutils.hxx
Normal file
@@ -0,0 +1,65 @@
|
||||
// String utilities.
|
||||
//
|
||||
// Written by Bernie Bright, 1998
|
||||
//
|
||||
// Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
#ifndef STRUTILS_H
|
||||
#define STRUTILS_H
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include STL_STRING
|
||||
|
||||
#ifdef FG_HAVE_STD_INCLUDES
|
||||
# include <cstdlib>
|
||||
#else
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
FG_USING_STD(string);
|
||||
|
||||
// Default characters to remove.
|
||||
extern const string whitespace;
|
||||
|
||||
// Returns a string with trailing characters removed.
|
||||
string trimleft( const string& s, const string& trimmings = whitespace );
|
||||
|
||||
// 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.
|
||||
string trim( const string& s, const string& trimmings = whitespace );
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
inline double
|
||||
atof( const string& str )
|
||||
{
|
||||
return ::atof( str.c_str() );
|
||||
}
|
||||
|
||||
inline int
|
||||
atoi( const string& str )
|
||||
{
|
||||
return ::atoi( str.c_str() );
|
||||
}
|
||||
|
||||
#endif // STRUTILS_H
|
||||
|
||||
197
simgear/misc/texcoord.cxx
Normal file
197
simgear/misc/texcoord.cxx
Normal file
@@ -0,0 +1,197 @@
|
||||
// texcoord.hxx -- routine(s) to handle texture coordinate generation
|
||||
//
|
||||
// Written by Curtis Olson, started March 1999.
|
||||
//
|
||||
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#include "texcoord.hxx"
|
||||
|
||||
|
||||
#define FG_STANDARD_TEXTURE_DIMENSION 1000.0 // meters
|
||||
#define MAX_TEX_COORD 8.0
|
||||
#define HALF_MAX_TEX_COORD ( MAX_TEX_COORD / 2.0 )
|
||||
|
||||
|
||||
// return the basic unshifted/unmoded texture coordinate for a lat/lon
|
||||
inline Point3D basic_tex_coord( const Point3D& p,
|
||||
double degree_width, double degree_height,
|
||||
double scale )
|
||||
{
|
||||
return Point3D( p.x() * ( degree_width * scale /
|
||||
FG_STANDARD_TEXTURE_DIMENSION ),
|
||||
p.y() * ( degree_width * scale /
|
||||
FG_STANDARD_TEXTURE_DIMENSION ),
|
||||
0.0 );
|
||||
}
|
||||
|
||||
|
||||
// traverse the specified fan/strip/list of vertices and attempt to
|
||||
// calculate "none stretching" texture coordinates
|
||||
point_list calc_tex_coords( const FGBucket& b, const point_list& geod_nodes,
|
||||
const int_list& fan, double scale )
|
||||
{
|
||||
// cout << "calculating texture coordinates for a specific fan of size = "
|
||||
// << fan.size() << endl;
|
||||
|
||||
// calculate perimeter based on center of this degree (not center
|
||||
// of bucket)
|
||||
double clat = (int)b.get_center_lat();
|
||||
if ( clat > 0 ) {
|
||||
clat = (int)clat + 0.5;
|
||||
} else {
|
||||
clat = (int)clat - 0.5;
|
||||
}
|
||||
|
||||
double clat_rad = clat * DEG_TO_RAD;
|
||||
double cos_lat = cos( clat_rad );
|
||||
double local_radius = cos_lat * EQUATORIAL_RADIUS_M;
|
||||
double local_perimeter = 2.0 * local_radius * FG_PI;
|
||||
double degree_width = local_perimeter / 360.0;
|
||||
|
||||
// cout << "clat = " << clat << endl;
|
||||
// cout << "clat (radians) = " << clat_rad << endl;
|
||||
// cout << "cos(lat) = " << cos_lat << endl;
|
||||
// cout << "local_radius = " << local_radius << endl;
|
||||
// cout << "local_perimeter = " << local_perimeter << endl;
|
||||
// cout << "degree_width = " << degree_width << endl;
|
||||
|
||||
double perimeter = 2.0 * EQUATORIAL_RADIUS_M * FG_PI;
|
||||
double degree_height = perimeter / 360.0;
|
||||
// cout << "degree_height = " << degree_height << endl;
|
||||
|
||||
// find min/max of fan
|
||||
Point3D tmin, tmax, p, t;
|
||||
bool first = true;
|
||||
|
||||
for ( int i = 0; i < (int)fan.size(); ++i ) {
|
||||
p = geod_nodes[ fan[i] ];
|
||||
// cout << "point p = " << p << endl;
|
||||
|
||||
t = basic_tex_coord( p, degree_width, degree_height, scale );
|
||||
// cout << "basic_tex_coord = " << t << endl;
|
||||
|
||||
if ( first ) {
|
||||
tmin = tmax = t;
|
||||
first = false;
|
||||
} else {
|
||||
if ( t.x() < tmin.x() ) {
|
||||
tmin.setx( t.x() );
|
||||
}
|
||||
if ( t.y() < tmin.y() ) {
|
||||
tmin.sety( t.y() );
|
||||
}
|
||||
if ( t.x() > tmax.x() ) {
|
||||
tmax.setx( t.x() );
|
||||
}
|
||||
if ( t.y() > tmax.y() ) {
|
||||
tmax.sety( t.y() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double dx = fabs( tmax.x() - tmin.x() );
|
||||
double dy = fabs( tmax.y() - tmin.y() );
|
||||
// cout << "dx = " << dx << " dy = " << dy << endl;
|
||||
|
||||
bool do_shift = false;
|
||||
Point3D mod_shift;
|
||||
if ( (dx > HALF_MAX_TEX_COORD) || (dy > HALF_MAX_TEX_COORD) ) {
|
||||
// structure is too big, we'll just have to shift it so that
|
||||
// tmin = (0,0). This messes up subsequent texture scaling,
|
||||
// but is the best we can do.
|
||||
// cout << "SHIFTING" << endl;
|
||||
do_shift = true;
|
||||
tmin.setx( (double)( (int)tmin.x() + 1 ) );
|
||||
tmin.sety( (double)( (int)tmin.y() + 1 ) );
|
||||
// cout << "found tmin = " << tmin << endl;
|
||||
} else {
|
||||
// structure is small enough ... we can mod it so we can
|
||||
// properly scale the texture coordinates later.
|
||||
// cout << "MODDING" << endl;
|
||||
double x1 = fmod(tmin.x(), MAX_TEX_COORD);
|
||||
while ( x1 < 0 ) { x1 += MAX_TEX_COORD; }
|
||||
|
||||
double y1 = fmod(tmin.y(), MAX_TEX_COORD);
|
||||
while ( y1 < 0 ) { y1 += MAX_TEX_COORD; }
|
||||
|
||||
double x2 = fmod(tmax.x(), MAX_TEX_COORD);
|
||||
while ( x2 < 0 ) { x2 += MAX_TEX_COORD; }
|
||||
|
||||
double y2 = fmod(tmax.y(), MAX_TEX_COORD);
|
||||
while ( y2 < 0 ) { y2 += MAX_TEX_COORD; }
|
||||
|
||||
// At this point we know that the object is < 16 wide in
|
||||
// texture coordinate space. If the modulo of the tmin is >
|
||||
// the mod of the tmax at this point, then we know that the
|
||||
// starting tex coordinate for the tmin > 16 so we can shift
|
||||
// everything down by 16 and get it within the 0-32 range.
|
||||
|
||||
if ( x1 > x2 ) {
|
||||
mod_shift.setx( HALF_MAX_TEX_COORD );
|
||||
} else {
|
||||
mod_shift.setx( 0.0 );
|
||||
}
|
||||
|
||||
if ( y1 > y2 ) {
|
||||
mod_shift.sety( HALF_MAX_TEX_COORD );
|
||||
} else {
|
||||
mod_shift.sety( 0.0 );
|
||||
}
|
||||
|
||||
// cout << "mod_shift = " << mod_shift << endl;
|
||||
}
|
||||
|
||||
// generate tex_list
|
||||
Point3D adjusted_t;
|
||||
point_list tex;
|
||||
tex.clear();
|
||||
for ( int i = 0; i < (int)fan.size(); ++i ) {
|
||||
p = geod_nodes[ fan[i] ];
|
||||
t = basic_tex_coord( p, degree_width, degree_height, scale );
|
||||
// cout << "second t = " << t << endl;
|
||||
|
||||
if ( do_shift ) {
|
||||
adjusted_t = t - tmin;
|
||||
} else {
|
||||
adjusted_t.setx( fmod(t.x() + mod_shift.x(), MAX_TEX_COORD) );
|
||||
while ( adjusted_t.x() < 0 ) {
|
||||
adjusted_t.setx( adjusted_t.x() + MAX_TEX_COORD );
|
||||
}
|
||||
adjusted_t.sety( fmod(t.y() + mod_shift.y(), MAX_TEX_COORD) );
|
||||
while ( adjusted_t.y() < 0 ) {
|
||||
adjusted_t.sety( adjusted_t.y() + MAX_TEX_COORD );
|
||||
}
|
||||
// cout << "adjusted_t " << adjusted_t << endl;
|
||||
}
|
||||
|
||||
if ( adjusted_t.x() < FG_EPSILON ) {
|
||||
adjusted_t.setx( 0.0 );
|
||||
}
|
||||
if ( adjusted_t.y() < FG_EPSILON ) {
|
||||
adjusted_t.sety( 0.0 );
|
||||
}
|
||||
adjusted_t.setz( 0.0 );
|
||||
// cout << "adjusted_t = " << adjusted_t << endl;
|
||||
|
||||
tex.push_back( adjusted_t );
|
||||
}
|
||||
|
||||
return tex;
|
||||
}
|
||||
45
simgear/misc/texcoord.hxx
Normal file
45
simgear/misc/texcoord.hxx
Normal file
@@ -0,0 +1,45 @@
|
||||
// texcoord.hxx -- routine(s) to handle texture coordinate generation
|
||||
//
|
||||
// Written by Curtis Olson, started March 1999.
|
||||
//
|
||||
// Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#ifndef _TEXCOORD_HXX
|
||||
#define _TEXCOORD_HXX
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
|
||||
#include <simgear/bucket/newbucket.hxx>
|
||||
#include <simgear/math/fg_types.hxx>
|
||||
|
||||
|
||||
// traverse the specified fan/strip/list of vertices and attempt to
|
||||
// calculate "none stretching" texture coordinates
|
||||
point_list calc_tex_coords( const FGBucket& b, const point_list& geod_nodes,
|
||||
const int_list& fan, double scale = 1.0 );
|
||||
|
||||
|
||||
#endif // _TEXCOORD_HXX
|
||||
|
||||
|
||||
313
simgear/misc/zfstream.cxx
Normal file
313
simgear/misc/zfstream.cxx
Normal file
@@ -0,0 +1,313 @@
|
||||
// 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>
|
||||
//
|
||||
// Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
#include <memory.h>
|
||||
#include "zfstream.hxx"
|
||||
|
||||
//
|
||||
// Construct a gzfilebuf object.
|
||||
// Allocate memory for 'get' buffer and zero all buffer pointers.
|
||||
//
|
||||
gzfilebuf::gzfilebuf()
|
||||
: streambuf(),
|
||||
file(NULL),
|
||||
#if defined( __MWERKS__ )
|
||||
mode(ios_openmode(0)),
|
||||
#else
|
||||
mode(0),
|
||||
#endif
|
||||
own_file_descriptor(false),
|
||||
ibuf_size(0),
|
||||
ibuffer(0)
|
||||
{
|
||||
// try {
|
||||
ibuf_size = page_size / sizeof(char);
|
||||
ibuffer = new char [ibuf_size];
|
||||
// } catch (...) {
|
||||
// delete [] ibuffer;
|
||||
// }
|
||||
|
||||
// Null get and set pointers.
|
||||
this->setg(0,0,0);
|
||||
this->setp(0,0);
|
||||
}
|
||||
|
||||
gzfilebuf::~gzfilebuf()
|
||||
{
|
||||
sync();
|
||||
if ( own_file_descriptor )
|
||||
this->close();
|
||||
delete [] ibuffer;
|
||||
}
|
||||
|
||||
void
|
||||
gzfilebuf::cvt_iomode( char* p, ios_openmode io_mode )
|
||||
{
|
||||
// memset( char_mode, '\0', 10 );
|
||||
// char* p = char_mode;
|
||||
|
||||
if ( io_mode & ios_in )
|
||||
{
|
||||
mode = ios_in;
|
||||
*p++ = 'r';
|
||||
}
|
||||
else if ( io_mode & ios_app )
|
||||
{
|
||||
mode = ios_app;
|
||||
*p++ = 'a';
|
||||
}
|
||||
else
|
||||
{
|
||||
mode = ios_out;
|
||||
*p++ = 'w';
|
||||
}
|
||||
|
||||
if ( io_mode & ios_binary )
|
||||
{
|
||||
mode |= ios_binary;
|
||||
*p++ = 'b';
|
||||
}
|
||||
|
||||
// Hard code the compression level
|
||||
if ( io_mode & (ios_out | ios_app) )
|
||||
{
|
||||
*p++ = '9';
|
||||
}
|
||||
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
gzfilebuf*
|
||||
gzfilebuf::open( const char *name, ios_openmode io_mode )
|
||||
{
|
||||
if ( is_open() )
|
||||
return NULL;
|
||||
|
||||
char char_mode[10];
|
||||
cvt_iomode( char_mode, io_mode );
|
||||
if ( (file = gzopen(name, char_mode)) == NULL )
|
||||
return NULL;
|
||||
|
||||
own_file_descriptor = true;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
gzfilebuf*
|
||||
gzfilebuf::attach( int file_descriptor, ios_openmode io_mode )
|
||||
{
|
||||
if ( is_open() )
|
||||
return NULL;
|
||||
|
||||
char char_mode[10];
|
||||
cvt_iomode( char_mode, io_mode );
|
||||
if ( (file = gzdopen(file_descriptor, char_mode)) == NULL )
|
||||
return NULL;
|
||||
|
||||
own_file_descriptor = false;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
gzfilebuf*
|
||||
gzfilebuf::close()
|
||||
{
|
||||
if ( is_open() )
|
||||
{
|
||||
sync();
|
||||
gzclose( file );
|
||||
file = NULL;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
// int
|
||||
// gzfilebuf::setcompressionlevel( int comp_level )
|
||||
// {
|
||||
// return gzsetparams(file, comp_level, -2);
|
||||
// }
|
||||
|
||||
// int
|
||||
// gzfilebuf::setcompressionstrategy( int comp_strategy )
|
||||
// {
|
||||
// return gzsetparams(file, -2, comp_strategy);
|
||||
// }
|
||||
|
||||
|
||||
streampos
|
||||
gzfilebuf::seekoff( streamoff, ios_seekdir, int )
|
||||
{
|
||||
return streampos(EOF);
|
||||
}
|
||||
|
||||
gzfilebuf::int_type
|
||||
gzfilebuf::overflow( int_type )
|
||||
{
|
||||
#if 0
|
||||
if ( !is_open() || !(mode & ios::out) )
|
||||
return EOF;
|
||||
|
||||
if ( !base() )
|
||||
{
|
||||
if ( allocate() == EOF )
|
||||
return EOF;
|
||||
setg(0,0,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (in_avail())
|
||||
{
|
||||
return EOF;
|
||||
}
|
||||
|
||||
if (out_waiting())
|
||||
{
|
||||
if (flushbuf() == EOF)
|
||||
return EOF;
|
||||
}
|
||||
}
|
||||
|
||||
int bl = blen();
|
||||
setp( base(), base() + bl);
|
||||
|
||||
if ( c != EOF )
|
||||
{
|
||||
*pptr() = c;
|
||||
pbump(1);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
gzfilebuf::sync()
|
||||
{
|
||||
if ( !is_open() )
|
||||
return EOF;
|
||||
|
||||
if ( pptr() != 0 && pptr() > pbase() )
|
||||
return flushbuf();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
gzfilebuf::int_type
|
||||
gzfilebuf::flushbuf()
|
||||
{
|
||||
char* q = pbase();
|
||||
int n = pptr() - q;
|
||||
|
||||
if ( gzwrite( file, q, n) < n )
|
||||
return traits_type::eof();
|
||||
|
||||
setp(0,0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
gzfilebuf::int_type
|
||||
gzfilebuf::underflow()
|
||||
{
|
||||
// cerr << "gzfilebuf::underflow(): gptr()=" << (void*)gptr() << endl;
|
||||
// Error if the file not open for reading.
|
||||
if ( !is_open() || !(mode & ios_in) )
|
||||
return traits_type::eof();
|
||||
|
||||
// If the input buffer is empty then try to fill it.
|
||||
if ( gptr() != 0 && gptr() < egptr() )
|
||||
{
|
||||
return int_type(*gptr());
|
||||
}
|
||||
else
|
||||
{
|
||||
return fillbuf() == EOF ? traits_type::eof() : int_type(*gptr());
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Load the input buffer from the underlying gz file.
|
||||
// Returns number of characters read, or EOF.
|
||||
//
|
||||
int
|
||||
gzfilebuf::fillbuf()
|
||||
{
|
||||
int t = gzread( file, ibuffer, ibuf_size );
|
||||
if ( t <= 0)
|
||||
{
|
||||
// disable get area
|
||||
setg(0,0,0);
|
||||
return EOF;
|
||||
}
|
||||
|
||||
// Set the input (get) pointers
|
||||
setg( ibuffer, ibuffer, ibuffer+t );
|
||||
|
||||
// cerr << "gzfilebuf::fillbuf():"
|
||||
// << " t=" << t
|
||||
// << ", ibuffer=" << (void*)ibuffer
|
||||
// << ", ibuffer+t=" << (void*)(ibuffer+t) << endl;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
#if 0
|
||||
gzifstream::gzifstream()
|
||||
: istream(&buffer), buffer()
|
||||
{
|
||||
clear( ios_badbit );
|
||||
}
|
||||
|
||||
gzifstream::gzifstream( const char *name, ios_openmode io_mode )
|
||||
: istream(&buffer), buffer()
|
||||
{
|
||||
this->open( name, io_mode );
|
||||
}
|
||||
|
||||
gzifstream::gzifstream( int fd, ios_openmode io_mode )
|
||||
: istream(&buffer), buffer()
|
||||
{
|
||||
buffer.attach( fd, io_mode );
|
||||
}
|
||||
|
||||
gzifstream::~gzifstream()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
gzifstream::open( const char *name, ios_openmode io_mode )
|
||||
{
|
||||
if ( !buffer.open( name, io_mode ) )
|
||||
clear( ios_failbit | ios_badbit );
|
||||
else
|
||||
clear();
|
||||
}
|
||||
|
||||
void
|
||||
gzifstream::close()
|
||||
{
|
||||
if ( !buffer.close() )
|
||||
clear( ios_failbit | ios_badbit );
|
||||
}
|
||||
#endif
|
||||
|
||||
155
simgear/misc/zfstream.hxx
Normal file
155
simgear/misc/zfstream.hxx
Normal file
@@ -0,0 +1,155 @@
|
||||
// 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>
|
||||
//
|
||||
// Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
#ifndef _zfstream_hxx
|
||||
#define _zfstream_hxx
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
#ifdef FG_HAVE_STD_INCLUDES
|
||||
|
||||
# include <streambuf>
|
||||
# include <istream>
|
||||
|
||||
# define ios_openmode ios_base::openmode
|
||||
# define ios_in ios_base::in
|
||||
# define ios_out ios_base::out
|
||||
# define ios_app ios_base::app
|
||||
# define ios_binary ios_base::binary
|
||||
|
||||
# define ios_seekdir ios_base::seekdir
|
||||
|
||||
# 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);
|
||||
|
||||
#else
|
||||
|
||||
# ifdef FG_HAVE_STREAMBUF
|
||||
# include <streambuf.h>
|
||||
# include <istream.h>
|
||||
# else
|
||||
# include <iostream.h>
|
||||
# endif
|
||||
|
||||
//# define ios_openmode ios::open_mode
|
||||
# define ios_openmode int
|
||||
# define ios_in ios::in
|
||||
# define ios_out ios::out
|
||||
# define ios_app ios::app
|
||||
|
||||
#if defined(__GNUC__) && __GNUC_MINOR__ < 8
|
||||
# define ios_binary ios::bin
|
||||
#elif defined( FG_HAVE_NATIVE_SGI_COMPILERS )
|
||||
# define ios_binary 0
|
||||
#else
|
||||
# define ios_binary ios::binary
|
||||
#endif
|
||||
|
||||
# define ios_seekdir ios::seek_dir
|
||||
|
||||
# define ios_badbit ios::badbit
|
||||
# define ios_failbit ios::failbit
|
||||
|
||||
# include <simgear/fg_traits.hxx>
|
||||
|
||||
#endif // FG_HAVE_STD_INCLUDES
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
class gzfilebuf : public streambuf
|
||||
{
|
||||
public:
|
||||
|
||||
#ifndef FG_HAVE_STD_INCLUDES
|
||||
typedef char_traits<char> traits_type;
|
||||
typedef char_traits<char>::int_type int_type;
|
||||
typedef char_traits<char>::pos_type pos_type;
|
||||
typedef char_traits<char>::off_type off_type;
|
||||
#endif
|
||||
|
||||
gzfilebuf();
|
||||
virtual ~gzfilebuf();
|
||||
|
||||
gzfilebuf* open( const char* name, ios_openmode io_mode );
|
||||
gzfilebuf* attach( int file_descriptor, ios_openmode io_mode );
|
||||
gzfilebuf* close();
|
||||
|
||||
// int setcompressionlevel( int comp_level );
|
||||
// int setcompressionstrategy( int comp_strategy );
|
||||
bool is_open() const { return (file != NULL); }
|
||||
virtual streampos seekoff( streamoff off, ios_seekdir way, int which );
|
||||
virtual int sync();
|
||||
|
||||
protected:
|
||||
|
||||
virtual int_type underflow();
|
||||
virtual int_type overflow( int_type c = traits_type::eof() );
|
||||
|
||||
private:
|
||||
|
||||
int_type flushbuf();
|
||||
int fillbuf();
|
||||
|
||||
// Convert io_mode to "rwab" string.
|
||||
void cvt_iomode( char* mode_str, ios_openmode io_mode );
|
||||
|
||||
private:
|
||||
|
||||
gzFile file;
|
||||
ios_openmode mode;
|
||||
bool own_file_descriptor;
|
||||
|
||||
// Get (input) buffer.
|
||||
int ibuf_size;
|
||||
char* ibuffer;
|
||||
|
||||
enum { page_size = 4096 };
|
||||
|
||||
private:
|
||||
// Not defined
|
||||
gzfilebuf( const gzfilebuf& );
|
||||
void operator= ( const gzfilebuf& );
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
struct gzifstream_base
|
||||
{
|
||||
gzifstream_base() {}
|
||||
|
||||
gzfilebuf gzbuf;
|
||||
};
|
||||
|
||||
#endif // _zfstream_hxx
|
||||
|
||||
82
simgear/screen/GLBitmaps.cxx
Executable file
82
simgear/screen/GLBitmaps.cxx
Executable file
@@ -0,0 +1,82 @@
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <GL/glut.h>
|
||||
#include <simgear/xgl/xgl.h>
|
||||
|
||||
#include "GLBitmaps.h"
|
||||
|
||||
GlBitmap::GlBitmap( GLenum mode, GLint width, GLint height, GLubyte *bitmap )
|
||||
: m_bytesPerPixel(mode==GL_RGB?3:4), m_width(width), m_height(height), m_bitmap(NULL)
|
||||
{
|
||||
m_bitmapSize = m_bytesPerPixel*m_width*m_height;
|
||||
if ( !m_bitmapSize )
|
||||
{
|
||||
GLint vp[4];
|
||||
glGetIntegerv( GL_VIEWPORT, vp );
|
||||
m_width = vp[2];
|
||||
m_height = vp[3];
|
||||
m_bitmapSize = m_bytesPerPixel*m_width*m_height;
|
||||
}
|
||||
m_bitmap = (GLubyte *)malloc( m_bitmapSize );
|
||||
if ( bitmap ) memcpy( m_bitmap, bitmap, m_bitmapSize );
|
||||
else glReadPixels( 0,0, m_width,m_height, mode, GL_UNSIGNED_BYTE, m_bitmap );
|
||||
}
|
||||
|
||||
GlBitmap::~GlBitmap( )
|
||||
{
|
||||
if ( m_bitmap ) free( m_bitmap );
|
||||
}
|
||||
|
||||
GLubyte *GlBitmap::getBitmap()
|
||||
{
|
||||
return m_bitmap;
|
||||
}
|
||||
|
||||
void GlBitmap::copyBitmap( GlBitmap *from, GLint at_x, GLint at_y )
|
||||
{
|
||||
GLint newWidth = at_x + from->m_width;
|
||||
GLint newHeight = at_y + from->m_height;
|
||||
if ( newWidth < m_width ) newWidth = m_width;
|
||||
if ( newHeight < m_height ) newHeight = m_height;
|
||||
m_bitmapSize = m_bytesPerPixel*newWidth*newHeight;
|
||||
GLubyte *newBitmap = (GLubyte *)malloc( m_bitmapSize );
|
||||
GLint x,y;
|
||||
for ( y=0; y<m_height; y++ )
|
||||
{
|
||||
GLubyte *s = m_bitmap + m_bytesPerPixel * (y * m_width);
|
||||
GLubyte *d = newBitmap + m_bytesPerPixel * (y * newWidth);
|
||||
memcpy( d, s, m_bytesPerPixel * m_width );
|
||||
}
|
||||
m_width = newWidth;
|
||||
m_height = newHeight;
|
||||
free( m_bitmap );
|
||||
m_bitmap = newBitmap;
|
||||
for ( y=0; y<from->m_height; y++ )
|
||||
{
|
||||
GLubyte *s = from->m_bitmap + from->m_bytesPerPixel * (y * from->m_width);
|
||||
GLubyte *d = m_bitmap + m_bytesPerPixel * ((at_y+y) * m_width + at_x);
|
||||
for ( x=0; x<from->m_width; x++ )
|
||||
{
|
||||
d[0] = s[0];
|
||||
d[1] = s[1];
|
||||
d[2] = s[2];
|
||||
if ( m_bytesPerPixel == 4 )
|
||||
{
|
||||
d[3] = (from->m_bytesPerPixel == 4) ? s[3] : 0;
|
||||
}
|
||||
s += from->m_bytesPerPixel;
|
||||
d += m_bytesPerPixel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
14
simgear/screen/GLBitmaps.h
Executable file
14
simgear/screen/GLBitmaps.h
Executable file
@@ -0,0 +1,14 @@
|
||||
class GlBitmap
|
||||
{
|
||||
public:
|
||||
GlBitmap( GLenum mode=GL_RGB, GLint width=0, GLint height=0, GLubyte *bitmap=0 );
|
||||
~GlBitmap();
|
||||
GLubyte *getBitmap();
|
||||
void copyBitmap( GlBitmap *from, GLint at_x, GLint at_y );
|
||||
private:
|
||||
GLint m_bytesPerPixel;
|
||||
GLint m_width;
|
||||
GLint m_height;
|
||||
GLint m_bitmapSize;
|
||||
GLubyte *m_bitmap;
|
||||
};
|
||||
12
simgear/screen/Makefile.am
Normal file
12
simgear/screen/Makefile.am
Normal file
@@ -0,0 +1,12 @@
|
||||
includedir = @includedir@/screen
|
||||
|
||||
lib_LIBRARIES = libsgscreen.a
|
||||
|
||||
include_HEADERS = screen-dump.hxx
|
||||
|
||||
libsgscreen_a_SOURCES = \
|
||||
GLBitmaps.cxx GLBitmaps.h \
|
||||
screen-dump.cxx \
|
||||
win32-printer.h
|
||||
|
||||
INCLUDES += -I$(top_builddir)/src
|
||||
83
simgear/screen/screen-dump.cxx
Normal file
83
simgear/screen/screen-dump.cxx
Normal file
@@ -0,0 +1,83 @@
|
||||
// screen-dump.cxx -- dump a copy of the opengl screen buffer to a file
|
||||
//
|
||||
// Contributed by Richard Kaszeta <bofh@me.umn.edu>, started October 1999.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <GL/glut.h>
|
||||
#include <simgear/xgl/xgl.h>
|
||||
|
||||
#include "screen-dump.hxx"
|
||||
|
||||
|
||||
#define RGB 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)
|
||||
{
|
||||
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);
|
||||
|
||||
fp = fopen(filename, "wb");
|
||||
fprintf(fp, "P6\n# CREATOR: glReadPixel()\n%d %d\n%d\n",
|
||||
win_width, win_height, UCHAR_MAX);
|
||||
q = 0;
|
||||
for (i = 0; i < win_height; i++)
|
||||
for (j = 0; j < win_width; j++)
|
||||
for (k = 0; k < RGB; k++)
|
||||
ibuffer[q++] = (unsigned char)
|
||||
*(buffer + (pixelSize*((win_height-1-i)*win_width+j)+k));
|
||||
fwrite(ibuffer, sizeof(unsigned char), RGB*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);
|
||||
}
|
||||
|
||||
|
||||
// dump the screen buffer to a ppm file
|
||||
void my_glDumpWindow(const char *filename, int win_width, int win_height) {
|
||||
GLubyte *buffer;
|
||||
|
||||
buffer = (GLubyte *) malloc(win_width*win_height*RGBA);
|
||||
|
||||
// read window contents from color buffer with glReadPixels
|
||||
glFinish();
|
||||
glReadPixels(0, 0, win_width, win_height,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, buffer);
|
||||
my_glWritePPMFile( filename, buffer, win_width, win_height, GL_RGBA );
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
26
simgear/screen/screen-dump.hxx
Normal file
26
simgear/screen/screen-dump.hxx
Normal file
@@ -0,0 +1,26 @@
|
||||
// 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 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$
|
||||
|
||||
|
||||
// dump the screen buffer to a ppm file
|
||||
void my_glDumpWindow( const char *filename, int win_width, int win_height );
|
||||
|
||||
void my_glWritePPMFile( const char *filename, GLubyte *buffer, int win_width,
|
||||
int win_height, int mode);
|
||||
325
simgear/screen/win32-printer.h
Normal file
325
simgear/screen/win32-printer.h
Normal file
@@ -0,0 +1,325 @@
|
||||
|
||||
class CGlPrinter
|
||||
{
|
||||
public:
|
||||
typedef enum { RENDER_TO_PRINTER, RENDER_TO_BITMAP, READ_BITMAP, PRINT_BITMAP } PRINTMODE;
|
||||
public:
|
||||
inline CGlPrinter( PRINTMODE mode = READ_BITMAP );
|
||||
inline ~CGlPrinter();
|
||||
inline bool Begin( char *title, int w=0, int h=0 );
|
||||
inline void End( GLubyte *bm=NULL );
|
||||
inline double GetAspect();
|
||||
inline int GetHorzRes();
|
||||
inline int GetVertRes();
|
||||
|
||||
private:
|
||||
PRINTMODE m_printMode;
|
||||
PRINTDLG m_printDLG;
|
||||
BITMAPINFO m_bitmapInfo;
|
||||
void *m_bitmap;
|
||||
HBITMAP bitmapHandle;
|
||||
HDC m_bitmapDC;
|
||||
HGLRC m_printerHGLRC;
|
||||
HGLRC m_bitmapHGLRC;
|
||||
int m_pageWidth; // Dimension of printer page (x)
|
||||
int m_pageHeight; // Dimension of printer page (y)
|
||||
};
|
||||
|
||||
inline double CGlPrinter::GetAspect()
|
||||
{
|
||||
return (double)m_pageWidth/(double)m_pageHeight;
|
||||
}
|
||||
|
||||
inline int CGlPrinter::GetHorzRes()
|
||||
{
|
||||
return m_pageWidth;
|
||||
}
|
||||
|
||||
inline int CGlPrinter::GetVertRes()
|
||||
{
|
||||
return m_pageHeight;
|
||||
}
|
||||
|
||||
inline CGlPrinter::CGlPrinter( PRINTMODE mode ) :
|
||||
m_printerHGLRC( 0 ), m_bitmapHGLRC( 0 ), m_printMode( mode ), m_bitmap( NULL )
|
||||
{
|
||||
}
|
||||
|
||||
inline CGlPrinter::~CGlPrinter()
|
||||
{
|
||||
}
|
||||
|
||||
inline bool CGlPrinter::Begin( char *title, int w, int h )
|
||||
{
|
||||
// Pixel format for Printer Device context
|
||||
static PIXELFORMATDESCRIPTOR pPrintfd = {
|
||||
sizeof(PIXELFORMATDESCRIPTOR), // Size of this structure
|
||||
1, // Version of this structure
|
||||
PFD_DRAW_TO_WINDOW | // Draw to Window (not to m_bitmap)
|
||||
PFD_SUPPORT_OPENGL | // Support OpenGL calls
|
||||
PFD_SUPPORT_GDI | // Allow GDI drawing in window too
|
||||
PFD_DEPTH_DONTCARE, // Don't care about depth buffering
|
||||
PFD_TYPE_RGBA, // RGBA Color mode
|
||||
24, // Want 24bit color
|
||||
0,0,0,0,0,0, // Not used to select mode
|
||||
0,0, // Not used to select mode
|
||||
0,0,0,0,0, // Not used to select mode
|
||||
0, // Size of depth buffer
|
||||
0, // Not used to select mode
|
||||
0, // Not used to select mode
|
||||
0, // Not used to select mode
|
||||
0, // Not used to select mode
|
||||
0,0,0 }; // Not used to select mode
|
||||
|
||||
DOCINFO docInfo; // Document Info
|
||||
int nPixelFormat; // Pixel format requested
|
||||
|
||||
// Get printer information
|
||||
memset(&m_printDLG,0,sizeof(PRINTDLG));
|
||||
m_printDLG.lStructSize = sizeof(PRINTDLG);
|
||||
m_printDLG.hwndOwner = GetForegroundWindow();
|
||||
m_printDLG.hDevMode = NULL;
|
||||
m_printDLG.hDevNames = NULL;
|
||||
m_printDLG.Flags = PD_RETURNDC | PD_ALLPAGES;
|
||||
|
||||
// Display printer dialog
|
||||
if(!PrintDlg(&m_printDLG))
|
||||
{
|
||||
printf( "PrintDlg() failed %lx\n", GetLastError() );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the dimensions of the page
|
||||
m_pageWidth = GetDeviceCaps(m_printDLG.hDC, HORZRES);
|
||||
m_pageHeight = GetDeviceCaps(m_printDLG.hDC, VERTRES);
|
||||
|
||||
// Initialize DocInfo structure
|
||||
docInfo.cbSize = sizeof(DOCINFO);
|
||||
docInfo.lpszDocName = title;
|
||||
docInfo.lpszOutput = NULL;
|
||||
|
||||
|
||||
// Choose a pixel format that best matches that described in pfd
|
||||
nPixelFormat = ChoosePixelFormat(m_printDLG.hDC, &pPrintfd);
|
||||
// Watch for no pixel format available for this printer
|
||||
if(nPixelFormat == 0)
|
||||
{
|
||||
// Delete the printer context
|
||||
DeleteDC(m_printDLG.hDC);
|
||||
|
||||
printf( "ChoosePixelFormat() failed %lx\n", GetLastError() );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Start the document and page
|
||||
StartDoc(m_printDLG.hDC, &docInfo);
|
||||
StartPage(m_printDLG.hDC);
|
||||
|
||||
// Set the pixel format for the device context, but watch for failure
|
||||
if(!SetPixelFormat(m_printDLG.hDC, nPixelFormat, &pPrintfd))
|
||||
{
|
||||
// Delete the printer context
|
||||
DeleteDC(m_printDLG.hDC);
|
||||
|
||||
printf( "SetPixelFormat() failed %lx\n", GetLastError() );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create the Rendering context and make it current
|
||||
if ( m_printMode == RENDER_TO_PRINTER )
|
||||
{
|
||||
m_printerHGLRC = wglCreateContext(m_printDLG.hDC);
|
||||
wglMakeCurrent(m_printDLG.hDC, m_printerHGLRC);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset( &m_bitmapInfo, 0, sizeof(BITMAPINFO) );
|
||||
m_bitmapInfo.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
|
||||
if ( m_printMode == READ_BITMAP )
|
||||
{
|
||||
GLint vp[4];
|
||||
glGetIntegerv( GL_VIEWPORT, vp );
|
||||
m_bitmapInfo.bmiHeader.biWidth = vp[2];
|
||||
m_bitmapInfo.bmiHeader.biHeight = (vp[3] + 3) & ~3;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( m_printMode == RENDER_TO_BITMAP )
|
||||
{
|
||||
m_bitmapInfo.bmiHeader.biWidth = m_pageWidth;
|
||||
m_bitmapInfo.bmiHeader.biHeight = m_pageHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
// PRINT_BITMAP
|
||||
m_bitmapInfo.bmiHeader.biWidth = w;
|
||||
m_bitmapInfo.bmiHeader.biHeight = h;
|
||||
}
|
||||
}
|
||||
m_bitmapInfo.bmiHeader.biPlanes = 1;
|
||||
m_bitmapInfo.bmiHeader.biBitCount = 24;
|
||||
m_bitmapInfo.bmiHeader.biCompression = BI_RGB;
|
||||
m_bitmapInfo.bmiHeader.biSizeImage = m_bitmapInfo.bmiHeader.biWidth*m_bitmapInfo.bmiHeader.biHeight*3;
|
||||
m_bitmapInfo.bmiHeader.biXPelsPerMeter = 2952; // 75dpi
|
||||
m_bitmapInfo.bmiHeader.biYPelsPerMeter = 2952; // 75dpi
|
||||
m_bitmapInfo.bmiHeader.biClrUsed = 0;
|
||||
m_bitmapInfo.bmiHeader.biClrImportant = 0;
|
||||
bitmapHandle = CreateDIBSection( NULL, &m_bitmapInfo, DIB_RGB_COLORS, &m_bitmap, NULL, 0);
|
||||
m_bitmapDC = CreateCompatibleDC( NULL );
|
||||
if ( m_bitmapDC == NULL )
|
||||
{
|
||||
DeleteDC(m_printDLG.hDC);
|
||||
printf( "CreateCompatibleDC() failed %lx\n", GetLastError() );
|
||||
return false;
|
||||
}
|
||||
if ( SelectObject( m_bitmapDC, bitmapHandle ) == NULL )
|
||||
{
|
||||
DeleteDC(m_printDLG.hDC);
|
||||
DeleteDC(m_bitmapDC);
|
||||
printf( "SelectObject() failed %lx\n", GetLastError() );
|
||||
return false;
|
||||
}
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
memset( &pfd, 0, sizeof(PIXELFORMATDESCRIPTOR) );
|
||||
pfd.nVersion = 1 ;
|
||||
pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL;
|
||||
pfd.iPixelType = PFD_TYPE_RGBA ;
|
||||
pfd.cColorBits = 24;
|
||||
pfd.iLayerType = PFD_MAIN_PLANE;
|
||||
int pixelFormat = ::ChoosePixelFormat(m_bitmapDC, &pfd);
|
||||
SetPixelFormat (m_bitmapDC, pixelFormat, &pfd);
|
||||
if ( m_printMode == RENDER_TO_BITMAP )
|
||||
{
|
||||
m_bitmapHGLRC = wglCreateContext( m_bitmapDC );
|
||||
wglMakeCurrent( m_bitmapDC, m_bitmapHGLRC );
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_printMode == RENDER_TO_PRINTER || m_printMode == RENDER_TO_BITMAP )
|
||||
{
|
||||
// Set viewing volume info
|
||||
//glViewport(0,0,m_pageWidth/2,m_pageHeight/2); // Put this in to restrict area of page.
|
||||
|
||||
GLfloat nRange = 100.0f;
|
||||
|
||||
// Reset projection matrix stack
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
|
||||
// Establish clipping volume (left, right, bottom, top, near, far)
|
||||
// This keeps the perspective square regardless of window or page size
|
||||
|
||||
if (m_pageHeight <= m_pageWidth)
|
||||
{
|
||||
glOrtho (-nRange, nRange, -nRange*m_pageHeight/m_pageWidth, nRange*m_pageHeight/m_pageWidth, -nRange, nRange);
|
||||
}
|
||||
else
|
||||
{
|
||||
glOrtho (-nRange*m_pageWidth/m_pageHeight, nRange*m_pageWidth/m_pageHeight, -nRange, nRange, -nRange, nRange);
|
||||
}
|
||||
|
||||
// Reset Model view matrix stack
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glRotatef(270.0f, 1.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void CGlPrinter::End( GLubyte *bm )
|
||||
{
|
||||
if ( m_printDLG.hDC )
|
||||
{
|
||||
glFinish();
|
||||
|
||||
if ( m_printMode == RENDER_TO_PRINTER )
|
||||
{
|
||||
if ( m_printerHGLRC )
|
||||
{
|
||||
wglDeleteContext( m_printerHGLRC );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( m_printMode == RENDER_TO_BITMAP )
|
||||
{
|
||||
BitBlt( m_printDLG.hDC, 0,0, m_pageWidth,m_pageHeight, m_bitmapDC, 0,0, SRCCOPY );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( m_printMode == READ_BITMAP )
|
||||
{
|
||||
glPixelStorei( GL_PACK_ALIGNMENT, 4 );
|
||||
glPixelStorei( GL_PACK_ROW_LENGTH, 0 );
|
||||
glPixelStorei( GL_PACK_SKIP_ROWS, 0 );
|
||||
glPixelStorei( GL_PACK_SKIP_PIXELS, 0 );
|
||||
//GLubyte *tempbitmap = (GLubyte *) malloc(m_bitmapInfo.bmiHeader.biWidth*m_bitmapInfo.bmiHeader.biHeight*4);
|
||||
glReadPixels( 0,0, m_bitmapInfo.bmiHeader.biWidth,m_bitmapInfo.bmiHeader.biHeight,
|
||||
GL_RGB, GL_UNSIGNED_BYTE, m_bitmap );
|
||||
}
|
||||
else
|
||||
{
|
||||
//PRINT_BITMAP
|
||||
memcpy( m_bitmap, bm, m_bitmapInfo.bmiHeader.biSizeImage );
|
||||
}
|
||||
int i,j;
|
||||
GLubyte *rgb, temp;
|
||||
for ( i = 0; i < m_bitmapInfo.bmiHeader.biHeight; i++ )
|
||||
{
|
||||
for ( j = 0, rgb = ((GLubyte *)m_bitmap) + i * m_bitmapInfo.bmiHeader.biWidth * 3;
|
||||
j < m_bitmapInfo.bmiHeader.biWidth;
|
||||
j++, rgb +=3 )
|
||||
{
|
||||
temp = rgb[0];
|
||||
rgb[0] = rgb[2];
|
||||
rgb[2] = temp;
|
||||
}
|
||||
}
|
||||
long width = m_pageWidth;
|
||||
long height = width * m_bitmapInfo.bmiHeader.biHeight / m_bitmapInfo.bmiHeader.biWidth;
|
||||
if ( height > m_pageHeight )
|
||||
{
|
||||
height = m_pageHeight;
|
||||
width = height * m_bitmapInfo.bmiHeader.biWidth / m_bitmapInfo.bmiHeader.biHeight;
|
||||
}
|
||||
long xoffset = (m_pageWidth - width) / 2;
|
||||
long yoffset = (m_pageHeight - height) / 2;
|
||||
StretchBlt( m_printDLG.hDC, xoffset, yoffset, width, height, m_bitmapDC, 0, 0,
|
||||
m_bitmapInfo.bmiHeader.biWidth, m_bitmapInfo.bmiHeader.biHeight, SRCCOPY );
|
||||
}
|
||||
if ( m_bitmapDC )
|
||||
{
|
||||
DeleteDC( m_bitmapDC );
|
||||
}
|
||||
if ( bitmapHandle )
|
||||
{
|
||||
DeleteObject( bitmapHandle );
|
||||
}
|
||||
if ( m_bitmapHGLRC )
|
||||
{
|
||||
wglDeleteContext( m_bitmapHGLRC );
|
||||
}
|
||||
}
|
||||
|
||||
/* EndPage... */
|
||||
if ( EndPage( m_printDLG.hDC ) <=0 )
|
||||
{
|
||||
printf( "EndPage() failed\n" );
|
||||
}
|
||||
|
||||
/* EndDoc... */
|
||||
if ( EndDoc( m_printDLG.hDC ) <=0 )
|
||||
{
|
||||
printf( "EndDoc() failed\n" );
|
||||
}
|
||||
|
||||
// Delete the printer context when done with it
|
||||
DeleteDC(m_printDLG.hDC);
|
||||
|
||||
// Restore window rendering context
|
||||
//wglMakeCurrent(hDC, hRC);
|
||||
wglMakeCurrent( NULL, NULL );
|
||||
|
||||
}
|
||||
}
|
||||
17
simgear/serial/Makefile.am
Normal file
17
simgear/serial/Makefile.am
Normal file
@@ -0,0 +1,17 @@
|
||||
includedir = @includedir@/serial
|
||||
|
||||
noinst_PROGRAMS = testserial
|
||||
|
||||
lib_LIBRARIES = libsgserial.a
|
||||
|
||||
include_HEADERS = serial.hxx
|
||||
|
||||
libsgserial_a_SOURCES = serial.cxx
|
||||
|
||||
testserial_SOURCES = testserial.cxx
|
||||
|
||||
testserial_LDADD = \
|
||||
$(top_builddir)/src/serial/libsgserial.a \
|
||||
$(top_builddir)/src/debug/libsgdebug.a
|
||||
|
||||
INCLUDES += -I$(top_builddir)/src
|
||||
446
simgear/serial/serial.cxx
Normal file
446
simgear/serial/serial.cxx
Normal file
@@ -0,0 +1,446 @@
|
||||
// serial.cxx -- Unix serial I/O support
|
||||
//
|
||||
// Written by Curtis Olson, started November 1998.
|
||||
//
|
||||
// Copyright (C) 1998 Curtis L. Olson - curt@flightgear.org
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#ifdef FG_HAVE_STD_INCLUDE
|
||||
# include <cerrno>
|
||||
#else
|
||||
# include <errno.h>
|
||||
#endif
|
||||
|
||||
#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ )
|
||||
// maybe include something???
|
||||
#else
|
||||
# include <termios.h>
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
# include <fcntl.h>
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#include "serial.hxx"
|
||||
|
||||
|
||||
FGSerialPort::FGSerialPort()
|
||||
: dev_open(false)
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
||||
FGSerialPort::FGSerialPort(const string& device, int baud) {
|
||||
open_port(device);
|
||||
|
||||
if ( dev_open ) {
|
||||
set_baud(baud);
|
||||
}
|
||||
}
|
||||
|
||||
FGSerialPort::~FGSerialPort() {
|
||||
// closing the port here screws us up because if we would even so
|
||||
// much as make a copy of an FGSerialPort object and then delete it,
|
||||
// the file descriptor gets closed. Doh!!!
|
||||
}
|
||||
|
||||
bool FGSerialPort::open_port(const string& device) {
|
||||
|
||||
#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ )
|
||||
|
||||
fd = CreateFile( device.c_str(),
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
0, // dwShareMode
|
||||
NULL, // lpSecurityAttributes
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_OVERLAPPED,
|
||||
NULL );
|
||||
if ( fd == INVALID_HANDLE_VALUE )
|
||||
{
|
||||
LPVOID lpMsgBuf;
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
GetLastError(),
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||||
(LPTSTR) &lpMsgBuf,
|
||||
0,
|
||||
NULL );
|
||||
|
||||
FG_LOG( FG_IO, FG_ALERT, "Error opening serial device \""
|
||||
<< device << "\" " << (const char*) lpMsgBuf );
|
||||
LocalFree( lpMsgBuf );
|
||||
return false;
|
||||
}
|
||||
|
||||
dev_open = true;
|
||||
return true;
|
||||
|
||||
#else
|
||||
|
||||
struct termios config;
|
||||
|
||||
fd = open(device.c_str(), O_RDWR | O_NONBLOCK);
|
||||
cout << "Serial fd created = " << fd << endl;
|
||||
|
||||
if ( fd == -1 ) {
|
||||
FG_LOG( FG_IO, FG_ALERT, "Cannot open " << device
|
||||
<< " for serial I/O" );
|
||||
return false;
|
||||
} else {
|
||||
dev_open = true;
|
||||
}
|
||||
|
||||
// set required port parameters
|
||||
if ( tcgetattr( fd, &config ) != 0 ) {
|
||||
FG_LOG( FG_IO, FG_ALERT, "Unable to poll port settings" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// cfmakeraw( &config );
|
||||
|
||||
// cout << "config.c_iflag = " << config.c_iflag << endl;
|
||||
|
||||
// software flow control on
|
||||
config.c_iflag |= IXON;
|
||||
// config.c_iflag |= IXOFF;
|
||||
|
||||
// config.c_cflag |= CLOCAL;
|
||||
|
||||
#if ! defined( sgi )
|
||||
// disable hardware flow control
|
||||
config.c_cflag &= ~(CRTSCTS);
|
||||
#endif
|
||||
|
||||
// cout << "config.c_iflag = " << config.c_iflag << endl;
|
||||
|
||||
if ( tcsetattr( fd, TCSANOW, &config ) != 0 ) {
|
||||
FG_LOG( FG_IO, FG_ALERT, "Unable to update port settings" );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool FGSerialPort::close_port() {
|
||||
#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ )
|
||||
CloseHandle( fd );
|
||||
#else
|
||||
close(fd);
|
||||
#endif
|
||||
|
||||
dev_open = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool FGSerialPort::set_baud(int baud) {
|
||||
|
||||
#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ )
|
||||
|
||||
return true;
|
||||
|
||||
#else
|
||||
|
||||
struct termios config;
|
||||
speed_t speed = B9600;
|
||||
|
||||
if ( tcgetattr( fd, &config ) != 0 ) {
|
||||
FG_LOG( FG_IO, FG_ALERT, "Unable to poll port settings" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( baud == 300 ) {
|
||||
speed = B300;
|
||||
} else if ( baud == 1200 ) {
|
||||
speed = B1200;
|
||||
} else if ( baud == 2400 ) {
|
||||
speed = B2400;
|
||||
} else if ( baud == 4800 ) {
|
||||
speed = B4800;
|
||||
} else if ( baud == 9600 ) {
|
||||
speed = B9600;
|
||||
} else if ( baud == 19200 ) {
|
||||
speed = B19200;
|
||||
} else if ( baud == 38400 ) {
|
||||
speed = B38400;
|
||||
} else if ( baud == 57600 ) {
|
||||
speed = B57600;
|
||||
} else if ( baud == 115200 ) {
|
||||
speed = B115200;
|
||||
#if defined( linux ) || defined( __FreeBSD__ )
|
||||
} else if ( baud == 230400 ) {
|
||||
speed = B230400;
|
||||
#endif
|
||||
} else {
|
||||
FG_LOG( FG_IO, FG_ALERT, "Unsupported baud rate " << baud );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( cfsetispeed( &config, speed ) != 0 ) {
|
||||
FG_LOG( FG_IO, FG_ALERT, "Problem setting input baud rate" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( cfsetospeed( &config, speed ) != 0 ) {
|
||||
FG_LOG( FG_IO, FG_ALERT, "Problem setting output baud rate" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( tcsetattr( fd, TCSANOW, &config ) != 0 ) {
|
||||
FG_LOG( FG_IO, FG_ALERT, "Unable to update port settings" );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
string FGSerialPort::read_port() {
|
||||
|
||||
#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ )
|
||||
|
||||
string result = "";
|
||||
return result;
|
||||
|
||||
#else
|
||||
|
||||
const int max_count = 1024;
|
||||
char buffer[max_count+1];
|
||||
int count;
|
||||
string result;
|
||||
|
||||
count = read(fd, buffer, max_count);
|
||||
// cout << "read " << count << " bytes" << endl;
|
||||
|
||||
if ( count < 0 ) {
|
||||
// error condition
|
||||
if ( errno != EAGAIN ) {
|
||||
FG_LOG( FG_IO, FG_ALERT,
|
||||
"Serial I/O on read, error number = " << errno );
|
||||
}
|
||||
|
||||
return "";
|
||||
} else {
|
||||
buffer[count] = '\0';
|
||||
result = buffer;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
int FGSerialPort::read_port(char *buf, int len) {
|
||||
|
||||
#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ )
|
||||
|
||||
buf[0] = '\0';
|
||||
return 0;
|
||||
|
||||
#else
|
||||
|
||||
string result;
|
||||
|
||||
int count = read(fd, buf, len);
|
||||
// cout << "read " << count << " bytes" << endl;
|
||||
|
||||
if ( count < 0 ) {
|
||||
// error condition
|
||||
if ( errno != EAGAIN ) {
|
||||
FG_LOG( FG_IO, FG_ALERT,
|
||||
"Serial I/O on read, error number = " << errno );
|
||||
}
|
||||
|
||||
buf[0] = '\0';
|
||||
return 0;
|
||||
} else {
|
||||
buf[count] = '\0';
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
int FGSerialPort::write_port(const string& value) {
|
||||
|
||||
#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ )
|
||||
|
||||
LPCVOID lpBuffer = value.c_str();
|
||||
DWORD nNumberOfBytesToWrite = value.length();
|
||||
DWORD lpNumberOfBytesWritten;
|
||||
OVERLAPPED lpOverlapped;
|
||||
|
||||
if ( WriteFile( fd,
|
||||
lpBuffer,
|
||||
nNumberOfBytesToWrite,
|
||||
&lpNumberOfBytesWritten,
|
||||
&lpOverlapped ) == 0 )
|
||||
{
|
||||
LPVOID lpMsgBuf;
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
GetLastError(),
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||||
(LPTSTR) &lpMsgBuf,
|
||||
0,
|
||||
NULL );
|
||||
|
||||
FG_LOG( FG_IO, FG_ALERT, "Serial I/O write error: "
|
||||
<< (const char*) lpMsgBuf );
|
||||
LocalFree( lpMsgBuf );
|
||||
return int(lpNumberOfBytesWritten);
|
||||
}
|
||||
|
||||
return int(lpNumberOfBytesWritten);
|
||||
|
||||
#else
|
||||
|
||||
static bool error = false;
|
||||
int count;
|
||||
|
||||
if ( error ) {
|
||||
FG_LOG( FG_IO, FG_ALERT, "attempting serial write error recovery" );
|
||||
// attempt some sort of error recovery
|
||||
count = write(fd, "\n", 1);
|
||||
if ( count == 1 ) {
|
||||
// cout << "Serial error recover successful!\n";
|
||||
error = false;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
count = write(fd, value.c_str(), value.length());
|
||||
// cout << "write '" << value << "' " << count << " bytes" << endl;
|
||||
|
||||
if ( (int)count == (int)value.length() ) {
|
||||
error = false;
|
||||
} else {
|
||||
if ( errno == EAGAIN ) {
|
||||
// ok ... in our context we don't really care if we can't
|
||||
// write a string, we'll just get it the next time around
|
||||
error = false;
|
||||
} else {
|
||||
error = true;
|
||||
FG_LOG( FG_IO, FG_ALERT,
|
||||
"Serial I/O on write, error number = " << errno );
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
int FGSerialPort::write_port(const char* buf, int len) {
|
||||
#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ )
|
||||
|
||||
LPCVOID lpBuffer = buf;
|
||||
DWORD nNumberOfBytesToWrite = len;
|
||||
DWORD lpNumberOfBytesWritten;
|
||||
OVERLAPPED lpOverlapped;
|
||||
|
||||
if ( WriteFile( fd,
|
||||
lpBuffer,
|
||||
nNumberOfBytesToWrite,
|
||||
&lpNumberOfBytesWritten,
|
||||
&lpOverlapped ) == 0 )
|
||||
{
|
||||
LPVOID lpMsgBuf;
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
GetLastError(),
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||||
(LPTSTR) &lpMsgBuf,
|
||||
0,
|
||||
NULL );
|
||||
|
||||
FG_LOG( FG_IO, FG_ALERT, "Serial I/O write error: "
|
||||
<< (const char*) lpMsgBuf );
|
||||
LocalFree( lpMsgBuf );
|
||||
return int(lpNumberOfBytesWritten);
|
||||
}
|
||||
|
||||
return int(lpNumberOfBytesWritten);
|
||||
|
||||
#else
|
||||
|
||||
static bool error = false;
|
||||
int count;
|
||||
|
||||
if ( error ) {
|
||||
// attempt some sort of error recovery
|
||||
count = write(fd, "\n", 1);
|
||||
if ( count == 1 ) {
|
||||
// cout << "Serial error recover successful!\n";
|
||||
error = false;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
count = write(fd, buf, len);
|
||||
// cout << "write '" << buf << "' " << count << " bytes" << endl;
|
||||
|
||||
if ( (int)count == len ) {
|
||||
error = false;
|
||||
} else {
|
||||
error = true;
|
||||
if ( errno == EAGAIN ) {
|
||||
// ok ... in our context we don't really care if we can't
|
||||
// write a string, we'll just get it the next time around
|
||||
} else {
|
||||
FG_LOG( FG_IO, FG_ALERT,
|
||||
"Serial I/O on write, error number = " << errno );
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
82
simgear/serial/serial.hxx
Normal file
82
simgear/serial/serial.hxx
Normal file
@@ -0,0 +1,82 @@
|
||||
// serial.hxx -- Unix serial I/O support
|
||||
//
|
||||
// Written by Curtis Olson, started November 1998.
|
||||
//
|
||||
// Copyright (C) 1998 Curtis L. Olson - curt@flightgear.org
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#ifndef _SERIAL_HXX
|
||||
#define _SERIAL_HXX
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ )
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
#include STL_STRING
|
||||
FG_USING_STD(string);
|
||||
|
||||
// if someone know how to do this all with C++ streams let me know
|
||||
// #include <stdio.h>
|
||||
|
||||
|
||||
class FGSerialPort
|
||||
{
|
||||
#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ )
|
||||
typedef HANDLE fd_type;
|
||||
#else
|
||||
typedef int fd_type;
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
fd_type fd;
|
||||
bool dev_open;
|
||||
|
||||
public:
|
||||
|
||||
FGSerialPort();
|
||||
FGSerialPort(const string& device, int baud);
|
||||
|
||||
~FGSerialPort();
|
||||
|
||||
bool open_port(const string& device);
|
||||
bool close_port();
|
||||
bool set_baud(int baud);
|
||||
string read_port();
|
||||
int read_port(char *buf, int len);
|
||||
int write_port(const string& value);
|
||||
int write_port(const char *buf, int len);
|
||||
|
||||
inline bool is_enabled() { return dev_open; }
|
||||
};
|
||||
|
||||
|
||||
#endif // _SERIAL_HXX
|
||||
|
||||
|
||||
30
simgear/serial/testserial.cxx
Normal file
30
simgear/serial/testserial.cxx
Normal file
@@ -0,0 +1,30 @@
|
||||
#include <string>
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#include "serial.hxx"
|
||||
|
||||
main () {
|
||||
FGSerialPort port;
|
||||
string value;
|
||||
bool result;
|
||||
|
||||
fglog().setLogLevels( FG_ALL, FG_INFO );
|
||||
|
||||
cout << "start of main" << endl;
|
||||
|
||||
result = port.open_port("/dev/ttyS1");
|
||||
cout << "opened port, result = " << result << endl;
|
||||
|
||||
result = port.set_baud(4800);
|
||||
cout << "set baud, result = " << result << endl;
|
||||
|
||||
port.write_port("ATDT 626-9800\n");
|
||||
|
||||
while ( true ) {
|
||||
value = port.read_port();
|
||||
if ( value.length() ) {
|
||||
cout << "-> " << value << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user