Compare commits
446 Commits
RELEASE_0_
...
SIMGEAR_1_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c044d711ef | ||
|
|
f2132f6a7d | ||
|
|
69871b15ff | ||
|
|
f4ec02a592 | ||
|
|
53f7743678 | ||
|
|
15893bc558 | ||
|
|
73b974f1b5 | ||
|
|
0e7bdc208b | ||
|
|
e0a07b7a92 | ||
|
|
4da58e8846 | ||
|
|
966b9e5c2b | ||
|
|
1625192c81 | ||
|
|
c5e8c6603c | ||
|
|
37e541d326 | ||
|
|
862a827fe6 | ||
|
|
b96c5c9e4b | ||
|
|
f7e91f1f08 | ||
|
|
2d77178ba3 | ||
|
|
b38e6d8bf3 | ||
|
|
b601cdb6a5 | ||
|
|
2803154213 | ||
|
|
ae5297e6d7 | ||
|
|
fa7490fb38 | ||
|
|
bad80521a8 | ||
|
|
8303e30033 | ||
|
|
27de1e271e | ||
|
|
98cecfe940 | ||
|
|
2e65538fb5 | ||
|
|
e6371cbf9c | ||
|
|
0b8b6ac56a | ||
|
|
cc17cc4af7 | ||
|
|
6afd7e1a38 | ||
|
|
91e22c1fb3 | ||
|
|
ad6129816d | ||
|
|
409db9d7ef | ||
|
|
2ccd58e917 | ||
|
|
7585ad430a | ||
|
|
c105c5a449 | ||
|
|
54065b59a1 | ||
|
|
f9250ae522 | ||
|
|
2f8621ed3d | ||
|
|
98a3e7cffa | ||
|
|
d7f2966216 | ||
|
|
8687b214e7 | ||
|
|
f5f1f0da8e | ||
|
|
818359bfd0 | ||
|
|
8174005ac8 | ||
|
|
0180cae8c3 | ||
|
|
dd1ea541ec | ||
|
|
19aac5b14c | ||
|
|
f3f8a211cd | ||
|
|
3edcbc3b99 | ||
|
|
5a1cc8745e | ||
|
|
12495547c4 | ||
|
|
ff654ab094 | ||
|
|
e55f55cd3e | ||
|
|
29aad066f0 | ||
|
|
74d3bdc68c | ||
|
|
7f9b3a8666 | ||
|
|
426f6de16f | ||
|
|
cf19b81dd4 | ||
|
|
d4c7e95092 | ||
|
|
aa07b5bdd8 | ||
|
|
c7cbb22667 | ||
|
|
ff72b68731 | ||
|
|
433be0e46b | ||
|
|
900607034e | ||
|
|
733e6fa14f | ||
|
|
cd72eb20c6 | ||
|
|
d754e616a5 | ||
|
|
d613e0a488 | ||
|
|
942fa53ed9 | ||
|
|
1729841083 | ||
|
|
315d83bc88 | ||
|
|
223aa0ccd5 | ||
|
|
38494a48d8 | ||
|
|
38456bddb5 | ||
|
|
b8a12b0e5b | ||
|
|
2d37c0aa42 | ||
|
|
c8c693db53 | ||
|
|
cdff0fceea | ||
|
|
3b6f47aea1 | ||
|
|
7bc37651c3 | ||
|
|
4fe43c3e50 | ||
|
|
0826b7c3ca | ||
|
|
d219c5c4c6 | ||
|
|
1a498348ee | ||
|
|
c6b03555f7 | ||
|
|
bb1a270532 | ||
|
|
69ea4b846a | ||
|
|
373a0e4a7d | ||
|
|
f4f5ab2392 | ||
|
|
b20b3229bf | ||
|
|
77fb93bb61 | ||
|
|
ec72b46dcb | ||
|
|
367f1813de | ||
|
|
74116057a7 | ||
|
|
9deb40216e | ||
|
|
daef76ec0b | ||
|
|
569a29fbbc | ||
|
|
0c06bfd3d9 | ||
|
|
8f46f2cac8 | ||
|
|
8f48515b80 | ||
|
|
c7dab4abea | ||
|
|
5e4c4725bc | ||
|
|
9861d74221 | ||
|
|
bb3b606820 | ||
|
|
09fb51189e | ||
|
|
bd19899bbc | ||
|
|
b69753fb76 | ||
|
|
9dc1b5f6f5 | ||
|
|
55c1ac36e3 | ||
|
|
c12e6cdc09 | ||
|
|
85562e8b95 | ||
|
|
fd34cc0b87 | ||
|
|
6322393782 | ||
|
|
1f9e954610 | ||
|
|
6491746809 | ||
|
|
6d2f1ff81e | ||
|
|
c724e5fb20 | ||
|
|
600726976c | ||
|
|
49b5c2058d | ||
|
|
21df21b144 | ||
|
|
620e71e800 | ||
|
|
db2216848d | ||
|
|
cfffe91ed5 | ||
|
|
a95aed1047 | ||
|
|
2883a36c76 | ||
|
|
ac4245013f | ||
|
|
b09e484492 | ||
|
|
dc63ddb010 | ||
|
|
09778a8eab | ||
|
|
8cbe9f1bd0 | ||
|
|
be61689458 | ||
|
|
4b63bc051e | ||
|
|
a098ba5e79 | ||
|
|
edee4b3fe5 | ||
|
|
0c9013e60e | ||
|
|
701c4bcf27 | ||
|
|
22f2fac56b | ||
|
|
605125c0e7 | ||
|
|
65d0ee126a | ||
|
|
4db6435090 | ||
|
|
4383fd3c45 | ||
|
|
b6be76b0ab | ||
|
|
92d8fa1193 | ||
|
|
9c51bf3edf | ||
|
|
cf0e4e6f8c | ||
|
|
c3719f35e3 | ||
|
|
0b1f074bcf | ||
|
|
7fe8514434 | ||
|
|
37c4dcf8ba | ||
|
|
e33dd3c499 | ||
|
|
94be52886e | ||
|
|
6646aa5644 | ||
|
|
d556eba296 | ||
|
|
a5b573b2d3 | ||
|
|
18d30ea8fa | ||
|
|
4324ffccf4 | ||
|
|
182ee9d7e4 | ||
|
|
68c1cfed46 | ||
|
|
1159784538 | ||
|
|
e683b5fdec | ||
|
|
3c409c5070 | ||
|
|
4b7361dfe7 | ||
|
|
037d5c11a5 | ||
|
|
95d857e091 | ||
|
|
4efa087cd1 | ||
|
|
60f0003436 | ||
|
|
fdb265cd6e | ||
|
|
34704a17f2 | ||
|
|
4a959ec2fd | ||
|
|
f182886fce | ||
|
|
2fbaddbecf | ||
|
|
cafcecf03d | ||
|
|
49473845cf | ||
|
|
d4d4ed22a0 | ||
|
|
240ed6f0b1 | ||
|
|
084a24e958 | ||
|
|
cd9e3648e9 | ||
|
|
7ed51be4e6 | ||
|
|
0c8358ae67 | ||
|
|
25cefd9129 | ||
|
|
af75c0ca0c | ||
|
|
a91b2629d3 | ||
|
|
de9070dba1 | ||
|
|
813b518b6f | ||
|
|
c47e800f60 | ||
|
|
8398f45d43 | ||
|
|
aeaaa50f6c | ||
|
|
f33ce846b8 | ||
|
|
4718b9dc07 | ||
|
|
fba00f7c5a | ||
|
|
3360383fd7 | ||
|
|
6c30f62693 | ||
|
|
ab5b0382da | ||
|
|
671f3f5890 | ||
|
|
9bae445624 | ||
|
|
30529ccdf5 | ||
|
|
a8a02d3a2e | ||
|
|
5da33ca244 | ||
|
|
04c1e95f08 | ||
|
|
2186fc1fc7 | ||
|
|
fb49a9192e | ||
|
|
ccbc5abec6 | ||
|
|
7aa6fd479d | ||
|
|
3fcc16c1a0 | ||
|
|
b3e0298189 | ||
|
|
7e1fe7d852 | ||
|
|
5d7d77d4b6 | ||
|
|
418856769b | ||
|
|
46a32dd3ee | ||
|
|
ecb4dc57b4 | ||
|
|
89d426470b | ||
|
|
23c7a1b5b7 | ||
|
|
3b21e9434f | ||
|
|
d4a4428e64 | ||
|
|
2dfc057135 | ||
|
|
a25eebef9b | ||
|
|
741c4ca15a | ||
|
|
0bcdf2e4dc | ||
|
|
cd5a720211 | ||
|
|
5cb04946b0 | ||
|
|
c8953c6275 | ||
|
|
e8dc9c9454 | ||
|
|
a0c325681f | ||
|
|
8d3bf19422 | ||
|
|
4477867ef4 | ||
|
|
e696c884dc | ||
|
|
80bcaa49e6 | ||
|
|
0096c1bb02 | ||
|
|
38b37a068d | ||
|
|
0281f31df2 | ||
|
|
40b182c550 | ||
|
|
d1dedc7511 | ||
|
|
04cd9b3eb6 | ||
|
|
de6003367d | ||
|
|
a5f42eeddf | ||
|
|
a8ba041b67 | ||
|
|
e700fc6f34 | ||
|
|
af29d3d257 | ||
|
|
487701a143 | ||
|
|
f32e037c58 | ||
|
|
8bd903dd96 | ||
|
|
560c100484 | ||
|
|
52444d177b | ||
|
|
b4f7ff29ef | ||
|
|
f7c6a5bfa2 | ||
|
|
6fe14f7a6b | ||
|
|
786e5addd8 | ||
|
|
2e9a15f523 | ||
|
|
bb0d2ddc53 | ||
|
|
702fb014a5 | ||
|
|
834eab9457 | ||
|
|
a85da04601 | ||
|
|
414f1c27e4 | ||
|
|
c76e2eb900 | ||
|
|
c523e15302 | ||
|
|
2dc8de295d | ||
|
|
d645fd6327 | ||
|
|
219a7f3a07 | ||
|
|
d95e3e0055 | ||
|
|
2cc31ff425 | ||
|
|
8258fd7d9f | ||
|
|
784cca2233 | ||
|
|
436539a700 | ||
|
|
dcb3da9f28 | ||
|
|
a354c841f1 | ||
|
|
3824f064cd | ||
|
|
cba6db752b | ||
|
|
a458e26581 | ||
|
|
9d68727a84 | ||
|
|
38b9a874e0 | ||
|
|
7a680fb9f2 | ||
|
|
a5f9262adb | ||
|
|
b05e32fa8c | ||
|
|
53d8cff835 | ||
|
|
00fe97ff88 | ||
|
|
607511fd64 | ||
|
|
8663c265d8 | ||
|
|
6c5d35d6ce | ||
|
|
95532cb318 | ||
|
|
4d91bc5908 | ||
|
|
b13900402d | ||
|
|
1bb6c03bd0 | ||
|
|
1445949e31 | ||
|
|
360d3834ca | ||
|
|
aacdcad529 | ||
|
|
ad9341835f | ||
|
|
b028adb6af | ||
|
|
39f683b272 | ||
|
|
a6c46c89eb | ||
|
|
d534cf6f02 | ||
|
|
dd4326f7c4 | ||
|
|
40aecd688e | ||
|
|
63730a6e2c | ||
|
|
4d4d26aef8 | ||
|
|
de6b32d8c6 | ||
|
|
a0af7f0524 | ||
|
|
c043bd3422 | ||
|
|
18ae1d6940 | ||
|
|
d6f64f9773 | ||
|
|
db99a4cb90 | ||
|
|
108689661f | ||
|
|
d3e00dba8e | ||
|
|
fcd33e5035 | ||
|
|
af9082cd9f | ||
|
|
6a0bb18fca | ||
|
|
8aa8d87781 | ||
|
|
4998af8d7a | ||
|
|
c6aa95f3f3 | ||
|
|
481be29366 | ||
|
|
3617b6ad8c | ||
|
|
3fb8e19a38 | ||
|
|
2ea2f1b4f2 | ||
|
|
26cb8ec4f1 | ||
|
|
7fe56bea86 | ||
|
|
11b16b8a86 | ||
|
|
de020ee695 | ||
|
|
3b83487611 | ||
|
|
09bab4f162 | ||
|
|
49fcc799ca | ||
|
|
10bc803775 | ||
|
|
4f40770fc6 | ||
|
|
a4495c6ef1 | ||
|
|
67d837c4ec | ||
|
|
138825af6d | ||
|
|
c093841336 | ||
|
|
2df1da4226 | ||
|
|
2792d60e2d | ||
|
|
656a3ace07 | ||
|
|
aec8e88c14 | ||
|
|
bdd5ca140d | ||
|
|
8b3b0def03 | ||
|
|
6440ece177 | ||
|
|
bd3518637c | ||
|
|
aef2a1c484 | ||
|
|
a4b28e5737 | ||
|
|
a3bc2eb836 | ||
|
|
3059da5805 | ||
|
|
18d5a492c8 | ||
|
|
160b0ea7d9 | ||
|
|
4dd1267bea | ||
|
|
b5c4328682 | ||
|
|
571fc69ef4 | ||
|
|
f51595cfc9 | ||
|
|
d54aea0036 | ||
|
|
51bb2974bc | ||
|
|
7a859061fd | ||
|
|
cefa9fcd75 | ||
|
|
d3bacd0b73 | ||
|
|
b94a98fc90 | ||
|
|
e0b2687231 | ||
|
|
cc6179a4dd | ||
|
|
e947bac4a3 | ||
|
|
11ecbb6ca7 | ||
|
|
322789cd4c | ||
|
|
f28464dba0 | ||
|
|
8f6456b1f8 | ||
|
|
1f32786c82 | ||
|
|
829c729ee9 | ||
|
|
5d3aacb892 | ||
|
|
741e9c5ed5 | ||
|
|
1408c1b623 | ||
|
|
c256f8d09e | ||
|
|
55c018c525 | ||
|
|
3fa94b5143 | ||
|
|
5127e2f89c | ||
|
|
3175fa3aca | ||
|
|
5614174b39 | ||
|
|
39fc52fe0a | ||
|
|
81188705b1 | ||
|
|
63c4873d8a | ||
|
|
1a85dcd890 | ||
|
|
27470fc504 | ||
|
|
65d18445d3 | ||
|
|
84dd54b33a | ||
|
|
7c410d36e3 | ||
|
|
98a603a570 | ||
|
|
5876052170 | ||
|
|
f8303b4623 | ||
|
|
20005a7a22 | ||
|
|
4f0bfbab21 | ||
|
|
811442832e | ||
|
|
40811311d7 | ||
|
|
198de211f8 | ||
|
|
9f5412fa9d | ||
|
|
0dc9de81ae | ||
|
|
5b8f42ce5e | ||
|
|
5314274ed6 | ||
|
|
c831856711 | ||
|
|
1bade6d796 | ||
|
|
629a4a950e | ||
|
|
aebb1f6ec8 | ||
|
|
6e42bc55e0 | ||
|
|
1235fba7ee | ||
|
|
7a459db022 | ||
|
|
607987def5 | ||
|
|
397ec62180 | ||
|
|
9315210fbe | ||
|
|
5127990a43 | ||
|
|
40ad2b155a | ||
|
|
a0412d026c | ||
|
|
7d2134c488 | ||
|
|
d894f52b97 | ||
|
|
735f475c24 | ||
|
|
353dd73e24 | ||
|
|
49fe06498a | ||
|
|
bc95ec8084 | ||
|
|
f79906bf16 | ||
|
|
b3262fcb80 | ||
|
|
52b8f924aa | ||
|
|
52f57160aa | ||
|
|
6d4f23919c | ||
|
|
899623f71b | ||
|
|
c5d677ac7b | ||
|
|
c75270a9fc | ||
|
|
1588a379eb | ||
|
|
72d2075828 | ||
|
|
e99c682637 | ||
|
|
c815f70831 | ||
|
|
0da50eaa79 | ||
|
|
b0af84a549 | ||
|
|
b9631e8521 | ||
|
|
f664f7a201 | ||
|
|
f72b3882c3 | ||
|
|
ea47a2973c | ||
|
|
04be9ca670 | ||
|
|
6f0baf6ca9 | ||
|
|
1f5ec6b8d5 | ||
|
|
a2a91520aa | ||
|
|
fd7b5d3de7 | ||
|
|
30ea844c43 | ||
|
|
efac53b121 | ||
|
|
73c0ef59c1 | ||
|
|
7e65ab2d3b | ||
|
|
fec769f632 | ||
|
|
90e42642b6 | ||
|
|
9d9610a882 | ||
|
|
1fc81f4b66 | ||
|
|
4f0b1e847c | ||
|
|
9567ac32f2 | ||
|
|
8dd9cfa2a6 | ||
|
|
dbda8ef893 | ||
|
|
cd143c15d5 | ||
|
|
509a388ccc |
2
Doxyfile
2
Doxyfile
@@ -22,7 +22,7 @@ PROJECT_NAME = SimGear
|
||||
# This could be handy for archiving the generated documentation or
|
||||
# if some version control system is used.
|
||||
|
||||
PROJECT_NUMBER = 0.3.10
|
||||
PROJECT_NUMBER = 1.9.0
|
||||
|
||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
||||
# base path where the generated documentation will be put.
|
||||
|
||||
@@ -4,7 +4,10 @@ EXTRA_DIST = \
|
||||
DoxygenMain.cxx \
|
||||
README.MSVC \
|
||||
README.zlib \
|
||||
projects \
|
||||
README.plib \
|
||||
README.OpenAL \
|
||||
README.OSG \
|
||||
projects \
|
||||
SimGear.dsp \
|
||||
SimGear.dsw
|
||||
|
||||
|
||||
12
NEWS
12
NEWS
@@ -1,3 +1,15 @@
|
||||
Version 1.9.0
|
||||
* Thu Dec 18 15:12:15 CST 2008
|
||||
|
||||
|
||||
Version 1.8.6
|
||||
* Mon Dec 1 14:02:47 CST 2008
|
||||
|
||||
|
||||
Version 1.8.5
|
||||
* October 30, 2008 (source code snapshot release)
|
||||
|
||||
|
||||
New in 0.3.10
|
||||
* April 5, 2006
|
||||
|
||||
|
||||
27
README.OSG
Normal file
27
README.OSG
Normal file
@@ -0,0 +1,27 @@
|
||||
[This file is mirrored in both the FlightGear and SimGear packages.]
|
||||
|
||||
You *must* have OpenSceneGraph (OSG) installed to build this version of
|
||||
FlightGear.
|
||||
|
||||
Notice that FlightGear 1.9.0 requires at least version 2.7.8. Using earlier
|
||||
versions of OSG will yield serious rendering bugs.
|
||||
|
||||
You can get the latest version of OSG from:
|
||||
|
||||
http://www.openscenegraph.org/
|
||||
|
||||
Build notes:
|
||||
|
||||
Unzip the file OpenSceneGraph-x.x.zip and install using the following
|
||||
commands:
|
||||
|
||||
unzip OpenSceneGraph-x.x
|
||||
cd OpenSceneGraph
|
||||
ccmake .
|
||||
|
||||
[ While running ccmake: press 'c' to configure, press 'c' once more, and
|
||||
then press 'g' to generate and exit ]
|
||||
|
||||
make
|
||||
sudo make install
|
||||
|
||||
@@ -3,10 +3,27 @@
|
||||
You *must* have the development components of OpenAL installed on your system
|
||||
to build FlightGear!" You can get a copy here:
|
||||
|
||||
http://www.openal.org
|
||||
http://connect.creativelabs.com/openal/default.aspx
|
||||
|
||||
Build notes:
|
||||
|
||||
The OpenAL developers do not make "versioned" releases so we recommend that
|
||||
you pull the latest version via anonymous CVS (follow the instructions at
|
||||
the OpenAL web site) and build/install that.
|
||||
You can download a versioned release of the openal library from
|
||||
http://www.openal.org/downloads.html. Download the openal source,
|
||||
release 0.0.8 (dated February 11, 2006) and run:
|
||||
tar xjvf openal-soft-1.5.304.tar.bz2
|
||||
cd openal-soft-1.5.304/
|
||||
ccmake .
|
||||
|
||||
[ While running ccmake: press 'c' to configure, press 'c' once more, and
|
||||
then press 'g' to generate and exit ]
|
||||
|
||||
|
||||
The alut library is also required, but comes separately in the package
|
||||
freelut-1.1.0.tar.gz. This package can be downloaded from the same page
|
||||
(http://connect.creativelabs.com/openal/default.aspx). Download and run:
|
||||
tar xzvf freelut-1.1.0.tar.gz
|
||||
cd freealut-1.1.0
|
||||
./configure
|
||||
make
|
||||
sudo make install
|
||||
|
||||
|
||||
18
README.plib
18
README.plib
@@ -1,6 +1,6 @@
|
||||
[This file is mirrored in both the FlightGear and SimGear packages.]
|
||||
|
||||
You *must* have plib version 1.6.0 or later installed on your system
|
||||
You *must* have plib version 1.8.5 or later installed on your system
|
||||
to build FlightGear!" Flight Gear is no longer compatible with the
|
||||
earlier versions of the library.
|
||||
|
||||
@@ -14,3 +14,19 @@ You should be able to just run "./configure" to configure the package
|
||||
and use all of plib's defaults. Then run "make" followed by "make
|
||||
install". By default, plib installs itself into /usr so if you don't
|
||||
like this, be sure to specify an alternate prefix such as --prefix=/usr/local
|
||||
|
||||
As of this writing (2007-11-18), many linux distributions are shipped with a
|
||||
working version of plib, so chances are that this library is already
|
||||
installed. It should be noted, that currently plib version no longer compiles
|
||||
using recent versions of gcc (confirmed on version gcc 4.1.2, as shipped with
|
||||
SuSe 10.2). As a workaround, it is possible to either use plib SVN. Run the
|
||||
following commands:
|
||||
|
||||
|
||||
svn co https://plib.svn.sourceforge.net/svnroot/plib/trunk plib
|
||||
cd plib
|
||||
./autogen.sh
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
|
||||
|
||||
779
SimGear.dsp
779
SimGear.dsp
@@ -496,36 +496,6 @@ SOURCE=.\simgear\math\leastsqs.cxx
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\math\polar3d.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgmath"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgmath"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\math\sg_geodesy.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgmath"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgmath"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\math\sg_random.c
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
@@ -556,7 +526,7 @@ SOURCE=.\simgear\math\vector.cxx
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\math\fastmath.cxx
|
||||
SOURCE=.\simgear\math\SGGeod.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
@@ -617,6 +587,21 @@ SOURCE=.\simgear\environment\visual_enviro.cxx
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\environment\precipitation.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgenvironment"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgenvironment"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Lib_sgmisc"
|
||||
@@ -726,6 +711,21 @@ SOURCE=.\simgear\misc\interpolator.cxx
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\misc\PathOptions.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgmisc"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgmisc"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Lib_sgnasal"
|
||||
@@ -733,6 +733,21 @@ SOURCE=.\simgear\misc\interpolator.cxx
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\nasal\bitslib.c
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgnasal"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgnasal"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\nasal\code.c
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
@@ -823,6 +838,36 @@ SOURCE=.\simgear\nasal\hash.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\nasal\iolib.c
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgnasal"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgnasal"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\nasal\iolib.h
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgnasal"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgnasal"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\nasal\lex.c
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
@@ -868,51 +913,6 @@ SOURCE=.\simgear\nasal\mathlib.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\nasal\iolib.c
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgnasal"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgnasal"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\nasal\iolib.h
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgnasal"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgnasal"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\nasal\bitslib.c
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgnasal"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgnasal"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\nasal\misc.c
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
@@ -928,6 +928,21 @@ SOURCE=.\simgear\nasal\misc.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\nasal\naref.h
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgnasal"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgnasal"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\nasal\nasal.h
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
@@ -988,21 +1003,6 @@ SOURCE=.\simgear\nasal\string.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\nasal\vector.c
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgnasal"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgnasal"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\nasal\thread-posix.c
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
@@ -1030,6 +1030,51 @@ SOURCE=.\simgear\nasal\thread-win32.c
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\nasal\threadlib.c
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgnasal"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgnasal"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\nasal\utf8lib.c
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgnasal"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgnasal"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\nasal\vector.c
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgnasal"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgnasal"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Lib_sgprops"
|
||||
@@ -1184,7 +1229,7 @@ SOURCE=.\simgear\scene\model\animation.cxx
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\model\custtrans.cxx
|
||||
SOURCE=.\simgear\scene\model\particles.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
@@ -1244,7 +1289,22 @@ SOURCE=.\simgear\scene\model\modellib.cxx
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\model\personality.cxx
|
||||
SOURCE=.\simgear\scene\model\ModelRegistry.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgmodel"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgmodel"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\model\persparam.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
@@ -1289,7 +1349,7 @@ SOURCE=.\simgear\scene\model\placementtrans.cxx
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\model\shadowvolume.cxx
|
||||
SOURCE=.\simgear\scene\model\shadanim.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
@@ -1304,7 +1364,127 @@ SOURCE=.\simgear\scene\model\shadowvolume.cxx
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\model\shadanim.cxx
|
||||
SOURCE=.\simgear\scene\model\CheckSceneryVisitor.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgmodel"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgmodel"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\model\SGClipGroup.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgmodel"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgmodel"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\model\SGMaterialAnimation.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgmodel"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgmodel"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\model\SGOffsetTransform.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgmodel"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgmodel"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\model\SGPagedLOD.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgmodel"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgmodel"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\model\SGReaderWriterXML.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgmodel"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgmodel"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\model\SGRotateTransform.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgmodel"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgmodel"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\model\SGScaleTransform.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgmodel"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgmodel"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\model\SGTranslateTransform.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
@@ -1470,6 +1650,21 @@ SOURCE=.\simgear\scene\sky\newcloud.cxx
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\sky\CloudShaderGeometry.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgsky"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgsky"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Lib_sgtgdb"
|
||||
@@ -1492,21 +1687,6 @@ SOURCE=.\simgear\scene\tgdb\apt_signs.cxx
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\tgdb\leaf.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgtgdb"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgtgdb"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\tgdb\obj.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
@@ -1549,6 +1729,310 @@ SOURCE=.\simgear\scene\tgdb\userdata.cxx
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\tgdb\ReaderWriterSTG.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgtgdb"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgtgdb"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\tgdb\SGOceanTile.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgtgdb"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgtgdb"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\tgdb\SGReaderWriterBTG.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgtgdb"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgtgdb"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\tgdb\SGReaderWriterBTG.hxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgtgdb"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgtgdb"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\tgdb\SGVasiDrawable.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgtgdb"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgtgdb"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\tgdb\GroundLightManager.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgtgdb"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgtgdb"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\tgdb\SGModelBin.hxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgtgdb"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgtgdb"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\tgdb\ShaderGeometry.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgtgdb"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgtgdb"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\tgdb\TileCache.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgtgdb"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgtgdb"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\tgdb\TileEntry.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgtgdb"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgtgdb"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\tgdb\TreeBin.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgtgdb"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgtgdb"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\tgdb\TreeBin.hxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgtgdb"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgtgdb"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Lib_sgutil"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\util\SGEnlargeBoundingBox.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgutil"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgutil"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\util\SGSceneFeatures.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgutil"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgutil"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\util\SGSceneUserData.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgutil"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgutil"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\util\SGStateAttributeVisitor.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgutil"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgutil"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\util\SGTextureStateAttributeVisitor.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgutil"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgutil"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\util\NodeAndDrawableVisitor.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgutil"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgutil"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\util\StateAttributeFactory.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgutil"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgutil"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\scene\util\QuadTreeBuilder.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgutil"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgutil"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Lib_sgscreen"
|
||||
@@ -1805,6 +2289,81 @@ SOURCE=.\simgear\structure\subsystem_mgr.cxx
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\structure\SGAtomic.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgstructure"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgstructure"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\structure\SGBinding.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgstructure"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgstructure"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\structure\SGExpression.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgstructure"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgstructure"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\structure\SGSmplhist.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgstructure"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgstructure"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\simgear\structure\SGSmplstat.cxx
|
||||
|
||||
!IF "$(CFG)" == "SimGear - Win32 Release"
|
||||
|
||||
# PROP Intermediate_Dir "Release\Lib_sgstructure"
|
||||
|
||||
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
|
||||
|
||||
# PROP Intermediate_Dir "Debug\Lib_sgstructure"
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Lib_sgtiming"
|
||||
|
||||
23
Thanks
23
Thanks
@@ -47,6 +47,18 @@ Jean-Francois Doue
|
||||
http://www.animats.com/simpleppp/ftp/public_html/topics/developers.html
|
||||
|
||||
|
||||
Melchior Franz
|
||||
METAR parser and fetcher. "material" animation (based on Jim Wilsons's
|
||||
"emission" animation). Debugging and extension of property listener
|
||||
features. Addition of removeChildren.
|
||||
|
||||
|
||||
Mathias Froehlich
|
||||
Reworked and cleaned up large parts of the infrastructure, of math
|
||||
files, animations and rendering in preparation of a transition to
|
||||
the OSG library. Added new handlers for shared and referenced objects.
|
||||
|
||||
|
||||
Bruce Finney <bfinney@gte.net>
|
||||
MSVC5 compatibility.
|
||||
|
||||
@@ -71,6 +83,10 @@ Bruce Jackson of NASA <e.b.jackson@larc.nasa.gov>
|
||||
http://dcb.larc.nasa.gov/www/DCBStaff/ebj/ebj.html
|
||||
|
||||
|
||||
Maik Justus
|
||||
Fixed an old bug in the SGPropertyNode class.
|
||||
|
||||
|
||||
Richard Kaszeta <bofh@me.umn.edu>
|
||||
Contributed screen buffer to ppm screen shot routine.
|
||||
Rich has also helped in the early development of the Flight Gear "altitude
|
||||
@@ -90,6 +106,11 @@ David Megginson <david@megginson.com>
|
||||
SimGear property manager/registry
|
||||
|
||||
|
||||
Tim Moore
|
||||
Ported the (chrome) "shader" animation to OSG, and helped with porting
|
||||
the "material" animation.
|
||||
|
||||
|
||||
Curt Olson http://www.flightgear.org/~curt/
|
||||
Curt is responsible for overall project and source code management.
|
||||
He has his hands in many of the areas.
|
||||
@@ -99,7 +120,7 @@ Petter Reinholdtsen <pere@games.no>
|
||||
Incorporated the Gnu automake/autoconf system (with libtool).
|
||||
This should streamline and standardize the build process for all
|
||||
Unix-like platforms. It should have little effect on IDE type
|
||||
environments since the don't use the Unix make system.
|
||||
environments since these don't use the Unix make system.
|
||||
|
||||
|
||||
Paul Schlyter <pausch@saaf.se>
|
||||
|
||||
271
acinclude.m4
271
acinclude.m4
@@ -413,3 +413,274 @@ AC_DEFUN([AC_SG_SET_COMPILER],
|
||||
## CFLAGS=
|
||||
;;
|
||||
esac])
|
||||
|
||||
pushdef([AC_PROG_INSTALL],
|
||||
[
|
||||
dnl our own version, testing for a -p flag
|
||||
popdef([AC_PROG_INSTALL])
|
||||
dnl as AC_PROG_INSTALL works as it works we first have
|
||||
dnl to save if the user didn't specify INSTALL, as the
|
||||
dnl autoconf one overwrites INSTALL and we have no chance to find
|
||||
dnl out afterwards
|
||||
AC_PROG_INSTALL
|
||||
|
||||
# OK, user hasn't given any INSTALL, autoconf found one for us
|
||||
# now we test, if it supports the -p flag
|
||||
AC_MSG_CHECKING(for -p flag to install)
|
||||
rm -f confinst.$$.* > /dev/null 2>&1
|
||||
echo "Testtest" > confinst.$$.orig
|
||||
ac_res=no
|
||||
if ${INSTALL} -p confinst.$$.orig confinst.$$.new > /dev/null 2>&1 ; then
|
||||
if test -f confinst.$$.new ; then
|
||||
# OK, -p seems to do no harm to install
|
||||
INSTALL="${INSTALL} -p"
|
||||
ac_res=yes
|
||||
fi
|
||||
fi
|
||||
rm -f confinst.$$.*
|
||||
AC_MSG_RESULT($ac_res)
|
||||
dnl the following tries to resolve some signs and wonders coming up
|
||||
dnl with different autoconf/automake versions
|
||||
dnl e.g.:
|
||||
dnl *automake 1.4 install-strip sets A_M_INSTALL_PROGRAM_FLAGS to -s
|
||||
dnl and has INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(A_M_INSTALL_PROGRAM_FLAGS)
|
||||
dnl it header-vars.am, so there the actual INSTALL_PROGRAM gets the -s
|
||||
dnl *automake 1.4a (and above) use INSTALL_STRIP_FLAG and only has
|
||||
dnl INSTALL_PROGRAM = @INSTALL_PROGRAM@ there, but changes the
|
||||
dnl install-@DIR@PROGRAMS targets to explicitly use that flag
|
||||
dnl *autoconf 2.13 is dumb, and thinks it can use INSTALL_PROGRAM as
|
||||
dnl INSTALL_SCRIPT, which breaks with automake <= 1.4
|
||||
dnl *autoconf >2.13 (since 10.Apr 1999) has not that failure
|
||||
dnl to clean up that mess we:
|
||||
dnl +set INSTALL_PROGRAM to use INSTALL_STRIP_FLAG
|
||||
dnl which cleans KDE's program with automake > 1.4;
|
||||
dnl +set INSTALL_SCRIPT to only use INSTALL, to clean up autoconf's problems
|
||||
dnl with automake<=1.4
|
||||
dnl note that dues to this sometimes two '-s' flags are used
|
||||
INSTALL_PROGRAM='${INSTALL} $(INSTALL_STRIP_FLAG)'
|
||||
INSTALL_SCRIPT='${INSTALL}'
|
||||
])dnl
|
||||
|
||||
# ===========================================================================
|
||||
# http://autoconf-archive.cryp.to/ax_boost_base.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_BOOST_BASE([MINIMUM-VERSION])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Test for the Boost C++ libraries of a particular version (or newer)
|
||||
#
|
||||
# If no path to the installed boost library is given the macro searchs
|
||||
# under /usr, /usr/local, /opt and /opt/local and evaluates the
|
||||
# $BOOST_ROOT environment variable. Further documentation is available at
|
||||
# <http://randspringer.de/boost/index.html>.
|
||||
#
|
||||
# This macro calls:
|
||||
#
|
||||
# AC_SUBST(BOOST_CPPFLAGS) / AC_SUBST(BOOST_LDFLAGS)
|
||||
#
|
||||
# And sets:
|
||||
#
|
||||
# HAVE_BOOST
|
||||
#
|
||||
# LAST MODIFICATION
|
||||
#
|
||||
# 2008-04-12
|
||||
#
|
||||
# COPYLEFT
|
||||
#
|
||||
# Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved.
|
||||
|
||||
AC_DEFUN([AX_BOOST_BASE],
|
||||
[
|
||||
AC_ARG_WITH([boost],
|
||||
AS_HELP_STRING([--with-boost@<:@=DIR@:>@], [use boost (default is yes) - it is possible to specify the root directory for boost (optional)]),
|
||||
[
|
||||
if test "$withval" = "no"; then
|
||||
want_boost="no"
|
||||
elif test "$withval" = "yes"; then
|
||||
want_boost="yes"
|
||||
ac_boost_path=""
|
||||
else
|
||||
want_boost="yes"
|
||||
ac_boost_path="$withval"
|
||||
fi
|
||||
],
|
||||
[want_boost="yes"])
|
||||
|
||||
|
||||
AC_ARG_WITH([boost-libdir],
|
||||
AS_HELP_STRING([--with-boost-libdir=LIB_DIR],
|
||||
[Force given directory for boost libraries. Note that this will overwrite library path detection, so use this parameter only if default library detection fails and you know exactly where your boost libraries are located.]),
|
||||
[
|
||||
if test -d $withval
|
||||
then
|
||||
ac_boost_lib_path="$withval"
|
||||
else
|
||||
AC_MSG_ERROR(--with-boost-libdir expected directory name)
|
||||
fi
|
||||
],
|
||||
[ac_boost_lib_path=""]
|
||||
)
|
||||
|
||||
if test "x$want_boost" = "xyes"; then
|
||||
boost_lib_version_req=ifelse([$1], ,1.20.0,$1)
|
||||
boost_lib_version_req_shorten=`expr $boost_lib_version_req : '\([[0-9]]*\.[[0-9]]*\)'`
|
||||
boost_lib_version_req_major=`expr $boost_lib_version_req : '\([[0-9]]*\)'`
|
||||
boost_lib_version_req_minor=`expr $boost_lib_version_req : '[[0-9]]*\.\([[0-9]]*\)'`
|
||||
boost_lib_version_req_sub_minor=`expr $boost_lib_version_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'`
|
||||
if test "x$boost_lib_version_req_sub_minor" = "x" ; then
|
||||
boost_lib_version_req_sub_minor="0"
|
||||
fi
|
||||
WANT_BOOST_VERSION=`expr $boost_lib_version_req_major \* 100000 \+ $boost_lib_version_req_minor \* 100 \+ $boost_lib_version_req_sub_minor`
|
||||
AC_MSG_CHECKING(for boostlib >= $boost_lib_version_req)
|
||||
succeeded=no
|
||||
|
||||
dnl first we check the system location for boost libraries
|
||||
dnl this location ist chosen if boost libraries are installed with the --layout=system option
|
||||
dnl or if you install boost with RPM
|
||||
if test "$ac_boost_path" != ""; then
|
||||
BOOST_LDFLAGS="-L$ac_boost_path/lib"
|
||||
BOOST_CPPFLAGS="-I$ac_boost_path/include"
|
||||
else
|
||||
for ac_boost_path_tmp in /usr /usr/local /opt /opt/local ; do
|
||||
if test -d "$ac_boost_path_tmp/include/boost" && test -r "$ac_boost_path_tmp/include/boost"; then
|
||||
BOOST_LDFLAGS="-L$ac_boost_path_tmp/lib"
|
||||
BOOST_CPPFLAGS="-I$ac_boost_path_tmp/include"
|
||||
break;
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
dnl overwrite ld flags if we have required special directory with
|
||||
dnl --with-boost-libdir parameter
|
||||
if test "$ac_boost_lib_path" != ""; then
|
||||
BOOST_LDFLAGS="-L$ac_boost_lib_path"
|
||||
fi
|
||||
|
||||
CPPFLAGS_SAVED="$CPPFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
|
||||
export CPPFLAGS
|
||||
|
||||
LDFLAGS_SAVED="$LDFLAGS"
|
||||
LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
|
||||
export LDFLAGS
|
||||
|
||||
AC_LANG_PUSH(C++)
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
||||
@%:@include <boost/version.hpp>
|
||||
]], [[
|
||||
#if BOOST_VERSION >= $WANT_BOOST_VERSION
|
||||
// Everything is okay
|
||||
#else
|
||||
# error Boost version is too old
|
||||
#endif
|
||||
]])],[
|
||||
AC_MSG_RESULT(yes)
|
||||
succeeded=yes
|
||||
found_system=yes
|
||||
],[
|
||||
])
|
||||
AC_LANG_POP([C++])
|
||||
|
||||
|
||||
|
||||
dnl if we found no boost with system layout we search for boost libraries
|
||||
dnl built and installed without the --layout=system option or for a staged(not installed) version
|
||||
if test "x$succeeded" != "xyes"; then
|
||||
_version=0
|
||||
if test "$ac_boost_path" != ""; then
|
||||
if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then
|
||||
for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do
|
||||
_version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'`
|
||||
V_CHECK=`expr $_version_tmp \> $_version`
|
||||
if test "$V_CHECK" = "1" ; then
|
||||
_version=$_version_tmp
|
||||
fi
|
||||
VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'`
|
||||
BOOST_CPPFLAGS="-I$ac_boost_path/include/boost-$VERSION_UNDERSCORE"
|
||||
done
|
||||
fi
|
||||
else
|
||||
for ac_boost_path in /usr /usr/local /opt /opt/local ; do
|
||||
if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then
|
||||
for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do
|
||||
_version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'`
|
||||
V_CHECK=`expr $_version_tmp \> $_version`
|
||||
if test "$V_CHECK" = "1" ; then
|
||||
_version=$_version_tmp
|
||||
best_path=$ac_boost_path
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
|
||||
VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'`
|
||||
BOOST_CPPFLAGS="-I$best_path/include/boost-$VERSION_UNDERSCORE"
|
||||
if test "$ac_boost_lib_path" = ""
|
||||
then
|
||||
BOOST_LDFLAGS="-L$best_path/lib"
|
||||
fi
|
||||
|
||||
if test "x$BOOST_ROOT" != "x"; then
|
||||
if test -d "$BOOST_ROOT" && test -r "$BOOST_ROOT" && test -d "$BOOST_ROOT/stage/lib" && test -r "$BOOST_ROOT/stage/lib"; then
|
||||
version_dir=`expr //$BOOST_ROOT : '.*/\(.*\)'`
|
||||
stage_version=`echo $version_dir | sed 's/boost_//' | sed 's/_/./g'`
|
||||
stage_version_shorten=`expr $stage_version : '\([[0-9]]*\.[[0-9]]*\)'`
|
||||
V_CHECK=`expr $stage_version_shorten \>\= $_version`
|
||||
if test "$V_CHECK" = "1" -a "$ac_boost_lib_path" = "" ; then
|
||||
AC_MSG_NOTICE(We will use a staged boost library from $BOOST_ROOT)
|
||||
BOOST_CPPFLAGS="-I$BOOST_ROOT"
|
||||
BOOST_LDFLAGS="-L$BOOST_ROOT/stage/lib"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
|
||||
export CPPFLAGS
|
||||
LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
|
||||
export LDFLAGS
|
||||
|
||||
AC_LANG_PUSH(C++)
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
||||
@%:@include <boost/version.hpp>
|
||||
]], [[
|
||||
#if BOOST_VERSION >= $WANT_BOOST_VERSION
|
||||
// Everything is okay
|
||||
#else
|
||||
# error Boost version is too old
|
||||
#endif
|
||||
]])],[
|
||||
AC_MSG_RESULT(yes)
|
||||
succeeded=yes
|
||||
found_system=yes
|
||||
],[
|
||||
])
|
||||
AC_LANG_POP([C++])
|
||||
fi
|
||||
|
||||
if test "$succeeded" != "yes" ; then
|
||||
if test "$_version" = "0" ; then
|
||||
AC_MSG_ERROR([[We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in <boost/version.hpp>. See http://randspringer.de/boost for more documentation.]])
|
||||
else
|
||||
AC_MSG_NOTICE([Your boost libraries seems to old (version $_version).])
|
||||
fi
|
||||
else
|
||||
AC_SUBST(BOOST_CPPFLAGS)
|
||||
AC_SUBST(BOOST_LDFLAGS)
|
||||
AC_DEFINE(HAVE_BOOST,,[define if the Boost library is available])
|
||||
fi
|
||||
|
||||
CPPFLAGS="$CPPFLAGS_SAVED"
|
||||
LDFLAGS="$LDFLAGS_SAVED"
|
||||
fi
|
||||
|
||||
])
|
||||
|
||||
73
configure.ac
73
configure.ac
@@ -8,7 +8,7 @@ dnl Require at least automake 2.52
|
||||
AC_PREREQ(2.52)
|
||||
|
||||
dnl Initialize the automake stuff
|
||||
AM_INIT_AUTOMAKE(SimGear, 0.3.10)
|
||||
AM_INIT_AUTOMAKE(SimGear, 1.9.0)
|
||||
|
||||
dnl Specify KAI C++ compiler and flags.
|
||||
dnl Borrowed with slight modification from blitz distribution.
|
||||
@@ -24,8 +24,10 @@ AC_ARG_WITH(cxx,
|
||||
esac
|
||||
])
|
||||
|
||||
echo CXX = $CXX
|
||||
echo CC = $CC
|
||||
AC_MSG_CHECKING([CXX])
|
||||
AC_MSG_RESULT([$CXX])
|
||||
AC_MSG_CHECKING([CC])
|
||||
AC_MSG_RESULT([$CC])
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_MAKE_SET
|
||||
@@ -35,6 +37,11 @@ AC_PROG_CXX
|
||||
AC_PROG_RANLIB
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_LN_S
|
||||
AX_BOOST_BASE([1.34.0])
|
||||
|
||||
if test "x$BOOST_CPPFLAGS" != "x-I/usr/include" ; then
|
||||
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
|
||||
fi
|
||||
|
||||
dnl set the $host variable based on local machine/os
|
||||
AC_CANONICAL_HOST
|
||||
@@ -119,6 +126,14 @@ if test "x$with_plib" != "x" ; then
|
||||
EXTRA_DIRS="${EXTRA_DIRS} $with_plib"
|
||||
fi
|
||||
|
||||
# specify the osg location
|
||||
AC_ARG_WITH(osg, [ --with-osg=PREFIX Specify the prefix path to osg])
|
||||
|
||||
if test "x$with_osg" != "x" ; then
|
||||
echo "osg prefix is $with_osg"
|
||||
EXTRA_DIRS="${EXTRA_DIRS} $with_osg"
|
||||
fi
|
||||
|
||||
dnl Determine an extra directories to add to include/lib search paths
|
||||
case "${host}" in
|
||||
*-apple-darwin* | *-*-cygwin* | *-*-mingw32*)
|
||||
@@ -258,16 +273,18 @@ LIBS="$base_LIBS"
|
||||
|
||||
dnl check for OpenAL libraries
|
||||
OPENAL_OK="no"
|
||||
ALUT_OK="no"
|
||||
case "${host}" in
|
||||
*-*-cygwin* | *-*-mingw32*)
|
||||
dnl CygWin under Windoze.
|
||||
INCLUDES="$INCLUDES -I/usr/local/include"
|
||||
INCLUDES="$INCLUDES -I/usr/local/include/"
|
||||
LIBS="$LIBS -L/usr/local/lib"
|
||||
AC_SEARCH_LIBS(alGenBuffers, openal32)
|
||||
AC_SEARCH_LIBS(alutInit, [ openal32 ALut ] )
|
||||
AC_SEARCH_LIBS(alGenBuffers, [ openal32 openal ] )
|
||||
AC_SEARCH_LIBS(alutInit, [ openal32 ALut alut ] )
|
||||
LIBS="$LIBS -lwinmm -ldsound -ldxguid -lole32"
|
||||
openal_LIBS="$LIBS"
|
||||
OPENAL_OK="$ac_cv_search_alGenBuffers"
|
||||
ALUT_OK="$ac_cv_search_alutInit"
|
||||
;;
|
||||
|
||||
*-apple-darwin*)
|
||||
@@ -277,6 +294,7 @@ case "${host}" in
|
||||
openal_LIBS="$LIBS"
|
||||
# not sure how to test if OpenAL exists on MacOS (does it come by default?)
|
||||
OPENAL_OK="yes"
|
||||
ALUT_OK="yes"
|
||||
;;
|
||||
|
||||
*)
|
||||
@@ -287,6 +305,7 @@ case "${host}" in
|
||||
AC_SEARCH_LIBS(alGenBuffers, openal)
|
||||
AC_SEARCH_LIBS(alutInit, [ alut openal ] )
|
||||
OPENAL_OK="$ac_cv_search_alGenBuffers"
|
||||
ALUT_OK="$ac_cv_search_alutInit"
|
||||
openal_LIBS="$LIBS"
|
||||
LIBS=$save_LIBS
|
||||
;;
|
||||
@@ -304,6 +323,19 @@ if test "$OPENAL_OK" == "no"; then
|
||||
exit
|
||||
fi
|
||||
|
||||
if test "$ALUT_OK" == "no"; then
|
||||
echo
|
||||
echo "You *must* have the alut library installed on your system to build"
|
||||
echo "SimGear!"
|
||||
echo
|
||||
echo "Please see README.OpenAL for more details."
|
||||
echo
|
||||
echo "configure aborted."
|
||||
exit
|
||||
fi
|
||||
|
||||
|
||||
|
||||
LIBS="$base_LIBS"
|
||||
|
||||
AC_SUBST(base_LIBS)
|
||||
@@ -334,11 +366,11 @@ if test "x$ac_cv_header_plib_ul_h" != "xyes"; then
|
||||
exit
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([for plib 1.8.4 or newer])
|
||||
AC_MSG_CHECKING([for plib 1.8.5 or newer])
|
||||
AC_TRY_RUN([
|
||||
#include <plib/ul.h>
|
||||
|
||||
#define MIN_PLIB_VERSION 184
|
||||
#define MIN_PLIB_VERSION 185
|
||||
|
||||
int main() {
|
||||
int major, minor, micro;
|
||||
@@ -353,12 +385,34 @@ int main() {
|
||||
],
|
||||
AC_MSG_RESULT(yes),
|
||||
[AC_MSG_RESULT(wrong version);
|
||||
AC_MSG_ERROR([Install plib 1.8.4 or later first...])],
|
||||
AC_MSG_ERROR([Install plib 1.8.5 or later first...])],
|
||||
AC_MSG_RESULT(yes)
|
||||
)
|
||||
|
||||
LIBS="$saved_LIBS"
|
||||
|
||||
AC_CHECK_HEADER(osg/Version)
|
||||
if test "x$ac_cv_header_osg_Version" != "xyes"; then
|
||||
echo
|
||||
echo "You *must* have the OpenSceneGraph support library installed on your system"
|
||||
echo "to build this version of SimGear!"
|
||||
echo
|
||||
echo "Please see README.OSG for more details."
|
||||
echo
|
||||
echo "configure aborted."
|
||||
exit
|
||||
fi
|
||||
|
||||
AC_CHECK_HEADER(boost/version.hpp)
|
||||
if test "x$ac_cv_header_boost_version_hpp" != "xyes"; then
|
||||
echo
|
||||
echo "You *must* have the Boost library installed on your system"
|
||||
echo "to build this version of SimGear!"
|
||||
echo
|
||||
echo "configure aborted."
|
||||
exit
|
||||
fi
|
||||
|
||||
AC_LANG_POP
|
||||
|
||||
dnl Check for system installed zlib
|
||||
@@ -430,6 +484,7 @@ AC_CONFIG_FILES([ \
|
||||
simgear/scene/model/Makefile \
|
||||
simgear/scene/sky/Makefile \
|
||||
simgear/scene/tgdb/Makefile \
|
||||
simgear/scene/util/Makefile \
|
||||
simgear/screen/Makefile \
|
||||
simgear/serial/Makefile \
|
||||
simgear/sound/Makefile \
|
||||
|
||||
4
projects/VC7.1/.cvsignore
Executable file
4
projects/VC7.1/.cvsignore
Executable file
@@ -0,0 +1,4 @@
|
||||
Debug
|
||||
Release
|
||||
SimGear.ncb
|
||||
SimGear.suo
|
||||
21
projects/VC7.1/SimGear.sln
Executable file
21
projects/VC7.1/SimGear.sln
Executable file
@@ -0,0 +1,21 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 8.00
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimGear", "SimGear.vcproj", "{22540CD3-D3CA-4C86-A773-80AEEE3ACDED}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
Debug = Debug
|
||||
Release = Release
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfiguration) = postSolution
|
||||
{22540CD3-D3CA-4C86-A773-80AEEE3ACDED}.Debug.ActiveCfg = Debug|Win32
|
||||
{22540CD3-D3CA-4C86-A773-80AEEE3ACDED}.Debug.Build.0 = Debug|Win32
|
||||
{22540CD3-D3CA-4C86-A773-80AEEE3ACDED}.Release.ActiveCfg = Release|Win32
|
||||
{22540CD3-D3CA-4C86-A773-80AEEE3ACDED}.Release.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityAddIns) = postSolution
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
1218
projects/VC7.1/SimGear.vcproj
Executable file
1218
projects/VC7.1/SimGear.vcproj
Executable file
File diff suppressed because it is too large
Load Diff
@@ -41,11 +41,11 @@
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../..;../../..;../../Simgear;../../../AL/include;"../../../zlib-1.2.3";"../../../Pre-built.2/include""
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;HAVE_CONFIG_H;ENABLE_THREADS;_CRT_SECURE_NO_DEPRECATE;_CONST_CORRECT_OVERLOADS;NOMINMAX;_USE_MATH_DEFINES"
|
||||
AdditionalIncludeDirectories="../..;../../..;$(ProgramFiles)/OpenThreads/include;$(ProgramFiles)/OpenSceneGraph/include;../../Simgear;../../../3rdparty/include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;HAVE_CONFIG_H;ENABLE_THREADS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_CONST_CORRECT_OVERLOADS;NOMINMAX;_USE_MATH_DEFINES"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="false"
|
||||
@@ -103,11 +103,11 @@
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
AdditionalIncludeDirectories="../..;../../..;../../Simgear;../../../AL/include;"../../../zlib-1.2.3";"../../../Pre-built.2/include""
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;HAVE_CONFIG_H;ENABLE_THREADS;_CRT_SECURE_NO_DEPRECATE;_CONST_CORRECT_OVERLOADS;NOMINMAX;_USE_MATH_DEFINES"
|
||||
AdditionalIncludeDirectories="../..;../../..;"$(ProgramFiles)/OpenThreads/include";"$(ProgramFiles)/OpenSceneGraph/include";../../Simgear;../../../3rdparty/include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;HAVE_CONFIG_H;ENABLE_THREADS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_CONST_CORRECT_OVERLOADS;NOMINMAX;_USE_MATH_DEFINES"
|
||||
StringPooling="true"
|
||||
MinimalRebuild="true"
|
||||
RuntimeLibrary="0"
|
||||
RuntimeLibrary="2"
|
||||
FloatingPointModel="2"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
@@ -215,10 +215,6 @@
|
||||
RelativePath="..\..\simgear\magvar\coremag.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\model\custtrans.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\nasal\data.h"
|
||||
>
|
||||
@@ -247,10 +243,6 @@
|
||||
RelativePath="..\..\simgear\screen\extensions.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\math\fastmath.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\timing\geocoord.h"
|
||||
>
|
||||
@@ -475,10 +467,6 @@
|
||||
RelativePath="..\..\simgear\sg_inlines.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\math\sg_memory.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\misc\sg_path.hxx"
|
||||
>
|
||||
@@ -511,6 +499,26 @@
|
||||
RelativePath="..\..\simgear\math\sg_types.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\structure\SGAtomic.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\structure\SGBinding.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\math\SGCMath.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\util\SGDebugDrawCallback.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\util\SGEnlargeBoundingBox.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\math\SGGeoc.hxx"
|
||||
>
|
||||
@@ -531,10 +539,18 @@
|
||||
RelativePath="..\..\simgear\math\SGLimits.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\model\SGMaterialAnimation.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\math\SGMath.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\math\SGMathFwd.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\math\SGMatrix.hxx"
|
||||
>
|
||||
@@ -543,6 +559,18 @@
|
||||
RelativePath="..\..\simgear\math\SGMisc.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\util\SGNodeMasks.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\tgdb\SGOceanTile.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\model\SGOffsetTransform.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\math\SGQuat.hxx"
|
||||
>
|
||||
@@ -551,22 +579,66 @@
|
||||
RelativePath="..\..\simgear\threads\SGQueue.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\tgdb\SGReaderWriterBTG.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\tgdb\SGReaderWriterBTGOptions.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\structure\SGReferenced.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\model\SGRotateTransform.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\model\SGScaleTransform.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\util\SGSceneFeatures.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\util\SGSceneUserData.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\structure\SGSharedPtr.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\util\SGStateAttributeVisitor.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\misc\sgstream.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\util\SGTextureStateAttributeVisitor.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\threads\SGThread.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\model\SGTranslateTransform.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\util\SGUpdateVisitor.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\tgdb\SGVasiDrawable.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\math\SGVec3.hxx"
|
||||
>
|
||||
@@ -583,20 +655,6 @@
|
||||
RelativePath="..\..\simgear\scene\model\shadowvolume.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\simgear_config.h"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description=""
|
||||
CommandLine=""
|
||||
Outputs=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\sky\sky.hxx"
|
||||
>
|
||||
@@ -761,6 +819,10 @@
|
||||
RelativePath="..\..\simgear\scene\sky\bbcache.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\nasal\bitslib.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\ephemeris\celestialBody.cxx"
|
||||
>
|
||||
@@ -793,10 +855,6 @@
|
||||
RelativePath="..\..\simgear\magvar\coremag.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\model\custtrans.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\sky\dome.cxx"
|
||||
>
|
||||
@@ -821,10 +879,6 @@
|
||||
RelativePath="..\..\simgear\screen\extensions.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\math\fastmath.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\nasal\gc.c"
|
||||
>
|
||||
@@ -837,6 +891,14 @@
|
||||
RelativePath="..\..\simgear\screen\GLBitmaps.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\tgdb\GroundLightManager.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\tgdb\GroundLightManager.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\nasal\hash.c"
|
||||
>
|
||||
@@ -858,11 +920,11 @@
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\ephemeris\jupiter.cxx"
|
||||
RelativePath="..\..\simgear\nasal\iolib.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\tgdb\leaf.cxx"
|
||||
RelativePath="..\..\simgear\ephemeris\jupiter.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
@@ -937,6 +999,14 @@
|
||||
RelativePath="..\..\simgear\scene\model\modellib.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\model\ModelRegistry.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\model\ModelRegistry.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\sky\moon.cxx"
|
||||
>
|
||||
@@ -970,7 +1040,15 @@
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\model\personality.cxx"
|
||||
RelativePath="..\..\simgear\misc\PathOptions.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\model\persparam.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\model\persparam.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
@@ -981,10 +1059,6 @@
|
||||
RelativePath="..\..\simgear\scene\model\placementtrans.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\math\polar3d.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\props\props.cxx"
|
||||
>
|
||||
@@ -997,6 +1071,10 @@
|
||||
RelativePath="..\..\simgear\scene\tgdb\pt_lights.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\util\QuadTreeBuilder.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\screen\RenderTexture.cpp"
|
||||
>
|
||||
@@ -1029,10 +1107,6 @@
|
||||
RelativePath="..\..\simgear\io\sg_file.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\math\sg_geodesy.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\misc\sg_path.cxx"
|
||||
>
|
||||
@@ -1057,18 +1131,114 @@
|
||||
RelativePath="..\..\simgear\timing\sg_time.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\structure\SGBinding.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\model\SGClipGroup.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\model\SGClipGroup.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\tgdb\SGDirectionalLightBin.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\util\SGEnlargeBoundingBox.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\math\SGGeodesy.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\tgdb\SGLightBin.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\model\SGMaterialAnimation.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\tgdb\SGModelBin.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\tgdb\SGOceanTile.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\model\SGOffsetTransform.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\tgdb\SGReaderWriterBTG.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\model\SGRotateTransform.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\model\SGScaleTransform.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\util\SGSceneFeatures.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\util\SGSceneUserData.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\structure\SGSmplhist.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\structure\SGSmplstat.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\util\SGStateAttributeVisitor.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\misc\sgstream.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\tgdb\SGTexturedTriangleBin.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\util\SGTextureStateAttributeVisitor.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\threads\SGThread.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\model\SGTranslateTransform.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\tgdb\SGTriangleBin.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\tgdb\SGVasiDrawable.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\tgdb\SGVertexArrayBin.hxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\model\shadanim.cxx"
|
||||
>
|
||||
@@ -1077,10 +1247,6 @@
|
||||
RelativePath="..\..\simgear\screen\shader.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\model\shadowvolume.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\sky\sky.cxx"
|
||||
>
|
||||
@@ -1105,6 +1271,10 @@
|
||||
RelativePath="..\..\simgear\scene\sky\stars.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\scene\util\StateAttributeFactory.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\nasal\string.c"
|
||||
>
|
||||
@@ -1137,6 +1307,10 @@
|
||||
RelativePath="..\..\simgear\nasal\thread-win32.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\nasal\threadlib.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\timing\timestamp.cxx"
|
||||
>
|
||||
@@ -1157,6 +1331,10 @@
|
||||
RelativePath="..\..\simgear\scene\tgdb\userdata.cxx"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\nasal\utf8lib.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\simgear\nasal\vector.c"
|
||||
>
|
||||
@@ -1214,6 +1392,28 @@
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath="..\..\simgear\simgear_config.h-msvc71"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="copy "$(InputPath)" "$(InputDir)\$(InputName).h"
"
|
||||
Outputs=""${InputDir}\$(InputName).h""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="copy "$(InputPath)" "$(InputDir)\$(InputName).h"
"
|
||||
Outputs="${InputDir}\$(InputName).h"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
|
||||
@@ -7,10 +7,10 @@ endif
|
||||
# METAR_DIRS =
|
||||
METAR_DIRS = environment
|
||||
|
||||
EXTRA_DIST = simgear_config.h.vc5 version.h.in
|
||||
EXTRA_DIST = simgear_config.h.vc5 simgear_config.h-msvc71 version.h.in
|
||||
|
||||
include_HEADERS = \
|
||||
compiler.h constants.h sg_inlines.h sg_traits.hxx version.h
|
||||
compiler.h constants.h sg_inlines.h version.h
|
||||
|
||||
SUBDIRS = \
|
||||
$(compatibility_DIR) \
|
||||
@@ -34,4 +34,4 @@ SUBDIRS = \
|
||||
$(SGTHREAD_DIR) \
|
||||
timing
|
||||
|
||||
DIST_SUBDIRS = $(SUBDIRS) compatibility threads
|
||||
DIST_SUBDIRS = $(SUBDIRS) compatibility
|
||||
|
||||
@@ -11,7 +11,7 @@ libsgbucket_a_SOURCES = newbucket.cxx
|
||||
# testbucket_SOURCES = testbucket.cxx
|
||||
|
||||
# testbucket_LDADD = \
|
||||
# $(top_builddir)/bucket/libsgbucket.a \
|
||||
# libsgbucket.a \
|
||||
# $(top_builddir)/misc/libsgmisc.a
|
||||
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
|
||||
@@ -44,6 +44,9 @@ SGBucket::SGBucket(const double dlon, const double dlat) {
|
||||
set_bucket(dlon, dlat);
|
||||
}
|
||||
|
||||
SGBucket::SGBucket(const SGGeod& geod) {
|
||||
set_bucket(geod);
|
||||
}
|
||||
|
||||
// create an impossible bucket if false
|
||||
SGBucket::SGBucket(const bool is_good) {
|
||||
@@ -73,11 +76,6 @@ SGBucket::SGBucket(const long int bindex) {
|
||||
}
|
||||
|
||||
|
||||
// default destructor
|
||||
SGBucket::~SGBucket() {
|
||||
}
|
||||
|
||||
|
||||
// Set the bucket params for the specified lat and lon
|
||||
void SGBucket::set_bucket( double *lonlat ) {
|
||||
set_bucket( lonlat[0], lonlat[1] );
|
||||
@@ -135,6 +133,11 @@ void SGBucket::set_bucket( double dlon, double dlat ) {
|
||||
}
|
||||
|
||||
|
||||
void SGBucket::set_bucket(const SGGeod& geod)
|
||||
{
|
||||
set_bucket(geod.getLongitudeDeg(), geod.getLatitudeDeg());
|
||||
}
|
||||
|
||||
// Build the path name for this bucket
|
||||
string SGBucket::gen_base_path() const {
|
||||
// long int index;
|
||||
|
||||
@@ -31,30 +31,12 @@
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
#include <simgear/constants.h>
|
||||
#include <simgear/math/SGMath.hxx>
|
||||
|
||||
#ifdef SG_HAVE_STD_INCLUDES
|
||||
# include <cmath>
|
||||
# include <cstdio> // sprintf()
|
||||
#else
|
||||
# include <math.h>
|
||||
# include <stdio.h> // sprintf()
|
||||
#endif
|
||||
|
||||
#include STL_IOSTREAM
|
||||
|
||||
// I don't understand ... <math.h> or <cmath> should be included
|
||||
// already depending on how you defined SG_HAVE_STD_INCLUDES, but I
|
||||
// can go ahead and add this -- CLO
|
||||
#ifdef __MWERKS__
|
||||
SG_USING_STD(sprintf);
|
||||
SG_USING_STD(fabs);
|
||||
#endif
|
||||
|
||||
#include STL_STRING
|
||||
|
||||
SG_USING_STD(string);
|
||||
SG_USING_STD(ostream);
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdio> // sprintf()
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* standard size of a bucket in degrees (1/8 of a degree)
|
||||
@@ -133,6 +115,13 @@ public:
|
||||
*/
|
||||
SGBucket(const double dlon, const double dlat);
|
||||
|
||||
/**
|
||||
* Construct a bucket given a specific location.
|
||||
* @param dlon longitude specified in degrees
|
||||
* @param dlat latitude specified in degrees
|
||||
*/
|
||||
SGBucket(const SGGeod& geod);
|
||||
|
||||
/** Construct a bucket.
|
||||
* @param is_good if false, create an invalid bucket. This is
|
||||
* useful * if you are comparing cur_bucket to last_bucket and
|
||||
@@ -146,11 +135,6 @@ public:
|
||||
*/
|
||||
SGBucket(const long int bindex);
|
||||
|
||||
/**
|
||||
* Default destructor.
|
||||
*/
|
||||
~SGBucket();
|
||||
|
||||
/**
|
||||
* Reset a bucket to represent a new lat and lon
|
||||
* @param dlon longitude specified in degrees
|
||||
@@ -165,6 +149,13 @@ public:
|
||||
*/
|
||||
void set_bucket( double *lonlat );
|
||||
|
||||
/**
|
||||
* Reset a bucket to represent a new lat and lon
|
||||
* @param dlon longitude specified in degrees
|
||||
* @param dlat latitude specified in degrees
|
||||
*/
|
||||
void set_bucket(const SGGeod& geod);
|
||||
|
||||
/**
|
||||
* Create an impossible bucket.
|
||||
* This is useful if you are comparing cur_bucket to last_bucket
|
||||
@@ -200,18 +191,19 @@ public:
|
||||
* string form.
|
||||
* @return tile index in string form
|
||||
*/
|
||||
inline string gen_index_str() const {
|
||||
inline std::string gen_index_str() const {
|
||||
char tmp[20];
|
||||
sprintf(tmp, "%ld",
|
||||
(((long)lon + 180) << 14) + ((lat + 90) << 6) + (y << 3) + x);
|
||||
return (string)tmp;
|
||||
std::sprintf(tmp, "%ld",
|
||||
(((long)lon + 180) << 14) + ((lat + 90) << 6)
|
||||
+ (y << 3) + x);
|
||||
return (std::string)tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the base path name for this bucket.
|
||||
* @return base path in string form
|
||||
*/
|
||||
string gen_base_path() const;
|
||||
std::string gen_base_path() const;
|
||||
|
||||
/**
|
||||
* @return the center lon of a tile.
|
||||
@@ -252,7 +244,24 @@ public:
|
||||
* @return the height of the tile in meters.
|
||||
*/
|
||||
double get_height_m() const;
|
||||
|
||||
|
||||
/**
|
||||
* @return the center of the bucket in geodetic coordinates.
|
||||
*/
|
||||
SGGeod get_center() const
|
||||
{ return SGGeod::fromDeg(get_center_lon(), get_center_lat()); }
|
||||
|
||||
/**
|
||||
* @return the center of the bucket in geodetic coordinates.
|
||||
*/
|
||||
SGGeod get_corner(unsigned num) const
|
||||
{
|
||||
double lonFac = ((num + 1) & 2) ? 0.5 : -0.5;
|
||||
double latFac = ((num ) & 2) ? 0.5 : -0.5;
|
||||
return SGGeod::fromDeg(get_center_lon() + lonFac*get_width(),
|
||||
get_center_lat() + latFac*get_height());
|
||||
}
|
||||
|
||||
// Informational methods.
|
||||
|
||||
/**
|
||||
@@ -279,10 +288,15 @@ public:
|
||||
|
||||
// friends
|
||||
|
||||
friend ostream& operator<< ( ostream&, const SGBucket& );
|
||||
friend std::ostream& operator<< ( std::ostream&, const SGBucket& );
|
||||
friend bool operator== ( const SGBucket&, const SGBucket& );
|
||||
};
|
||||
|
||||
inline bool operator!= (const SGBucket& lhs, const SGBucket& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \relates SGBucket
|
||||
@@ -313,8 +327,8 @@ void sgBucketDiff( const SGBucket& b1, const SGBucket& b2, int *dx, int *dy );
|
||||
* @param out output stream
|
||||
* @param b bucket
|
||||
*/
|
||||
inline ostream&
|
||||
operator<< ( ostream& out, const SGBucket& b )
|
||||
inline std::ostream&
|
||||
operator<< ( std::ostream& out, const SGBucket& b )
|
||||
{
|
||||
return out << b.lon << ":" << b.x << ", " << b.lat << ":" << b.y;
|
||||
}
|
||||
|
||||
@@ -23,48 +23,9 @@
|
||||
* A set of defines to encapsulate compiler and platform differences.
|
||||
* Please refer to the source code for full documentation on this file.
|
||||
*
|
||||
* Here is a summary of what this file does.
|
||||
* This file is useful to set compiler-specific options in every file - for
|
||||
* example, disabling warnings.
|
||||
*
|
||||
* (1) Defines macros for some STL includes which may be affected
|
||||
* by file name length limitations.
|
||||
*
|
||||
* (2) Defines macros for some features not supported by all C++ compilers.
|
||||
*
|
||||
* (3) Defines 'explicit' as a null macro if the compiler doesn't support
|
||||
* the explicit keyword.
|
||||
*
|
||||
* (4) Defines 'typename' as a null macro if the compiler doesn't support
|
||||
* the typename keyword.
|
||||
*
|
||||
* (5) Defines bool, true and false if the compiler doesn't do so.
|
||||
*
|
||||
* (6) Defines SG_EXPLICIT_FUNCTION_TMPL_ARGS if the compiler
|
||||
* supports calling a function template by providing its template
|
||||
* arguments explicitly.
|
||||
*
|
||||
* (7) Defines SG_NEED_AUTO_PTR if STL doesn't provide auto_ptr<>.
|
||||
*
|
||||
* (8) Defines SG_NO_ARROW_OPERATOR if the compiler is unable
|
||||
* to support operator->() for iterators.
|
||||
*
|
||||
* (9) Defines SG_USE_EXCEPTIONS if the compiler supports exceptions.
|
||||
* Note: no FlightGear code uses exceptions.
|
||||
*
|
||||
* (10) Define SG_NAMESPACES if the compiler supports namespaces.
|
||||
*
|
||||
* (11) SG_MATH_FN_IN_NAMESPACE_STD -- not used??
|
||||
*
|
||||
* (12) Define SG_HAVE_STD if std namespace is supported.
|
||||
*
|
||||
* (13) Defines SG_CLASS_PARTIAL_SPECIALIZATION if the compiler
|
||||
* supports partial specialization of class templates.
|
||||
*
|
||||
* (14) Defines SG_HAVE_STD_INCLUDES to use ISO C++ Standard headers.
|
||||
*
|
||||
* (15) Defines SG_HAVE_STREAMBUF if <streambuf> of <streambuf.h> are present.
|
||||
*
|
||||
* (16) Define SG_MATH_EXCEPTION_CLASH if math.h defines an exception class
|
||||
* that clashes with the one defined in <stdexcept>.
|
||||
*/
|
||||
|
||||
#ifndef _SG_COMPILER_H
|
||||
@@ -79,157 +40,30 @@
|
||||
#define SG_DO_STRINGIZE(X) #X
|
||||
|
||||
#ifdef __GNUC__
|
||||
# if __GNUC__ == 2
|
||||
# if __GNUC_MINOR__ < 8
|
||||
|
||||
// g++-2.7.x
|
||||
# define STL_ALGORITHM <algorithm>
|
||||
# define STL_FUNCTIONAL <functional>
|
||||
# define STL_IOMANIP <iomanip.h>
|
||||
# define STL_IOSTREAM <iostream.h>
|
||||
# define STL_ITERATOR <iterator.h>
|
||||
# define STL_FSTREAM <fstream.h>
|
||||
# define STL_STDEXCEPT <stdexcept>
|
||||
# define STL_STRING <string>
|
||||
# define STL_STRSTREAM <strstream.h>
|
||||
|
||||
# define SG_NEED_AUTO_PTR
|
||||
# define SG_NO_DEFAULT_TEMPLATE_ARGS
|
||||
# define SG_INCOMPLETE_FUNCTIONAL
|
||||
# define SG_NO_ARROW_OPERATOR
|
||||
|
||||
# elif __GNUC_MINOR__ >= 8
|
||||
|
||||
// g++-2.8.x and egcs-1.x
|
||||
# define SG_EXPLICIT_FUNCTION_TMPL_ARGS
|
||||
# define SG_NEED_AUTO_PTR
|
||||
# define SG_MEMBER_TEMPLATES
|
||||
# define SG_NAMESPACES
|
||||
# define SG_HAVE_STD
|
||||
# define SG_HAVE_STREAMBUF
|
||||
# define SG_CLASS_PARTIAL_SPECIALIZATION
|
||||
|
||||
# define STL_ALGORITHM <algorithm>
|
||||
# define STL_FUNCTIONAL <functional>
|
||||
# define STL_IOMANIP <iomanip>
|
||||
# define STL_IOSTREAM <iostream>
|
||||
# define STL_ITERATOR <iterator>
|
||||
# define STL_FSTREAM <fstream>
|
||||
# define STL_STDEXCEPT <stdexcept>
|
||||
# define STL_STRING <string>
|
||||
# define STL_STRSTREAM <strstream>
|
||||
|
||||
# endif
|
||||
# elif __GNUC__ >= 3
|
||||
// g++-3.0.x
|
||||
# define SG_EXPLICIT_FUNCTION_TMPL_ARGS
|
||||
# define SG_NEED_AUTO_PTR
|
||||
# define SG_MEMBER_TEMPLATES
|
||||
# define SG_NAMESPACES
|
||||
# define SG_HAVE_STD
|
||||
# define SG_HAVE_STREAMBUF
|
||||
# define SG_CLASS_PARTIAL_SPECIALIZATION
|
||||
# define SG_HAVE_STD_INCLUDES
|
||||
|
||||
# define STL_ALGORITHM <algorithm>
|
||||
# define STL_FUNCTIONAL <functional>
|
||||
# define STL_IOMANIP <iomanip>
|
||||
# define STL_IOSTREAM <iostream>
|
||||
# define STL_ITERATOR <iterator>
|
||||
# define STL_FSTREAM <fstream>
|
||||
# define STL_STDEXCEPT <stdexcept>
|
||||
# define STL_STRING <string>
|
||||
# define STL_STRSTREAM <strstream>
|
||||
# else
|
||||
# error Time to upgrade. GNU compilers < 2.7 not supported
|
||||
# if __GNUC__ < 3
|
||||
# error Time to upgrade. GNU compilers < 3.0 not supported
|
||||
# elif (__GNUC__ == 3) && (__GNUC_MINOR__ < 4)
|
||||
# warning GCC compilers prior to 3.4 are suspect
|
||||
# endif
|
||||
|
||||
# define SG_COMPILER_STR "GNU C++ version " SG_STRINGIZE(__GNUC__) "." SG_STRINGIZE(__GNUC_MINOR__)
|
||||
|
||||
#endif // __GNUC__
|
||||
|
||||
/* KAI C++ */
|
||||
#if defined(__KCC)
|
||||
|
||||
# define SG_NAMESPACES
|
||||
# define SG_HAVE_STD
|
||||
# define SG_HAVE_STREAMBUF
|
||||
# define SG_HAVE_TRAITS
|
||||
# define SG_HAVE_STD_INCLUDES
|
||||
|
||||
# define STL_ALGORITHM <algorithm>
|
||||
# define STL_FUNCTIONAL <functional>
|
||||
# define STL_IOMANIP <iomanip>
|
||||
# define STL_IOSTREAM <iostream>
|
||||
# define STL_ITERATOR <iterator>
|
||||
# define STL_FSTREAM <fstream>
|
||||
# define STL_STDEXCEPT <stdexcept>
|
||||
# define STL_STRING <string>
|
||||
# define STL_STRSTREAM <strstream>
|
||||
|
||||
# define SG_COMPILER_STR "Kai C++ version " SG_STRINGIZE(__KCC_VERSION)
|
||||
|
||||
#endif // __KCC
|
||||
|
||||
//
|
||||
// Metrowerks
|
||||
//
|
||||
#if defined(__MWERKS__)
|
||||
/*
|
||||
CodeWarrior compiler from Metrowerks, Inc.
|
||||
*/
|
||||
# define SG_HAVE_TRAITS
|
||||
# define SG_HAVE_STD_INCLUDES
|
||||
# define SG_HAVE_STD
|
||||
# define SG_NAMESPACES
|
||||
|
||||
# define STL_ALGORITHM <algorithm>
|
||||
# define STL_FUNCTIONAL <functional>
|
||||
# define STL_IOMANIP <iomanip>
|
||||
# define STL_IOSTREAM <iostream>
|
||||
# define STL_ITERATOR <iterator>
|
||||
# define STL_FSTREAM <fstream>
|
||||
# define STL_STDEXCEPT <stdexcept>
|
||||
# define STL_STRING <string>
|
||||
|
||||
// Temp:
|
||||
# define bcopy(from, to, n) memcpy(to, from, n)
|
||||
|
||||
// -rp- please use FG_MEM_COPY everywhere !
|
||||
// #define FG_MEM_COPY(to,from,n) memcpy(to, from, n)
|
||||
|
||||
// -dw- currently used glut has no game mode stuff
|
||||
# define GLUT_WRONG_VERSION
|
||||
|
||||
# define SG_COMPILER_STR "Metrowerks CodeWarrior C++ version " SG_STRINGIZE(__MWERKS__)
|
||||
|
||||
#endif // __MWERKS__
|
||||
|
||||
//
|
||||
// Microsoft compilers.
|
||||
//
|
||||
#ifdef _MSC_VER
|
||||
# define bcopy(from, to, n) memcpy(to, from, n)
|
||||
# define FG_MEM_COPY(to,from,n) memcpy(to, from, n)
|
||||
|
||||
# if _MSC_VER >= 1200 // msvc++ 6.0 or greater
|
||||
# define SG_NAMESPACES
|
||||
# define SG_HAVE_STD
|
||||
# define SG_HAVE_STD_INCLUDES
|
||||
# define SG_HAVE_STREAMBUF
|
||||
|
||||
# define STL_ALGORITHM <algorithm>
|
||||
# define STL_FUNCTIONAL <functional>
|
||||
# define STL_IOMANIP <iomanip>
|
||||
# define STL_IOSTREAM <iostream>
|
||||
# define STL_ITERATOR <iterator>
|
||||
# define STL_FSTREAM <fstream>
|
||||
# define STL_STDEXCEPT <stdexcept>
|
||||
# define STL_STRING <string>
|
||||
# define STL_STRSTREAM <strstream>
|
||||
|
||||
# define isnan _isnan
|
||||
# define snprintf _snprintf
|
||||
# define copysign _copysign
|
||||
|
||||
# pragma warning(disable: 4786) // identifier was truncated to '255' characters
|
||||
# pragma warning(disable: 4244) // conversion from double to float
|
||||
@@ -243,79 +77,23 @@
|
||||
|
||||
#endif // _MSC_VER
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
# if defined(HAVE_SGI_STL_PORT)
|
||||
|
||||
// Use quotes around long file names to get around Borland's include hackery
|
||||
|
||||
# define STL_ALGORITHM "algorithm"
|
||||
# define STL_FUNCTIONAL "functional"
|
||||
|
||||
# define SG_MATH_EXCEPTION_CLASH
|
||||
|
||||
# else
|
||||
|
||||
# define STL_ALGORITHM <algorithm>
|
||||
# define STL_FUNCTIONAL <functional>
|
||||
# define STL_IOMANIP <iomanip>
|
||||
# define STL_STDEXCEPT <stdexcept>
|
||||
# define STL_STRSTREAM <strstream>
|
||||
|
||||
# define SG_INCOMPLETE_FUNCTIONAL
|
||||
|
||||
# endif // HAVE_SGI_STL_PORT
|
||||
|
||||
# define STL_IOSTREAM <iostream>
|
||||
# define STL_ITERATOR <iterator>
|
||||
# define STL_FSTREAM <fstream>
|
||||
# define STL_STRING <string>
|
||||
# define SG_NO_DEFAULT_TEMPLATE_ARGS
|
||||
# define SG_NAMESPACES
|
||||
// # define SG_HAVE_STD
|
||||
|
||||
# define SG_COMPILER_STR "Borland C++ version " SG_STRINGIZE(__BORLANDC__)
|
||||
|
||||
#endif // __BORLANDC__
|
||||
|
||||
//
|
||||
// Native SGI compilers
|
||||
//
|
||||
|
||||
#if defined ( sgi ) && !defined( __GNUC__ )
|
||||
# define SG_HAVE_NATIVE_SGI_COMPILERS
|
||||
# if (_COMPILER_VERSION < 740)
|
||||
# error Need MipsPro 7.4.0 or higher now
|
||||
# endif
|
||||
|
||||
# define SG_EXPLICIT_FUNCTION_TMPL_ARGS
|
||||
# define SG_CLASS_PARTIAL_SPECIALIZATION
|
||||
# define SG_NEED_AUTO_PTR
|
||||
# define SG_MEMBER_TEMPLATES
|
||||
# define SG_NAMESPACES
|
||||
# define SG_HAVE_STD
|
||||
# define SG_HAVE_STREAMBUF
|
||||
# define SG_HAVE_TRAITS
|
||||
# define SG_HAVE_STD_INCLUDES
|
||||
|
||||
# define STL_ALGORITHM <algorithm>
|
||||
# define STL_FUNCTIONAL <functional>
|
||||
# define STL_IOMANIP <iomanip>
|
||||
# define STL_IOSTREAM <iostream>
|
||||
# define STL_ITERATOR <iterator>
|
||||
# define STL_FSTREAM <fstream>
|
||||
# define STL_STDEXCEPT <stdexcept>
|
||||
#if (_COMPILER_VERSION < 740)
|
||||
# define STL_STRING <irix_string>
|
||||
#else
|
||||
# define STL_STRING <string>
|
||||
#endif
|
||||
# define STL_STRSTREAM <strstream>
|
||||
#define SG_HAVE_NATIVE_SGI_COMPILERS
|
||||
|
||||
#pragma set woff 1001,1012,1014,1116,1155,1172,1174
|
||||
#pragma set woff 1401,1460,1551,1552,1681
|
||||
|
||||
#ifdef __cplusplus
|
||||
#pragma set woff 1682,3303
|
||||
#if (_COMPILER_VERSION >= 740)
|
||||
# pragma set woff 3624
|
||||
#endif
|
||||
# pragma set woff 1682,3303
|
||||
# pragma set woff 3624
|
||||
#endif
|
||||
|
||||
# define SG_COMPILER_STR "SGI MipsPro compiler version " SG_STRINGIZE(_COMPILER_VERSION)
|
||||
@@ -345,24 +123,7 @@
|
||||
// Intel C++ Compiler
|
||||
//
|
||||
#if defined(__ICC) || defined (__ECC)
|
||||
# define SG_NAMESPACES
|
||||
# define SG_HAVE_STD
|
||||
# define SG_HAVE_STREAMBUF
|
||||
# define SG_HAVE_TRAITS
|
||||
# define SG_HAVE_STD_INCLUDES
|
||||
|
||||
# define STL_ALGORITHM <algorithm>
|
||||
# define STL_FUNCTIONAL <functional>
|
||||
# define STL_IOMANIP <iomanip>
|
||||
# define STL_IOSTREAM <iostream>
|
||||
# define STL_ITERATOR <iterator>
|
||||
# define STL_FSTREAM <fstream>
|
||||
# define STL_STDEXCEPT <stdexcept>
|
||||
# define STL_STRING <string>
|
||||
# define STL_STRSTREAM <strstream>
|
||||
|
||||
# define SG_COMPILER_STR "Intel C++ version " SG_STRINGIZE(__ICC)
|
||||
|
||||
#endif // __ICC
|
||||
|
||||
//
|
||||
@@ -370,19 +131,9 @@
|
||||
//
|
||||
|
||||
#ifdef __APPLE__
|
||||
# define SG_GL_H <OpenGL/gl.h>
|
||||
# define SG_GLX_H <AGL/agl.h>
|
||||
# define SG_GLU_H <OpenGL/glu.h>
|
||||
# define SG_GLEXT_H <OpenGL/glext.h>
|
||||
# define SG_GLUT_H <GLUT/glut.h>
|
||||
|
||||
inline int (isnan)(double r) { return !(r <= 0 || r >= 0); }
|
||||
#else
|
||||
# define SG_GL_H <GL/gl.h>
|
||||
# define SG_GLX_H <GL/glx.h>
|
||||
# define SG_GLU_H <GL/glu.h>
|
||||
# define SG_GLEXT_H <GL/glext.h>
|
||||
# define SG_GLUT_H <GL/glut.h>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -390,81 +141,5 @@ inline int (isnan)(double r) { return !(r <= 0 || r >= 0); }
|
||||
// No user modifiable definitions beyond here.
|
||||
//
|
||||
|
||||
#ifdef SG_NEED_EXPLICIT
|
||||
# define explicit
|
||||
#endif
|
||||
|
||||
#ifdef SG_NEED_TYPENAME
|
||||
# define typename
|
||||
#endif
|
||||
|
||||
#ifdef SG_NEED_MUTABLE
|
||||
# define mutable
|
||||
#endif
|
||||
|
||||
#ifdef SG_NEED_BOOL
|
||||
typedef int bool;
|
||||
# define true 1
|
||||
# define false 0
|
||||
#endif
|
||||
|
||||
#ifdef SG_EXPLICIT_FUNCTION_TMPL_ARGS
|
||||
# define SG_NULL_TMPL_ARGS <>
|
||||
#else
|
||||
# define SG_NULL_TMPL_ARGS
|
||||
#endif
|
||||
|
||||
#ifdef SG_CLASS_PARTIAL_SPECIALIZATION
|
||||
# define SG_TEMPLATE_NULL template<>
|
||||
#else
|
||||
# define SG_TEMPLATE_NULL
|
||||
#endif
|
||||
|
||||
// SG_NO_NAMESPACES is a hook so that users can disable namespaces
|
||||
// without having to edit library headers.
|
||||
#if defined(SG_NAMESPACES) && !defined(SG_NO_NAMESPACES)
|
||||
# define SG_NAMESPACE(X) namespace X {
|
||||
# define SG_NAMESPACE_END }
|
||||
# define SG_USING_NAMESPACE(X) using namespace X
|
||||
# else
|
||||
# define SG_NAMESPACE(X)
|
||||
# define SG_NAMESPACE_END
|
||||
# define SG_USING_NAMESPACE(X)
|
||||
#endif
|
||||
|
||||
/** \def SG_USING_STD(x)
|
||||
* Expands to using std::x if SG_HAVE_STD is defined
|
||||
*/
|
||||
# ifdef SG_HAVE_STD
|
||||
# define SG_USING_STD(X) using std::X
|
||||
# define STD std
|
||||
# else
|
||||
# define SG_USING_STD(X)
|
||||
# define STD
|
||||
# endif
|
||||
|
||||
// Additional <functional> implementation from SGI STL 3.11
|
||||
// Adapter function objects: pointers to member functions
|
||||
#ifdef SG_INCOMPLETE_FUNCTIONAL
|
||||
|
||||
template <class _Ret, class _Tp>
|
||||
class const_mem_fun_ref_t
|
||||
#ifndef __BORLANDC__
|
||||
: public unary_function<_Tp,_Ret>
|
||||
#endif // __BORLANDC__
|
||||
{
|
||||
public:
|
||||
explicit const_mem_fun_ref_t(_Ret (_Tp::*__pf)() const) : _M_f(__pf) {}
|
||||
_Ret operator()(const _Tp& __r) const { return (__r.*_M_f)(); }
|
||||
private:
|
||||
_Ret (_Tp::*_M_f)() const;
|
||||
};
|
||||
|
||||
template <class _Ret, class _Tp>
|
||||
inline const_mem_fun_ref_t<_Ret,_Tp> mem_fun_ref(_Ret (_Tp::*__f)() const)
|
||||
{ return const_mem_fun_ref_t<_Ret,_Tp>(__f); }
|
||||
|
||||
#endif // SG_INCOMPLETE_FUNCTIONAL
|
||||
|
||||
#endif // _SG_COMPILER_H
|
||||
|
||||
|
||||
@@ -31,14 +31,8 @@
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#ifdef SG_HAVE_STD_INCLUDES
|
||||
# include <cmath>
|
||||
#else
|
||||
# ifdef SG_MATH_EXCEPTION_CLASH
|
||||
# define exception C_exception
|
||||
# endif
|
||||
# include <math.h>
|
||||
#endif
|
||||
#include <cmath>
|
||||
|
||||
|
||||
#include <plib/sg.h>
|
||||
|
||||
@@ -75,6 +69,8 @@
|
||||
* 6378.165 but this is probably close enough */
|
||||
#define SG_EARTH_RAD 6378.155
|
||||
|
||||
// Maximum terrain elevation from sea level
|
||||
#define SG_MAX_ELEVATION_M 9000.0
|
||||
|
||||
// Earth parameters for WGS 84, taken from LaRCsim/ls_constants.h
|
||||
|
||||
@@ -128,6 +124,12 @@
|
||||
/** Knots to Miles per second */
|
||||
#define SG_KT_TO_MPS 0.5144444444444444444
|
||||
|
||||
/** Feet per second to Knots */
|
||||
#define SG_FPS_TO_KT 0.5924838012958962841
|
||||
|
||||
/** Knots to Feet per second */
|
||||
#define SG_KT_TO_FPS 1.6878098571011956874
|
||||
|
||||
/** Miles per second to Miles per hour */
|
||||
#define SG_MPS_TO_MPH 2.2369362920544020312
|
||||
|
||||
|
||||
@@ -20,15 +20,31 @@
|
||||
//
|
||||
// $Id$
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "logstream.hxx"
|
||||
|
||||
logstream *global_logstream = NULL;
|
||||
logstream *logstream::global_logstream = 0;
|
||||
|
||||
bool logbuf::logging_enabled = true;
|
||||
#ifdef _MSC_VER
|
||||
bool logbuf::has_console = true;
|
||||
#endif
|
||||
sgDebugClass logbuf::logClass = SG_NONE;
|
||||
sgDebugPriority logbuf::logPriority = SG_INFO;
|
||||
streambuf* logbuf::sbuf = NULL;
|
||||
|
||||
namespace {
|
||||
struct ignore_me
|
||||
{
|
||||
ignore_me()
|
||||
{
|
||||
logstream::initGlobalLogstream();
|
||||
}
|
||||
};
|
||||
static ignore_me im;
|
||||
}
|
||||
|
||||
logbuf::logbuf()
|
||||
{
|
||||
// if ( sbuf == NULL )
|
||||
@@ -87,3 +103,12 @@ logstream::setLogLevels( sgDebugClass c, sgDebugPriority p )
|
||||
logbuf::set_log_level( c, p );
|
||||
}
|
||||
|
||||
logstream *
|
||||
logstream::initGlobalLogstream()
|
||||
{
|
||||
// Force initialization of cerr.
|
||||
static std::ios_base::Init initializer;
|
||||
if( !global_logstream )
|
||||
global_logstream = new logstream(std::cerr);
|
||||
return global_logstream;
|
||||
}
|
||||
|
||||
@@ -31,25 +31,13 @@
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef SG_HAVE_STD_INCLUDES
|
||||
# include <streambuf>
|
||||
# include <iostream>
|
||||
#else
|
||||
# include <iostream.h>
|
||||
# include <simgear/sg_traits.hxx>
|
||||
#endif
|
||||
#include <streambuf>
|
||||
#include <ostream>
|
||||
|
||||
#include <simgear/debug/debug_types.h>
|
||||
|
||||
SG_USING_STD(streambuf);
|
||||
SG_USING_STD(ostream);
|
||||
SG_USING_STD(cout);
|
||||
SG_USING_STD(cerr);
|
||||
SG_USING_STD(endl);
|
||||
|
||||
#ifdef __MWERKS__
|
||||
SG_USING_STD(iostream);
|
||||
#endif
|
||||
using std::streambuf;
|
||||
using std::ostream;
|
||||
|
||||
//
|
||||
// TODO:
|
||||
@@ -67,17 +55,10 @@ SG_USING_STD(iostream);
|
||||
#ifdef SG_NEED_STREAMBUF_HACK
|
||||
class logbuf : public __streambuf
|
||||
#else
|
||||
class logbuf : public streambuf
|
||||
class logbuf : public std::streambuf
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
|
||||
#ifndef SG_HAVE_STD_INCLUDES
|
||||
typedef char_traits<char> traits_type;
|
||||
typedef char_traits<char>::int_type int_type;
|
||||
// typedef char_traits<char>::pos_type pos_type;
|
||||
// typedef char_traits<char>::off_type off_type;
|
||||
#endif
|
||||
// logbuf( streambuf* sb ) : sbuf(sb) {}
|
||||
/** Constructor */
|
||||
logbuf();
|
||||
@@ -97,6 +78,8 @@ public:
|
||||
*/
|
||||
void set_log_state( sgDebugClass c, sgDebugPriority p );
|
||||
|
||||
bool would_log( sgDebugClass c, sgDebugPriority p ) const;
|
||||
|
||||
/**
|
||||
* Set the global logging level.
|
||||
* @param c debug class
|
||||
@@ -137,7 +120,11 @@ public:
|
||||
* Set the stream buffer
|
||||
* @param sb stream buffer
|
||||
*/
|
||||
void set_sb( streambuf* sb );
|
||||
void set_sb( std::streambuf* sb );
|
||||
|
||||
#ifdef _MSC_VER
|
||||
static void has_no_console() { has_console = false; }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
@@ -151,9 +138,12 @@ protected:
|
||||
private:
|
||||
|
||||
// The streambuf used for actual output. Defaults to cerr.rdbuf().
|
||||
static streambuf* sbuf;
|
||||
static std::streambuf* sbuf;
|
||||
|
||||
static bool logging_enabled;
|
||||
#ifdef _MSC_VER
|
||||
static bool has_console;
|
||||
#endif
|
||||
static sgDebugClass logClass;
|
||||
static sgDebugPriority logPriority;
|
||||
|
||||
@@ -167,11 +157,7 @@ private:
|
||||
inline int
|
||||
logbuf::sync()
|
||||
{
|
||||
#ifdef SG_HAVE_STD_INCLUDES
|
||||
return sbuf->pubsync();
|
||||
#else
|
||||
return sbuf->sync();
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void
|
||||
@@ -180,11 +166,16 @@ logbuf::set_log_state( sgDebugClass c, sgDebugPriority p )
|
||||
logging_enabled = ((c & logClass) != 0 && p >= logPriority);
|
||||
}
|
||||
|
||||
inline bool
|
||||
logbuf::would_log( sgDebugClass c, sgDebugPriority p ) const
|
||||
{
|
||||
return ((c & logClass) != 0 && p >= logPriority);
|
||||
}
|
||||
|
||||
inline logbuf::int_type
|
||||
logbuf::overflow( int c )
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
static bool has_console = false;
|
||||
if ( logging_enabled ) {
|
||||
if ( !has_console ) {
|
||||
AllocConsole();
|
||||
@@ -232,23 +223,23 @@ struct logstream_base
|
||||
/**
|
||||
* Class to manage the debug logging stream.
|
||||
*/
|
||||
class logstream : private logstream_base, public ostream
|
||||
class logstream : private logstream_base, public std::ostream
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* The default is to send messages to cerr.
|
||||
* @param out output stream
|
||||
*/
|
||||
logstream( ostream& out )
|
||||
logstream( std::ostream& out )
|
||||
// : logstream_base(out.rdbuf()),
|
||||
: logstream_base(),
|
||||
ostream(&lbuf) { lbuf.set_sb(out.rdbuf());}
|
||||
std::ostream(&lbuf) { lbuf.set_sb(out.rdbuf());}
|
||||
|
||||
/**
|
||||
* Set the output stream
|
||||
* @param out output stream
|
||||
*/
|
||||
void set_output( ostream& out ) { lbuf.set_sb( out.rdbuf() ); }
|
||||
void set_output( std::ostream& out ) { lbuf.set_sb( out.rdbuf() ); }
|
||||
|
||||
/**
|
||||
* Set the global log class and priority level.
|
||||
@@ -257,22 +248,29 @@ public:
|
||||
*/
|
||||
void setLogLevels( sgDebugClass c, sgDebugPriority p );
|
||||
|
||||
bool would_log( sgDebugClass c, sgDebugPriority p ) const
|
||||
{
|
||||
return lbuf.would_log( c, p );
|
||||
};
|
||||
|
||||
/**
|
||||
* Output operator to capture the debug level and priority of a message.
|
||||
* @param l log level
|
||||
*/
|
||||
inline ostream& operator<< ( const loglevel& l );
|
||||
inline std::ostream& operator<< ( const loglevel& l );
|
||||
friend logstream& sglog();
|
||||
static logstream *initGlobalLogstream();
|
||||
protected:
|
||||
static logstream *global_logstream;
|
||||
};
|
||||
|
||||
inline ostream&
|
||||
inline std::ostream&
|
||||
logstream::operator<< ( const loglevel& l )
|
||||
{
|
||||
lbuf.set_log_state( l.logClass, l.logPriority );
|
||||
return *this;
|
||||
}
|
||||
|
||||
extern logstream *global_logstream;
|
||||
|
||||
/**
|
||||
* \relates logstream
|
||||
* Return the one and only logstream instance.
|
||||
@@ -283,22 +281,7 @@ extern logstream *global_logstream;
|
||||
inline logstream&
|
||||
sglog()
|
||||
{
|
||||
if (global_logstream == NULL) {
|
||||
|
||||
#ifdef __APPLE__
|
||||
/**
|
||||
* There appears to be a bug in the C++ runtime in Mac OS X that
|
||||
* will crash if certain funtions are called (in this case
|
||||
* cerr.rdbuf()) during static initialization of a class. This
|
||||
* print statement is hack to kick the library in the pants so it
|
||||
* won't crash when cerr.rdbuf() is first called -DW
|
||||
**/
|
||||
cout << "Using Mac OS X hack for initializing C++ stdio..." << endl;
|
||||
#endif
|
||||
global_logstream = new logstream (cerr);
|
||||
}
|
||||
|
||||
return *global_logstream;
|
||||
return *logstream::initGlobalLogstream();
|
||||
}
|
||||
|
||||
|
||||
@@ -310,12 +293,15 @@ sglog()
|
||||
*/
|
||||
#ifdef FG_NDEBUG
|
||||
# define SG_LOG(C,P,M)
|
||||
#elif defined( __MWERKS__ )
|
||||
# define SG_LOG(C,P,M) ::sglog() << ::loglevel(C,P) << M << std::endl
|
||||
#else
|
||||
# define SG_LOG(C,P,M) sglog() << loglevel(C,P) << M << endl
|
||||
# define SG_LOG(C,P,M) do { \
|
||||
logstream& __tmplogstreamref(sglog()); \
|
||||
if(__tmplogstreamref.would_log(C,P)) { \
|
||||
__tmplogstreamref << loglevel(C,P) << M << std::endl; } \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
#define SG_ORIGIN __FILE__ ":" SG_STRINGIZE(__LINE__)
|
||||
|
||||
#endif // _LOGSTREAM_H
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@ includedir = @includedir@/environment
|
||||
|
||||
lib_LIBRARIES = libsgenvironment.a
|
||||
|
||||
include_HEADERS = metar.hxx visual_enviro.hxx
|
||||
include_HEADERS = metar.hxx visual_enviro.hxx precipitation.hxx
|
||||
|
||||
libsgenvironment_a_SOURCES = metar.cxx visual_enviro.cxx
|
||||
libsgenvironment_a_SOURCES = metar.cxx visual_enviro.cxx precipitation.cxx
|
||||
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
* @file metar.cxx
|
||||
* Interface for encoded Meteorological Aerodrome Reports (METAR).
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <time.h>
|
||||
@@ -490,7 +493,6 @@ bool SGMetar::scanVisibility()
|
||||
distance = i;
|
||||
} else {
|
||||
// M?(\d{1,2}|\d{1,2}/\d{1,2}|\d{1,2} \d{1,2}/\d{1,2})(SM|KM)
|
||||
modifier = 0;
|
||||
if (*m == 'M')
|
||||
m++, modifier = SGMetarVisibility::LESS_THAN;
|
||||
|
||||
@@ -744,6 +746,14 @@ bool SGMetar::scanSkyCondition()
|
||||
int i;
|
||||
SGMetarCloud cl;
|
||||
|
||||
if (!strncmp(m, "//////", 6)) {
|
||||
m += 6;
|
||||
if (!scanBoundary(&m))
|
||||
return false;
|
||||
_m = m;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!strncmp(m, "CLR", i = 3) // clear
|
||||
|| !strncmp(m, "SKC", i = 3) // sky clear
|
||||
|| !strncmp(m, "NSC", i = 3) // no significant clouds
|
||||
@@ -833,7 +843,7 @@ bool SGMetar::scanTemperature()
|
||||
return false;
|
||||
if (!scanBoundary(&m)) {
|
||||
if (!strncmp(m, "XX", 2)) // not spec compliant!
|
||||
m += 2, sign = 0;
|
||||
m += 2, sign = 0, dew = temp;
|
||||
else {
|
||||
sign = 1;
|
||||
if (*m == 'M')
|
||||
@@ -1171,7 +1181,7 @@ const struct Token *SGMetar::scanToken(char **str, const struct Token *list)
|
||||
{
|
||||
const struct Token *longest = 0;
|
||||
int maxlen = 0, len;
|
||||
char *s;
|
||||
const char *s;
|
||||
for (int i = 0; (s = list[i].id); i++) {
|
||||
len = strlen(s);
|
||||
if (!strncmp(s, *str, len) && len > maxlen) {
|
||||
|
||||
@@ -29,16 +29,16 @@
|
||||
|
||||
#include <simgear/constants.h>
|
||||
|
||||
SG_USING_STD(vector);
|
||||
SG_USING_STD(map);
|
||||
SG_USING_STD(string);
|
||||
using std::vector;
|
||||
using std::map;
|
||||
using std::string;
|
||||
|
||||
const double SGMetarNaN = -1E20;
|
||||
#define NaN SGMetarNaN
|
||||
|
||||
struct Token {
|
||||
char *id;
|
||||
char *text;
|
||||
const char *id;
|
||||
const char *text;
|
||||
};
|
||||
|
||||
|
||||
@@ -130,25 +130,21 @@ protected:
|
||||
class SGMetarCloud {
|
||||
friend class SGMetar;
|
||||
public:
|
||||
SGMetarCloud() :
|
||||
_coverage(-1),
|
||||
_altitude(NaN),
|
||||
_type(0),
|
||||
_type_long(0) {}
|
||||
SGMetarCloud() : _coverage(-1), _altitude(NaN), _type(0), _type_long(0) {}
|
||||
|
||||
void set(double alt, int cov = -1);
|
||||
|
||||
inline int getCoverage() const { return _coverage; }
|
||||
inline double getAltitude_m() const { return _altitude; }
|
||||
inline double getAltitude_ft() const { return _altitude == NaN ? NaN : _altitude * SG_METER_TO_FEET; }
|
||||
inline char *getTypeString() const { return _type; }
|
||||
inline char *getTypeLongString() const { return _type_long; }
|
||||
inline int getCoverage() const { return _coverage; }
|
||||
inline double getAltitude_m() const { return _altitude; }
|
||||
inline double getAltitude_ft() const { return _altitude == NaN ? NaN : _altitude * SG_METER_TO_FEET; }
|
||||
inline const char *getTypeString() const { return _type; }
|
||||
inline const char *getTypeLongString() const { return _type_long; }
|
||||
|
||||
protected:
|
||||
int _coverage; // quarters: 0 -> clear ... 4 -> overcast
|
||||
double _altitude; // 1000 m
|
||||
char *_type; // CU
|
||||
char *_type_long; // cumulus
|
||||
int _coverage; // quarters: 0 -> clear ... 4 -> overcast
|
||||
double _altitude; // 1000 m
|
||||
const char *_type; // CU
|
||||
const char *_type_long; // cumulus
|
||||
};
|
||||
|
||||
|
||||
|
||||
181
simgear/environment/precipitation.cxx
Normal file
181
simgear/environment/precipitation.cxx
Normal file
@@ -0,0 +1,181 @@
|
||||
/**
|
||||
* @file precipitation.cxx
|
||||
* @author Nicolas VIVIEN
|
||||
* @date 2008-02-10
|
||||
*
|
||||
* @note Copyright (C) 2008 Nicolas VIVIEN
|
||||
*
|
||||
* @brief Precipitation effects to draw rain and snow.
|
||||
*
|
||||
* @par Licences
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precipitation.hxx"
|
||||
#include "visual_enviro.hxx"
|
||||
|
||||
#include <simgear/constants.h>
|
||||
|
||||
/**
|
||||
* @brief SGPrecipitation constructor
|
||||
*
|
||||
* Build a new OSG object from osgParticle.
|
||||
*/
|
||||
SGPrecipitation::SGPrecipitation() :
|
||||
_freeze(false), _snow_intensity(0.0), _rain_intensity(0.0)
|
||||
{
|
||||
_precipitationEffect = new osgParticle::PrecipitationEffect;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Build and add the object "precipitationEffect"
|
||||
*
|
||||
* This function permits you to create an object precipitationEffect and initialize it.
|
||||
* I define by default the color of water (for raining)
|
||||
*/
|
||||
osg::Group* SGPrecipitation::build(void)
|
||||
{
|
||||
osg::Group* group = new osg::Group;
|
||||
|
||||
_precipitationEffect->snow(0);
|
||||
_precipitationEffect->rain(0);
|
||||
|
||||
group->addChild(_precipitationEffect.get());
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Define the snow intensity
|
||||
*
|
||||
* This function permits you to define and change the snow intensity
|
||||
* The param 'intensity' is normed (0 to 1).
|
||||
*/
|
||||
void SGPrecipitation::setSnowIntensity(float intensity)
|
||||
{
|
||||
if (this->_snow_intensity < intensity-0.001)
|
||||
this->_snow_intensity += 0.001;
|
||||
else if (this->_snow_intensity > intensity+0.001)
|
||||
this->_snow_intensity -= 0.001;
|
||||
else
|
||||
this->_snow_intensity = intensity;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Define the rain intensity
|
||||
*
|
||||
* This function permits you to define and change the rain intensity
|
||||
* The param 'intensity' is normed (0 to 1).
|
||||
*/
|
||||
void SGPrecipitation::setRainIntensity(float intensity)
|
||||
{
|
||||
if (this->_rain_intensity < intensity-0.001)
|
||||
this->_rain_intensity += 0.001;
|
||||
else if (this->_rain_intensity > intensity+0.001)
|
||||
this->_rain_intensity -= 0.001;
|
||||
else
|
||||
this->_rain_intensity = intensity;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Freeze the rain to snow
|
||||
*
|
||||
* @param freeze Boolean
|
||||
*
|
||||
* This function permits you to turn off the rain to snow.
|
||||
*/
|
||||
void SGPrecipitation::setFreezing(bool freeze)
|
||||
{
|
||||
this->_freeze = freeze;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Define the wind direction and speed
|
||||
*
|
||||
* This function permits you to define and change the wind direction
|
||||
*
|
||||
* After apply the MatrixTransform to the osg::Precipitation object,
|
||||
* x points full south... From wind heading and speed, we can calculate
|
||||
* the wind vector.
|
||||
*/
|
||||
void SGPrecipitation::setWindProperty(double heading, double speed)
|
||||
{
|
||||
double x, y, z;
|
||||
|
||||
heading = (heading + 180) * SGD_DEGREES_TO_RADIANS;
|
||||
speed = speed * SG_FEET_TO_METER;
|
||||
|
||||
x = -cos(heading) * speed;
|
||||
y = sin(heading) * speed;
|
||||
z = 0;
|
||||
|
||||
this->_wind_vec = osg::Vec3(x, y, z);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Update the precipitation effects
|
||||
*
|
||||
* This function permits you to update the precipitation effects.
|
||||
* Be careful, if snow and rain intensity are greater than '0', snow effect
|
||||
* will be first.
|
||||
*
|
||||
* The settings come from the osgParticule/PrecipitationEffect.cpp exemple.
|
||||
*/
|
||||
bool SGPrecipitation::update(void)
|
||||
{
|
||||
if (this->_freeze) {
|
||||
if (this->_rain_intensity > 0)
|
||||
this->_snow_intensity = this->_rain_intensity;
|
||||
}
|
||||
|
||||
bool enabled = sgEnviro.get_precipitation_enable_state();
|
||||
if (enabled && this->_snow_intensity > 0) {
|
||||
_precipitationEffect->setWind(_wind_vec);
|
||||
_precipitationEffect->setParticleSpeed( -0.75f - 0.25f*_snow_intensity);
|
||||
|
||||
_precipitationEffect->setParticleSize(0.02f + 0.03f*_snow_intensity);
|
||||
_precipitationEffect->setMaximumParticleDensity(_snow_intensity * 7.2f);
|
||||
_precipitationEffect->setCellSize(osg::Vec3(5.0f / (0.25f+_snow_intensity), 5.0f / (0.25f+_snow_intensity), 5.0f));
|
||||
|
||||
_precipitationEffect->setNearTransition(25.f);
|
||||
_precipitationEffect->setFarTransition(100.0f - 60.0f*sqrtf(_snow_intensity));
|
||||
|
||||
_precipitationEffect->setParticleColor(osg::Vec4(0.85, 0.85, 0.85, 1.0) - osg::Vec4(0.1, 0.1, 0.1, 1.0) * _snow_intensity);
|
||||
} else if (enabled && this->_rain_intensity > 0) {
|
||||
_precipitationEffect->setWind(_wind_vec);
|
||||
_precipitationEffect->setParticleSpeed( -2.0f + -5.0f*_rain_intensity);
|
||||
|
||||
_precipitationEffect->setParticleSize(0.01 + 0.02*_rain_intensity);
|
||||
_precipitationEffect->setMaximumParticleDensity(_rain_intensity * 7.5f);
|
||||
_precipitationEffect->setCellSize(osg::Vec3(5.0f / (0.25f+_rain_intensity), 5.0f / (0.25f+_rain_intensity), 5.0f));
|
||||
|
||||
_precipitationEffect->setNearTransition(25.f);
|
||||
_precipitationEffect->setFarTransition(100.0f - 60.0f*sqrtf(_rain_intensity));
|
||||
|
||||
_precipitationEffect->setParticleColor( osg::Vec4(0x7A, 0xCE, 0xFF, 0x80));
|
||||
} else {
|
||||
_precipitationEffect->snow(0);
|
||||
_precipitationEffect->rain(0);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
60
simgear/environment/precipitation.hxx
Normal file
60
simgear/environment/precipitation.hxx
Normal file
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* @file precipitation.hxx
|
||||
* @author Nicolas VIVIEN
|
||||
* @date 2008-02-10
|
||||
*
|
||||
* @note Copyright (C) 2008 Nicolas VIVIEN
|
||||
*
|
||||
* @brief Precipitation effects to draw rain and snow.
|
||||
*
|
||||
* @par Licences
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _PRECIPITATION_HXX
|
||||
#define _PRECIPITATION_HXX
|
||||
|
||||
#include <osg/Group>
|
||||
#include <osg/Referenced>
|
||||
#include <osgParticle/PrecipitationEffect>
|
||||
|
||||
|
||||
class SGPrecipitation : public osg::Referenced
|
||||
{
|
||||
private:
|
||||
bool _freeze;
|
||||
|
||||
float _snow_intensity;
|
||||
float _rain_intensity;
|
||||
|
||||
int _wind_dir;
|
||||
osg::Vec3 _wind_vec;
|
||||
|
||||
osg::ref_ptr<osgParticle::PrecipitationEffect> _precipitationEffect;
|
||||
|
||||
public:
|
||||
SGPrecipitation();
|
||||
virtual ~SGPrecipitation() {}
|
||||
osg::Group* build(void);
|
||||
bool update(void);
|
||||
|
||||
void setWindProperty(double, double);
|
||||
void setFreezing(bool);
|
||||
void setRainIntensity(float);
|
||||
void setSnowIntensity(float);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -23,7 +23,6 @@
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include <plib/sg.h>
|
||||
#include <simgear/constants.h>
|
||||
#include <simgear/structure/SGReferenced.hxx>
|
||||
#include <simgear/structure/SGSharedPtr.hxx>
|
||||
@@ -39,7 +38,7 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
SG_USING_STD(vector);
|
||||
using std::vector;
|
||||
|
||||
|
||||
typedef struct {
|
||||
@@ -190,6 +189,8 @@ SGEnviro::SGEnviro() :
|
||||
}
|
||||
|
||||
SGEnviro::~SGEnviro(void) {
|
||||
// OSGFIXME
|
||||
return;
|
||||
list_of_lightning::iterator iLightning;
|
||||
for( iLightning = lightnings.begin() ; iLightning != lightnings.end() ; iLightning++ ) {
|
||||
delete (*iLightning);
|
||||
@@ -198,10 +199,10 @@ SGEnviro::~SGEnviro(void) {
|
||||
}
|
||||
|
||||
void SGEnviro::startOfFrame( sgVec3 p, sgVec3 up, double lon, double lat, double alt, double delta_time) {
|
||||
// OSGFIXME
|
||||
return;
|
||||
view_in_cloud = false;
|
||||
// ask the impostor cache to do some cleanup
|
||||
if(SGNewCloud::cldCache)
|
||||
SGNewCloud::cldCache->startNewFrame();
|
||||
last_cloud_turbulence = cloud_turbulence;
|
||||
cloud_turbulence = 0.0;
|
||||
elapsed_time += delta_time;
|
||||
@@ -252,43 +253,10 @@ void SGEnviro::set_view_in_cloud(bool incloud) {
|
||||
view_in_cloud = incloud;
|
||||
}
|
||||
|
||||
int SGEnviro::get_CacheResolution(void) const {
|
||||
return SGCloudField::get_CacheResolution();
|
||||
}
|
||||
|
||||
int SGEnviro::get_clouds_CacheSize(void) const {
|
||||
return SGCloudField::get_CacheSize();
|
||||
}
|
||||
float SGEnviro::get_clouds_visibility(void) const {
|
||||
return SGCloudField::get_CloudVis();
|
||||
}
|
||||
float SGEnviro::get_clouds_density(void) const {
|
||||
return SGCloudField::get_density();
|
||||
}
|
||||
bool SGEnviro::get_clouds_enable_state(void) const {
|
||||
return SGCloudField::get_enable3dClouds();
|
||||
}
|
||||
|
||||
bool SGEnviro::get_turbulence_enable_state(void) const {
|
||||
return turbulence_enable_state;
|
||||
}
|
||||
|
||||
void SGEnviro::set_CacheResolution(int resolutionPixels) {
|
||||
SGCloudField::set_CacheResolution(resolutionPixels);
|
||||
}
|
||||
|
||||
void SGEnviro::set_clouds_CacheSize(int sizeKb) {
|
||||
SGCloudField::set_CacheSize(sizeKb);
|
||||
}
|
||||
void SGEnviro::set_clouds_visibility(float distance) {
|
||||
SGCloudField::set_CloudVis(distance);
|
||||
}
|
||||
void SGEnviro::set_clouds_density(float density) {
|
||||
SGCloudField::set_density(density);
|
||||
}
|
||||
void SGEnviro::set_clouds_enable_state(bool enable) {
|
||||
SGCloudField::set_enable3dClouds(enable);
|
||||
}
|
||||
void SGEnviro::set_turbulence_enable_state(bool enable) {
|
||||
turbulence_enable_state = enable;
|
||||
}
|
||||
@@ -320,12 +288,14 @@ void SGEnviro::set_lightning_enable_state(bool enable) {
|
||||
}
|
||||
|
||||
void SGEnviro::setLight(sgVec4 adj_fog_color) {
|
||||
// OSGFIXME
|
||||
return;
|
||||
sgCopyVec4( fog_color, adj_fog_color );
|
||||
if( false ) {
|
||||
// ssgGetLight( 0 ) -> setColour( GL_DIFFUSE, l->scene_diffuse() );
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
void SGEnviro::callback_cloud(float heading, float alt, float radius, int family, float dist, int cloudId) {
|
||||
// send data to wx radar
|
||||
// compute turbulence
|
||||
@@ -398,6 +368,7 @@ void SGEnviro::callback_cloud(float heading, float alt, float radius, int family
|
||||
LWC = 0.29*2.0;
|
||||
break;
|
||||
}
|
||||
|
||||
// add to the list for the wxRadar instrument
|
||||
if( LWC > 0.0 )
|
||||
radarEcho.push_back( SGWxRadarEcho ( heading, alt, radius, dist, LWC, false, cloudId ) );
|
||||
@@ -435,12 +406,16 @@ void SGEnviro::callback_cloud(float heading, float alt, float radius, int family
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
list_of_SGWxRadarEcho *SGEnviro::get_radar_echo(void) {
|
||||
return &radarEcho;
|
||||
}
|
||||
|
||||
// precipitation rendering code
|
||||
void SGEnviro::DrawCone2(float baseRadius, float height, int slices, bool down, double rain_norm, double speed) {
|
||||
// OSGFIXME
|
||||
return;
|
||||
sgVec3 light;
|
||||
sgAddVec3( light, fog_color, min_light );
|
||||
float da = SG_PI * 2.0f / (float) slices;
|
||||
@@ -489,6 +464,8 @@ void SGEnviro::DrawCone2(float baseRadius, float height, int slices, bool down,
|
||||
}
|
||||
|
||||
void SGEnviro::drawRain(double pitch, double roll, double heading, double hspeed, double rain_norm) {
|
||||
// OSGFIXME
|
||||
return;
|
||||
|
||||
#if 0
|
||||
static int debug_period = 0;
|
||||
@@ -558,6 +535,8 @@ void SGEnviro::set_soundMgr(SGSoundMgr *mgr) {
|
||||
}
|
||||
|
||||
void SGEnviro::drawPrecipitation(double rain_norm, double snow_norm, double hail_norm, double pitch, double roll, double heading, double hspeed) {
|
||||
// OSGFIXME
|
||||
return;
|
||||
if( precipitation_enable_state && rain_norm > 0.0)
|
||||
if( precipitation_max_alt >= last_alt )
|
||||
drawRain(pitch, roll, heading, hspeed, rain_norm);
|
||||
@@ -580,6 +559,8 @@ SGLightning::~SGLightning() {
|
||||
|
||||
// lightning rendering code
|
||||
void SGLightning::lt_build_tree_branch(int tree_nr, Point3D &start, float energy, int nbseg, float segsize) {
|
||||
// OSGFIXME
|
||||
return;
|
||||
|
||||
sgVec3 dir, newdir;
|
||||
int nseg = 0;
|
||||
@@ -627,6 +608,8 @@ void SGLightning::lt_build_tree_branch(int tree_nr, Point3D &start, float energy
|
||||
}
|
||||
|
||||
void SGLightning::lt_build(void) {
|
||||
// OSGFIXME
|
||||
return;
|
||||
Point3D top;
|
||||
nb_tree = 0;
|
||||
top[PX] = 0 ;
|
||||
@@ -652,6 +635,8 @@ void SGLightning::lt_build(void) {
|
||||
|
||||
|
||||
void SGLightning::lt_Render(void) {
|
||||
// OSGFIXME
|
||||
return;
|
||||
float flash = 0.5;
|
||||
if( fmod(sgEnviro.elapsed_time*100.0, 100.0) > 50.0 )
|
||||
flash = sg_random() * 0.75f + 0.25f;
|
||||
@@ -676,10 +661,12 @@ void SGLightning::lt_Render(void) {
|
||||
glDisable( GL_FOG );
|
||||
glPushMatrix();
|
||||
sgMat4 modelview, tmp;
|
||||
ssgGetModelviewMatrix( modelview );
|
||||
// OSGFIXME
|
||||
// ssgGetModelviewMatrix( modelview );
|
||||
sgCopyMat4( tmp, sgEnviro.transform );
|
||||
sgPostMultMat4( tmp, modelview );
|
||||
ssgLoadModelviewMatrix( tmp );
|
||||
// OSGFIXME
|
||||
// ssgLoadModelviewMatrix( tmp );
|
||||
|
||||
Point3D start( sgEnviro.last_lon*SG_DEGREES_TO_RADIANS, sgEnviro.last_lat*SG_DEGREES_TO_RADIANS, 0.0 );
|
||||
Point3D dest( lon*SG_DEGREES_TO_RADIANS, lat*SG_DEGREES_TO_RADIANS, 0.0 );
|
||||
@@ -737,6 +724,8 @@ void SGLightning::lt_Render(void) {
|
||||
}
|
||||
|
||||
void SGEnviro::addLightning(double lon, double lat, double alt) {
|
||||
// OSGFIXME
|
||||
return;
|
||||
if( lightnings.size() > 10)
|
||||
return;
|
||||
SGLightning *lt= new SGLightning(lon, lat, alt);
|
||||
@@ -744,6 +733,8 @@ void SGEnviro::addLightning(double lon, double lat, double alt) {
|
||||
}
|
||||
|
||||
void SGEnviro::drawLightning(void) {
|
||||
// OSGFIXME
|
||||
return;
|
||||
list_of_lightning::iterator iLightning;
|
||||
// play 'thunder' for lightning
|
||||
if( snd_active )
|
||||
|
||||
@@ -22,12 +22,14 @@
|
||||
#ifndef _VISUAL_ENVIRO_HXX
|
||||
#define _VISUAL_ENVIRO_HXX
|
||||
|
||||
#include <plib/sg.h>
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
#include STL_STRING
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
SG_USING_STD(vector);
|
||||
SG_USING_STD(string);
|
||||
using std::vector;
|
||||
using std::string;
|
||||
|
||||
class SGLightning;
|
||||
class SGSoundMgr;
|
||||
@@ -38,7 +40,8 @@ class SGSoundMgr;
|
||||
*/
|
||||
class SGWxRadarEcho {
|
||||
public:
|
||||
SGWxRadarEcho(float _heading, float _alt, float _radius, float _dist, double _LWC, bool _lightning, int _cloudId) :
|
||||
SGWxRadarEcho(float _heading, float _alt, float _radius, float _dist,
|
||||
double _LWC, bool _lightning, int _cloudId ) :
|
||||
heading( _heading ),
|
||||
alt ( _alt ),
|
||||
radius ( _radius ),
|
||||
@@ -54,7 +57,7 @@ public:
|
||||
/** reflectivity converted to liquid water content. */
|
||||
double LWC;
|
||||
/** if true then this data is for a lightning else it is for water echo. */
|
||||
bool lightning;
|
||||
bool lightning;
|
||||
/** Unique identifier of cloud */
|
||||
int cloudId;
|
||||
};
|
||||
@@ -122,6 +125,7 @@ public:
|
||||
|
||||
void endOfFrame(void);
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Whenever a cloud is drawn we check his 'impact' on the environment.
|
||||
* @param heading direction of cloud in radians
|
||||
@@ -131,7 +135,7 @@ public:
|
||||
* @param dist squared dist to cloud in meters
|
||||
*/
|
||||
void callback_cloud(float heading, float alt, float radius, int family, float dist, int cloudId);
|
||||
|
||||
#endif
|
||||
void drawRain(double pitch, double roll, double heading, double hspeed, double rain_norm);
|
||||
/**
|
||||
* Draw rain or snow precipitation around the viewer.
|
||||
|
||||
@@ -24,9 +24,6 @@
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#ifdef SG_MATH_EXCEPTION_CLASH
|
||||
# define exception c_exception
|
||||
#endif
|
||||
#include <math.h>
|
||||
|
||||
#include "celestialBody.hxx"
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
|
||||
// Constructor
|
||||
SGEphemeris::SGEphemeris( const string &path ) {
|
||||
SGEphemeris::SGEphemeris( const std::string &path ) {
|
||||
our_sun = new Star;
|
||||
moon = new MoonPos;
|
||||
mercury = new Mercury;
|
||||
@@ -42,9 +42,8 @@ SGEphemeris::SGEphemeris( const string &path ) {
|
||||
uranus = new Uranus;
|
||||
neptune = new Neptune;
|
||||
nplanets = 7;
|
||||
for ( int i = 0; i < nplanets; ++i ) {
|
||||
sgdSetVec3( planets[i], 0.0, 0.0, 0.0 );
|
||||
}
|
||||
for ( int i = 0; i < nplanets; ++i )
|
||||
planets[i] = SGVec3d::zeros();
|
||||
stars = new SGStarData( SGPath(path) );
|
||||
}
|
||||
|
||||
|
||||
@@ -29,8 +29,7 @@
|
||||
#ifndef _EPHEMERIS_HXX
|
||||
#define _EPHEMERIS_HXX
|
||||
|
||||
|
||||
#include <plib/sg.h>
|
||||
#include <string>
|
||||
|
||||
#include <simgear/ephemeris/star.hxx>
|
||||
#include <simgear/ephemeris/moonpos.hxx>
|
||||
@@ -43,6 +42,9 @@
|
||||
#include <simgear/ephemeris/neptune.hxx>
|
||||
#include <simgear/ephemeris/stardata.hxx>
|
||||
|
||||
#include <simgear/math/SGMath.hxx>
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
|
||||
|
||||
/** Ephemeris class
|
||||
*
|
||||
@@ -83,7 +85,7 @@ class SGEphemeris {
|
||||
// planets[i][1] = Declination
|
||||
// planets[i][2] = Magnitude
|
||||
int nplanets;
|
||||
sgdVec3 planets[7];
|
||||
SGVec3d planets[7];
|
||||
|
||||
SGStarData *stars;
|
||||
|
||||
@@ -95,7 +97,7 @@ public:
|
||||
* calling the constructor you need to provide a path pointing to
|
||||
* your star database file.
|
||||
* @param path path to your star database */
|
||||
SGEphemeris( const string &path );
|
||||
SGEphemeris( const std::string &path );
|
||||
|
||||
/** Destructor */
|
||||
~SGEphemeris( void );
|
||||
@@ -155,7 +157,7 @@ public:
|
||||
* the second is the declination, and the third is the magnitude.
|
||||
* @return planets array
|
||||
*/
|
||||
inline sgdVec3 *getPlanets() { return planets; }
|
||||
inline SGVec3d *getPlanets() { return planets; }
|
||||
|
||||
/** @return the numbers of defined stars. */
|
||||
inline int getNumStars() const { return stars->getNumStars(); }
|
||||
@@ -167,7 +169,7 @@ public:
|
||||
* third is the magnitude.
|
||||
* @returns star array
|
||||
*/
|
||||
inline sgdVec3 *getStars() { return stars->getStars(); }
|
||||
inline SGVec3d *getStars() { return stars->getStars(); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -22,10 +22,6 @@
|
||||
* $Id$
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
# define exception c_exception
|
||||
#endif
|
||||
#include <math.h>
|
||||
|
||||
#include "jupiter.hxx"
|
||||
|
||||
@@ -22,9 +22,6 @@
|
||||
* $Id$
|
||||
**************************************************************************/
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
# define exception c_exception
|
||||
#endif
|
||||
#include <math.h>
|
||||
|
||||
#include "mars.hxx"
|
||||
|
||||
@@ -22,9 +22,6 @@
|
||||
* $Id$
|
||||
**************************************************************************/
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
# define exception c_exception
|
||||
#endif
|
||||
#include <math.h>
|
||||
|
||||
#include "mercury.hxx"
|
||||
|
||||
@@ -27,9 +27,6 @@
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
# define exception c_exception
|
||||
#endif
|
||||
#include <math.h>
|
||||
|
||||
// #include <FDM/flight.hxx>
|
||||
|
||||
@@ -22,9 +22,6 @@
|
||||
* $Id$
|
||||
**************************************************************************/
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
# define exception c_exception
|
||||
#endif
|
||||
#include <math.h>
|
||||
|
||||
#include "saturn.hxx"
|
||||
|
||||
@@ -22,10 +22,6 @@
|
||||
* $Id$
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
# define exception c_exception
|
||||
#endif
|
||||
#include <math.h>
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
@@ -25,25 +25,19 @@
|
||||
#endif
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
#include <simgear/misc/sgstream.hxx>
|
||||
|
||||
#include "stardata.hxx"
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
SG_USING_STD(getline);
|
||||
using std::getline;
|
||||
#endif
|
||||
|
||||
// Constructor
|
||||
SGStarData::SGStarData() :
|
||||
nstars(0)
|
||||
SGStarData::SGStarData( const SGPath& path )
|
||||
{
|
||||
}
|
||||
|
||||
SGStarData::SGStarData( SGPath path ) :
|
||||
nstars(0)
|
||||
{
|
||||
data_path = SGPath( path );
|
||||
load();
|
||||
load(path);
|
||||
}
|
||||
|
||||
|
||||
@@ -52,31 +46,28 @@ SGStarData::~SGStarData() {
|
||||
}
|
||||
|
||||
|
||||
bool SGStarData::load() {
|
||||
bool SGStarData::load( const SGPath& path ) {
|
||||
|
||||
// -dw- avoid local data > 32k error by dynamic allocation of the
|
||||
// array, problem for some compilers
|
||||
stars = new sgdVec3[SG_MAX_STARS];
|
||||
_stars.clear();
|
||||
|
||||
// build the full path name to the stars data base file
|
||||
data_path.append( "stars" );
|
||||
SG_LOG( SG_ASTRO, SG_INFO, " Loading stars from " << data_path.str() );
|
||||
// build the full path name to the stars data base file
|
||||
SGPath tmp = path;
|
||||
tmp.append( "stars" );
|
||||
SG_LOG( SG_ASTRO, SG_INFO, " Loading stars from " << tmp.str() );
|
||||
|
||||
sg_gzifstream in( data_path.str() );
|
||||
sg_gzifstream in( tmp.str() );
|
||||
if ( ! in.is_open() ) {
|
||||
SG_LOG( SG_ASTRO, SG_ALERT, "Cannot open star file: "
|
||||
<< data_path.str() );
|
||||
exit(-1);
|
||||
<< tmp.str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
double ra, dec, mag;
|
||||
char c;
|
||||
string name;
|
||||
|
||||
nstars = 0;
|
||||
|
||||
// read in each line of the file
|
||||
while ( ! in.eof() && nstars < SG_MAX_STARS ) {
|
||||
while ( ! in.eof() ) {
|
||||
in >> skipcomment;
|
||||
|
||||
getline( in, name, ',' );
|
||||
@@ -116,13 +107,10 @@ bool SGStarData::load() {
|
||||
in >> mag;
|
||||
|
||||
// cout << " star data = " << ra << " " << dec << " " << mag << endl;
|
||||
|
||||
sgdSetVec3( stars[nstars], ra, dec, mag );
|
||||
|
||||
++nstars;
|
||||
_stars.push_back(SGVec3d(ra, dec, mag));
|
||||
}
|
||||
|
||||
SG_LOG( SG_ASTRO, SG_INFO, " Loaded " << nstars << " stars" );
|
||||
SG_LOG( SG_ASTRO, SG_INFO, " Loaded " << _stars.size() << " stars" );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -24,37 +24,28 @@
|
||||
#ifndef _SG_STARDATA_HXX
|
||||
#define _SG_STARDATA_HXX
|
||||
|
||||
#include <vector>
|
||||
#include <simgear/math/SGMath.hxx>
|
||||
|
||||
#include <plib/sg.h>
|
||||
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
|
||||
|
||||
#define SG_MAX_STARS 850
|
||||
|
||||
class SGPath;
|
||||
|
||||
class SGStarData {
|
||||
|
||||
int nstars;
|
||||
sgdVec3 *stars;
|
||||
|
||||
SGPath data_path;
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
SGStarData();
|
||||
SGStarData( SGPath path );
|
||||
SGStarData( const SGPath& path );
|
||||
|
||||
// Destructor
|
||||
~SGStarData();
|
||||
|
||||
// load the stars database
|
||||
bool load();
|
||||
bool load( const SGPath& path );
|
||||
|
||||
// stars
|
||||
inline int getNumStars() const { return nstars; }
|
||||
inline sgdVec3 *getStars() { return stars; }
|
||||
inline int getNumStars() const { return _stars.size(); }
|
||||
inline SGVec3d *getStars() { return &(_stars[0]); }
|
||||
|
||||
private:
|
||||
std::vector<SGVec3d> _stars;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -22,9 +22,6 @@
|
||||
* $Id$
|
||||
**************************************************************************/
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
# define exception c_exception
|
||||
#endif
|
||||
#include <math.h>
|
||||
|
||||
#include "uranus.hxx"
|
||||
|
||||
@@ -22,9 +22,6 @@
|
||||
* $Id$
|
||||
**************************************************************************/
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
# define exception c_exception
|
||||
#endif
|
||||
#include <math.h>
|
||||
|
||||
#include "venus.hxx"
|
||||
|
||||
@@ -27,7 +27,7 @@ noinst_PROGRAMS = decode_binobj socktest lowtest tcp_server tcp_client
|
||||
tcp_server_SOURCES = tcp_server.cxx
|
||||
|
||||
tcp_server_LDADD = \
|
||||
$(top_builddir)/simgear/io/libsgio.a \
|
||||
libsgio.a \
|
||||
$(top_builddir)/simgear/debug/libsgdebug.a \
|
||||
$(top_builddir)/simgear/bucket/libsgbucket.a \
|
||||
$(top_builddir)/simgear/misc/libsgmisc.a \
|
||||
@@ -38,7 +38,7 @@ tcp_server_LDADD = \
|
||||
tcp_client_SOURCES = tcp_client.cxx
|
||||
|
||||
tcp_client_LDADD = \
|
||||
$(top_builddir)/simgear/io/libsgio.a \
|
||||
libsgio.a \
|
||||
$(top_builddir)/simgear/debug/libsgdebug.a \
|
||||
$(top_builddir)/simgear/bucket/libsgbucket.a \
|
||||
$(top_builddir)/simgear/misc/libsgmisc.a \
|
||||
@@ -49,7 +49,7 @@ tcp_client_LDADD = \
|
||||
socktest_SOURCES = socktest.cxx
|
||||
|
||||
socktest_LDADD = \
|
||||
$(top_builddir)/simgear/io/libsgio.a \
|
||||
libsgio.a \
|
||||
$(top_builddir)/simgear/debug/libsgdebug.a \
|
||||
$(top_builddir)/simgear/bucket/libsgbucket.a \
|
||||
$(top_builddir)/simgear/misc/libsgmisc.a \
|
||||
@@ -60,7 +60,7 @@ socktest_LDADD = \
|
||||
lowtest_SOURCES = lowtest.cxx
|
||||
|
||||
lowtest_LDADD = \
|
||||
$(top_builddir)/simgear/io/libsgio.a \
|
||||
libsgio.a \
|
||||
$(top_builddir)/simgear/debug/libsgdebug.a \
|
||||
$(top_builddir)/simgear/bucket/libsgbucket.a \
|
||||
$(top_builddir)/simgear/misc/libsgmisc.a \
|
||||
@@ -69,7 +69,7 @@ lowtest_LDADD = \
|
||||
decode_binobj_SOURCES = decode_binobj.cxx
|
||||
|
||||
decode_binobj_LDADD = \
|
||||
$(top_builddir)/simgear/io/libsgio.a \
|
||||
libsgio.a \
|
||||
$(top_builddir)/simgear/debug/libsgdebug.a \
|
||||
$(top_builddir)/simgear/bucket/libsgbucket.a \
|
||||
$(top_builddir)/simgear/misc/libsgmisc.a \
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include STL_IOSTREAM
|
||||
#include <iostream>
|
||||
|
||||
#include "sg_binobj.hxx"
|
||||
|
||||
SG_USING_STD(cout);
|
||||
SG_USING_STD(endl);
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
|
||||
int main( int argc, char **argv ) {
|
||||
@@ -37,14 +37,14 @@ int main( int argc, char **argv ) {
|
||||
obj.get_gbs_radius());
|
||||
cout << endl;
|
||||
|
||||
point_list nodes = obj.get_wgs84_nodes();
|
||||
std::vector<SGVec3d> nodes = obj.get_wgs84_nodes();
|
||||
cout << "# vertex list" << endl;
|
||||
for ( i = 0; i < (int)nodes.size(); ++i ) {
|
||||
printf("v %.5f %.5f %.5f\n", nodes[i].x(), nodes[i].y(), nodes[i].z() );
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
point_list normals = obj.get_normals();
|
||||
std::vector<SGVec3f> normals = obj.get_normals();
|
||||
cout << "# vertex normal list" << endl;
|
||||
for ( i = 0; i < (int)normals.size(); ++i ) {
|
||||
printf("vn %.5f %.5f %.5f\n",
|
||||
@@ -52,7 +52,7 @@ int main( int argc, char **argv ) {
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
point_list texcoords = obj.get_texcoords();
|
||||
std::vector<SGVec2f> texcoords = obj.get_texcoords();
|
||||
cout << "# texture coordinate list" << endl;
|
||||
for ( i = 0; i < (int)texcoords.size(); ++i ) {
|
||||
printf("vt %.5f %.5f\n",
|
||||
|
||||
@@ -32,11 +32,11 @@
|
||||
|
||||
// #include "protocol.hxx"
|
||||
|
||||
#include STL_STRING
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
SG_USING_STD(vector);
|
||||
SG_USING_STD(string);
|
||||
using std::vector;
|
||||
using std::string;
|
||||
|
||||
|
||||
#define SG_IO_MAX_MSG_SIZE 16384
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include STL_IOSTREAM
|
||||
#include <iostream>
|
||||
#include "lowlevel.hxx"
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@ static const int sgEndianTest = 1;
|
||||
#define sgIsLittleEndian (*((char *) &sgEndianTest ) != 0)
|
||||
#define sgIsBigEndian (*((char *) &sgEndianTest ) == 0)
|
||||
|
||||
SG_USING_STD(cout);
|
||||
SG_USING_STD(endl);
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
|
||||
int main() {
|
||||
|
||||
@@ -33,7 +33,8 @@
|
||||
#include <time.h>
|
||||
|
||||
#include <vector>
|
||||
#include STL_STRING
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#include <simgear/bucket/newbucket.hxx>
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
@@ -42,9 +43,10 @@
|
||||
#include "sg_binobj.hxx"
|
||||
|
||||
|
||||
SG_USING_STD( string );
|
||||
SG_USING_STD( vector );
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
enum sgObjectTypes {
|
||||
SG_BOUNDING_SPHERE = 0,
|
||||
@@ -174,7 +176,7 @@ static void read_object( gzFile fp,
|
||||
int idx_size;
|
||||
bool do_vertices, do_normals, do_colors, do_texcoords;
|
||||
int j, k, idx;
|
||||
static sgSimpleBuffer buf( 32768 ); // 32 Kb
|
||||
sgSimpleBuffer buf( 32768 ); // 32 Kb
|
||||
char material[256];
|
||||
|
||||
// default values
|
||||
@@ -280,13 +282,13 @@ static void read_object( gzFile fp,
|
||||
|
||||
// read a binary file and populate the provided structures.
|
||||
bool SGBinObject::read_bin( const string& file ) {
|
||||
Point3D p;
|
||||
SGVec3d p;
|
||||
int i, j, k;
|
||||
unsigned int nbytes;
|
||||
static sgSimpleBuffer buf( 32768 ); // 32 Kb
|
||||
sgSimpleBuffer buf( 32768 ); // 32 Kb
|
||||
|
||||
// zero out structures
|
||||
gbs_center = Point3D( 0 );
|
||||
gbs_center = SGVec3d(0, 0, 0);
|
||||
gbs_radius = 0.0;
|
||||
|
||||
wgs84_nodes.clear();
|
||||
@@ -322,7 +324,7 @@ bool SGBinObject::read_bin( const string& file ) {
|
||||
string filegz = file + ".gz";
|
||||
if ( (fp = gzopen( filegz.c_str(), "rb" )) == NULL ) {
|
||||
SG_LOG( SG_EVENT, SG_ALERT,
|
||||
"ERROR: opening " << file << " or " << filegz << "for reading!");
|
||||
"ERROR: opening " << file << " or " << filegz << " for reading!");
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -364,18 +366,32 @@ bool SGBinObject::read_bin( const string& file ) {
|
||||
#endif
|
||||
|
||||
// read number of top level objects
|
||||
short nobjects;
|
||||
sgReadShort( fp, &nobjects );
|
||||
unsigned short nobjects;
|
||||
if ( version >= 7 ) {
|
||||
sgReadUShort( fp, &nobjects );
|
||||
} else {
|
||||
short tmp;
|
||||
sgReadShort( fp, &tmp );
|
||||
nobjects = tmp;
|
||||
}
|
||||
// cout << "Total objects to read = " << nobjects << endl;
|
||||
|
||||
// read in objects
|
||||
for ( i = 0; i < nobjects; ++i ) {
|
||||
// read object header
|
||||
char obj_type;
|
||||
short nproperties, nelements;
|
||||
unsigned short nproperties, nelements;
|
||||
sgReadChar( fp, &obj_type );
|
||||
sgReadShort( fp, &nproperties );
|
||||
sgReadShort( fp, &nelements );
|
||||
if ( version >= 7 ) {
|
||||
sgReadUShort( fp, &nproperties );
|
||||
sgReadUShort( fp, &nelements );
|
||||
} else {
|
||||
short tmp;
|
||||
sgReadShort( fp, &tmp );
|
||||
nproperties = tmp;
|
||||
sgReadShort( fp, &tmp );
|
||||
nelements = tmp;
|
||||
}
|
||||
|
||||
// cout << "object " << i << " = " << (int)obj_type << " props = "
|
||||
// << nproperties << " elements = " << nelements << endl;
|
||||
@@ -407,7 +423,7 @@ bool SGBinObject::read_bin( const string& file ) {
|
||||
sgEndianSwap( (uint64_t *)&(dptr[1]) );
|
||||
sgEndianSwap( (uint64_t *)&(dptr[2]) );
|
||||
}
|
||||
gbs_center = Point3D( dptr[0], dptr[1], dptr[2] );
|
||||
gbs_center = SGVec3d( dptr[0], dptr[1], dptr[2] );
|
||||
// cout << "Center = " << gbs_center << endl;
|
||||
ptr += sizeof(double) * 3;
|
||||
|
||||
@@ -447,7 +463,7 @@ bool SGBinObject::read_bin( const string& file ) {
|
||||
sgEndianSwap( (uint32_t *)&(fptr[1]) );
|
||||
sgEndianSwap( (uint32_t *)&(fptr[2]) );
|
||||
}
|
||||
wgs84_nodes.push_back( Point3D(fptr[0], fptr[1], fptr[2]) );
|
||||
wgs84_nodes.push_back( SGVec3d(fptr[0], fptr[1], fptr[2]) );
|
||||
fptr += 3;
|
||||
}
|
||||
}
|
||||
@@ -481,7 +497,8 @@ bool SGBinObject::read_bin( const string& file ) {
|
||||
sgEndianSwap( (uint32_t *)&(fptr[2]) );
|
||||
sgEndianSwap( (uint32_t *)&(fptr[3]) );
|
||||
}
|
||||
colors.push_back( Point3D( fptr[0], fptr[1], fptr[2] ) );
|
||||
SGVec4f color( fptr[0], fptr[1], fptr[2], fptr[3] );
|
||||
colors.push_back( color );
|
||||
fptr += 4;
|
||||
}
|
||||
}
|
||||
@@ -508,14 +525,11 @@ bool SGBinObject::read_bin( const string& file ) {
|
||||
int count = nbytes / 3;
|
||||
normals.reserve( count );
|
||||
for ( k = 0; k < count; ++k ) {
|
||||
sgdVec3 normal;
|
||||
sgdSetVec3( normal,
|
||||
(ptr[0]) / 127.5 - 1.0,
|
||||
(ptr[1]) / 127.5 - 1.0,
|
||||
(ptr[2]) / 127.5 - 1.0 );
|
||||
sgdNormalizeVec3( normal );
|
||||
SGVec3f normal((ptr[0]) / 127.5 - 1.0,
|
||||
(ptr[1]) / 127.5 - 1.0,
|
||||
(ptr[2]) / 127.5 - 1.0);
|
||||
|
||||
normals.push_back(Point3D(normal[0], normal[1], normal[2]));
|
||||
normals.push_back(normalize(normal));
|
||||
ptr += 3;
|
||||
}
|
||||
}
|
||||
@@ -547,7 +561,7 @@ bool SGBinObject::read_bin( const string& file ) {
|
||||
sgEndianSwap( (uint32_t *)&(fptr[0]) );
|
||||
sgEndianSwap( (uint32_t *)&(fptr[1]) );
|
||||
}
|
||||
texcoords.push_back( Point3D( fptr[0], fptr[1], 0 ) );
|
||||
texcoords.push_back( SGVec2f( fptr[0], fptr[1] ) );
|
||||
fptr += 2;
|
||||
}
|
||||
}
|
||||
@@ -612,10 +626,6 @@ bool SGBinObject::read_bin( const string& file ) {
|
||||
bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
const SGBucket& b )
|
||||
{
|
||||
Point3D p;
|
||||
sgVec2 t;
|
||||
sgVec3 pt;
|
||||
sgVec4 color;
|
||||
int i, j;
|
||||
unsigned char idx_mask;
|
||||
int idx_size;
|
||||
@@ -655,7 +665,7 @@ bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
string material;
|
||||
int start;
|
||||
int end;
|
||||
short nobjects = 0;
|
||||
unsigned short nobjects = 0;
|
||||
nobjects++; // for gbs
|
||||
nobjects++; // for vertices
|
||||
nobjects++; // for colors
|
||||
@@ -663,7 +673,7 @@ bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
nobjects++; // for texcoords
|
||||
|
||||
// points
|
||||
short npts = 0;
|
||||
unsigned short npts = 0;
|
||||
start = 0; end = 1;
|
||||
while ( start < (int)pt_materials.size() ) {
|
||||
material = pt_materials[start];
|
||||
@@ -677,7 +687,7 @@ bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
nobjects += npts;
|
||||
|
||||
// tris
|
||||
short ntris = 0;
|
||||
unsigned short ntris = 0;
|
||||
start = 0; end = 1;
|
||||
while ( start < (int)tri_materials.size() ) {
|
||||
material = tri_materials[start];
|
||||
@@ -691,7 +701,7 @@ bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
nobjects += ntris;
|
||||
|
||||
// strips
|
||||
short nstrips = 0;
|
||||
unsigned short nstrips = 0;
|
||||
start = 0; end = 1;
|
||||
while ( start < (int)strip_materials.size() ) {
|
||||
material = strip_materials[start];
|
||||
@@ -705,7 +715,7 @@ bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
nobjects += nstrips;
|
||||
|
||||
// fans
|
||||
short nfans = 0;
|
||||
unsigned short nfans = 0;
|
||||
start = 0; end = 1;
|
||||
while ( start < (int)fan_materials.size() ) {
|
||||
material = fan_materials[start];
|
||||
@@ -719,12 +729,12 @@ bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
nobjects += nfans;
|
||||
|
||||
cout << "total top level objects = " << nobjects << endl;
|
||||
sgWriteShort( fp, nobjects );
|
||||
sgWriteUShort( fp, nobjects );
|
||||
|
||||
// write bounding sphere
|
||||
sgWriteChar( fp, (char)SG_BOUNDING_SPHERE ); // type
|
||||
sgWriteShort( fp, 0 ); // nproperties
|
||||
sgWriteShort( fp, 1 ); // nelements
|
||||
sgWriteUShort( fp, 0 ); // nproperties
|
||||
sgWriteUShort( fp, 1 ); // nelements
|
||||
|
||||
sgWriteUInt( fp, sizeof(double) * 3 + sizeof(float) ); // nbytes
|
||||
sgdVec3 center;
|
||||
@@ -734,37 +744,31 @@ bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
|
||||
// dump vertex list
|
||||
sgWriteChar( fp, (char)SG_VERTEX_LIST ); // type
|
||||
sgWriteShort( fp, 0 ); // nproperties
|
||||
sgWriteShort( fp, 1 ); // nelements
|
||||
sgWriteUShort( fp, 0 ); // nproperties
|
||||
sgWriteUShort( fp, 1 ); // nelements
|
||||
sgWriteUInt( fp, wgs84_nodes.size() * sizeof(float) * 3 ); // nbytes
|
||||
for ( i = 0; i < (int)wgs84_nodes.size(); ++i ) {
|
||||
p = wgs84_nodes[i] - gbs_center;
|
||||
sgSetVec3( pt, p.x(), p.y(), p.z() );
|
||||
sgWriteVec3( fp, pt );
|
||||
SGVec3f p = toVec3f(wgs84_nodes[i] - gbs_center);
|
||||
sgWriteVec3( fp, p.data() );
|
||||
}
|
||||
|
||||
// dump vertex color list
|
||||
sgWriteChar( fp, (char)SG_COLOR_LIST ); // type
|
||||
sgWriteShort( fp, 0 ); // nproperties
|
||||
sgWriteShort( fp, 1 ); // nelements
|
||||
sgWriteUShort( fp, 0 ); // nproperties
|
||||
sgWriteUShort( fp, 1 ); // nelements
|
||||
sgWriteUInt( fp, colors.size() * sizeof(float) * 4 ); // nbytes
|
||||
for ( i = 0; i < (int)colors.size(); ++i ) {
|
||||
p = colors[i];
|
||||
// Right now we have a place holder for color alpha but we
|
||||
// need to update the interface so the calling program can
|
||||
// provide the info.
|
||||
sgSetVec4( color, p.x(), p.y(), p.z(), 1.0 );
|
||||
sgWriteVec4( fp, color );
|
||||
sgWriteVec4( fp, colors[i].data() );
|
||||
}
|
||||
|
||||
// dump vertex normal list
|
||||
sgWriteChar( fp, (char)SG_NORMAL_LIST ); // type
|
||||
sgWriteShort( fp, 0 ); // nproperties
|
||||
sgWriteShort( fp, 1 ); // nelements
|
||||
sgWriteUShort( fp, 0 ); // nproperties
|
||||
sgWriteUShort( fp, 1 ); // nelements
|
||||
sgWriteUInt( fp, normals.size() * 3 ); // nbytes
|
||||
char normal[3];
|
||||
for ( i = 0; i < (int)normals.size(); ++i ) {
|
||||
p = normals[i];
|
||||
SGVec3f p = normals[i];
|
||||
normal[0] = (unsigned char)((p.x() + 1.0) * 127.5);
|
||||
normal[1] = (unsigned char)((p.y() + 1.0) * 127.5);
|
||||
normal[2] = (unsigned char)((p.z() + 1.0) * 127.5);
|
||||
@@ -773,13 +777,11 @@ bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
|
||||
// dump texture coordinates
|
||||
sgWriteChar( fp, (char)SG_TEXCOORD_LIST ); // type
|
||||
sgWriteShort( fp, 0 ); // nproperties
|
||||
sgWriteShort( fp, 1 ); // nelements
|
||||
sgWriteUShort( fp, 0 ); // nproperties
|
||||
sgWriteUShort( fp, 1 ); // nelements
|
||||
sgWriteUInt( fp, texcoords.size() * sizeof(float) * 2 ); // nbytes
|
||||
for ( i = 0; i < (int)texcoords.size(); ++i ) {
|
||||
p = texcoords[i];
|
||||
sgSetVec2( t, p.x(), p.y() );
|
||||
sgWriteVec2( fp, t );
|
||||
sgWriteVec2( fp, texcoords[i].data() );
|
||||
}
|
||||
|
||||
// dump point groups if they exist
|
||||
@@ -800,8 +802,8 @@ bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
|
||||
// write group headers
|
||||
sgWriteChar( fp, (char)SG_POINTS ); // type
|
||||
sgWriteShort( fp, 2 ); // nproperties
|
||||
sgWriteShort( fp, end - start ); // nelements
|
||||
sgWriteUShort( fp, 2 ); // nproperties
|
||||
sgWriteUShort( fp, end - start ); // nelements
|
||||
|
||||
sgWriteChar( fp, (char)SG_MATERIAL ); // property
|
||||
sgWriteUInt( fp, material.length() ); // nbytes
|
||||
@@ -820,19 +822,20 @@ bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
// write strips
|
||||
for ( i = start; i < end; ++i ) {
|
||||
// nbytes
|
||||
sgWriteUInt( fp, pts_v[i].size() * idx_size * sizeof(short) );
|
||||
sgWriteUInt( fp, pts_v[i].size() * idx_size
|
||||
* sizeof(unsigned short) );
|
||||
for ( j = 0; j < (int)pts_v[i].size(); ++j ) {
|
||||
if ( pts_v.size() ) {
|
||||
sgWriteShort( fp, (short)pts_v[i][j] );
|
||||
sgWriteUShort( fp, (unsigned short)pts_v[i][j] );
|
||||
}
|
||||
if ( pts_n.size() ) {
|
||||
sgWriteShort( fp, (short)pts_n[i][j] );
|
||||
sgWriteUShort( fp, (unsigned short)pts_n[i][j] );
|
||||
}
|
||||
if ( pts_c.size() ) {
|
||||
sgWriteShort( fp, (short)pts_c[i][j] );
|
||||
sgWriteUShort( fp, (unsigned short)pts_c[i][j] );
|
||||
}
|
||||
if ( pts_tc.size() ) {
|
||||
sgWriteShort( fp, (short)pts_tc[i][j] );
|
||||
sgWriteUShort( fp, (unsigned short)pts_tc[i][j] );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -861,8 +864,8 @@ bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
|
||||
// write group headers
|
||||
sgWriteChar( fp, (char)SG_TRIANGLE_FACES ); // type
|
||||
sgWriteShort( fp, 2 ); // nproperties
|
||||
sgWriteShort( fp, 1 ); // nelements
|
||||
sgWriteUShort( fp, 2 ); // nproperties
|
||||
sgWriteUShort( fp, 1 ); // nelements
|
||||
|
||||
sgWriteChar( fp, (char)SG_MATERIAL ); // property
|
||||
sgWriteUInt( fp, material.length() ); // nbytes
|
||||
@@ -879,22 +882,23 @@ bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
sgWriteChar( fp, idx_mask );
|
||||
|
||||
// nbytes
|
||||
sgWriteUInt( fp, (end - start) * 3 * idx_size * sizeof(short) );
|
||||
sgWriteUInt( fp, (end - start) * 3 * idx_size
|
||||
* sizeof(unsigned short) );
|
||||
|
||||
// write group
|
||||
for ( i = start; i < end; ++i ) {
|
||||
for ( j = 0; j < 3; ++j ) {
|
||||
if ( tris_v.size() ) {
|
||||
sgWriteShort( fp, (short)tris_v[i][j] );
|
||||
sgWriteUShort( fp, (unsigned short)tris_v[i][j] );
|
||||
}
|
||||
if ( tris_n.size() ) {
|
||||
sgWriteShort( fp, (short)tris_n[i][j] );
|
||||
sgWriteUShort( fp, (unsigned short)tris_n[i][j] );
|
||||
}
|
||||
if ( tris_c.size() ) {
|
||||
sgWriteShort( fp, (short)tris_c[i][j] );
|
||||
sgWriteUShort( fp, (unsigned short)tris_c[i][j] );
|
||||
}
|
||||
if ( tris_tc.size() ) {
|
||||
sgWriteShort( fp, (short)tris_tc[i][j] );
|
||||
sgWriteUShort( fp, (unsigned short)tris_tc[i][j] );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -922,8 +926,8 @@ bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
|
||||
// write group headers
|
||||
sgWriteChar( fp, (char)SG_TRIANGLE_STRIPS ); // type
|
||||
sgWriteShort( fp, 2 ); // nproperties
|
||||
sgWriteShort( fp, end - start ); // nelements
|
||||
sgWriteUShort( fp, 2 ); // nproperties
|
||||
sgWriteUShort( fp, end - start ); // nelements
|
||||
|
||||
sgWriteChar( fp, (char)SG_MATERIAL ); // property
|
||||
sgWriteUInt( fp, material.length() ); // nbytes
|
||||
@@ -942,19 +946,20 @@ bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
// write strips
|
||||
for ( i = start; i < end; ++i ) {
|
||||
// nbytes
|
||||
sgWriteUInt( fp, strips_v[i].size() * idx_size * sizeof(short));
|
||||
sgWriteUInt( fp, strips_v[i].size() * idx_size
|
||||
* sizeof(unsigned short));
|
||||
for ( j = 0; j < (int)strips_v[i].size(); ++j ) {
|
||||
if ( strips_v.size() ) {
|
||||
sgWriteShort( fp, (short)strips_v[i][j] );
|
||||
sgWriteUShort( fp, (unsigned short)strips_v[i][j] );
|
||||
}
|
||||
if ( strips_n.size() ) {
|
||||
sgWriteShort( fp, (short)strips_n[i][j] );
|
||||
sgWriteUShort( fp, (unsigned short)strips_n[i][j] );
|
||||
}
|
||||
if ( strips_c.size() ) {
|
||||
sgWriteShort( fp, (short)strips_c[i][j] );
|
||||
sgWriteUShort( fp, (unsigned short)strips_c[i][j] );
|
||||
}
|
||||
if ( strips_tc.size() ) {
|
||||
sgWriteShort( fp, (short)strips_tc[i][j] );
|
||||
sgWriteUShort( fp, (unsigned short)strips_tc[i][j] );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -982,8 +987,8 @@ bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
|
||||
// write group headers
|
||||
sgWriteChar( fp, (char)SG_TRIANGLE_FANS ); // type
|
||||
sgWriteShort( fp, 2 ); // nproperties
|
||||
sgWriteShort( fp, end - start ); // nelements
|
||||
sgWriteUShort( fp, 2 ); // nproperties
|
||||
sgWriteUShort( fp, end - start ); // nelements
|
||||
|
||||
sgWriteChar( fp, (char)SG_MATERIAL ); // property
|
||||
sgWriteUInt( fp, material.length() ); // nbytes
|
||||
@@ -1002,19 +1007,20 @@ bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
// write fans
|
||||
for ( i = start; i < end; ++i ) {
|
||||
// nbytes
|
||||
sgWriteUInt( fp, fans_v[i].size() * idx_size * sizeof(short) );
|
||||
sgWriteUInt( fp, fans_v[i].size() * idx_size
|
||||
* sizeof(unsigned short) );
|
||||
for ( j = 0; j < (int)fans_v[i].size(); ++j ) {
|
||||
if ( fans_v.size() ) {
|
||||
sgWriteShort( fp, (short)fans_v[i][j] );
|
||||
sgWriteUShort( fp, (unsigned short)fans_v[i][j] );
|
||||
}
|
||||
if ( fans_n.size() ) {
|
||||
sgWriteShort( fp, (short)fans_n[i][j] );
|
||||
sgWriteUShort( fp, (unsigned short)fans_n[i][j] );
|
||||
}
|
||||
if ( fans_c.size() ) {
|
||||
sgWriteShort( fp, (short)fans_c[i][j] );
|
||||
sgWriteUShort( fp, (unsigned short)fans_c[i][j] );
|
||||
}
|
||||
if ( fans_tc.size() ) {
|
||||
sgWriteShort( fp, (short)fans_tc[i][j] );
|
||||
sgWriteUShort( fp, (unsigned short)fans_tc[i][j] );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1042,7 +1048,6 @@ bool SGBinObject::write_bin( const string& base, const string& name,
|
||||
bool SGBinObject::write_ascii( const string& base, const string& name,
|
||||
const SGBucket& b )
|
||||
{
|
||||
Point3D p;
|
||||
int i, j;
|
||||
|
||||
SGPath file = base + "/" + b.gen_base_path() + "/" + name;
|
||||
@@ -1084,7 +1089,7 @@ bool SGBinObject::write_ascii( const string& base, const string& name,
|
||||
// dump vertex list
|
||||
fprintf(fp, "# vertex list\n");
|
||||
for ( i = 0; i < (int)wgs84_nodes.size(); ++i ) {
|
||||
p = wgs84_nodes[i] - gbs_center;
|
||||
SGVec3d p = wgs84_nodes[i] - gbs_center;
|
||||
|
||||
fprintf(fp, "v %.5f %.5f %.5f\n", p.x(), p.y(), p.z() );
|
||||
}
|
||||
@@ -1092,7 +1097,7 @@ bool SGBinObject::write_ascii( const string& base, const string& name,
|
||||
|
||||
fprintf(fp, "# vertex normal list\n");
|
||||
for ( i = 0; i < (int)normals.size(); ++i ) {
|
||||
p = normals[i];
|
||||
SGVec3f p = normals[i];
|
||||
fprintf(fp, "vn %.5f %.5f %.5f\n", p.x(), p.y(), p.z() );
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
@@ -1100,7 +1105,7 @@ bool SGBinObject::write_ascii( const string& base, const string& name,
|
||||
// dump texture coordinates
|
||||
fprintf(fp, "# texture coordinate list\n");
|
||||
for ( i = 0; i < (int)texcoords.size(); ++i ) {
|
||||
p = texcoords[i];
|
||||
SGVec2f p = texcoords[i];
|
||||
fprintf(fp, "vt %.5f %.5f\n", p.x(), p.y() );
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
@@ -1126,13 +1131,13 @@ bool SGBinObject::write_ascii( const string& base, const string& name,
|
||||
// make a list of points for the group
|
||||
point_list group_nodes;
|
||||
group_nodes.clear();
|
||||
Point3D bs_center;
|
||||
SGVec3d bs_center;
|
||||
double bs_radius = 0;
|
||||
for ( i = start; i < end; ++i ) {
|
||||
for ( j = 0; j < (int)tris_v[i].size(); ++j ) {
|
||||
group_nodes.push_back( wgs84_nodes[ tris_v[i][j] ] );
|
||||
bs_center = sgCalcCenter( group_nodes );
|
||||
bs_radius = sgCalcBoundingRadius( bs_center, group_nodes );
|
||||
group_nodes.push_back( Point3D::fromSGVec3(wgs84_nodes[ tris_v[i][j] ]) );
|
||||
bs_center = sgCalcCenter( group_nodes ).toSGVec3d();
|
||||
bs_radius = sgCalcBoundingRadius( Point3D::fromSGVec3(bs_center), group_nodes );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1177,13 +1182,13 @@ bool SGBinObject::write_ascii( const string& base, const string& name,
|
||||
// make a list of points for the group
|
||||
point_list group_nodes;
|
||||
group_nodes.clear();
|
||||
Point3D bs_center;
|
||||
SGVec3d bs_center;
|
||||
double bs_radius = 0;
|
||||
for ( i = start; i < end; ++i ) {
|
||||
for ( j = 0; j < (int)strips_v[i].size(); ++j ) {
|
||||
group_nodes.push_back( wgs84_nodes[ strips_v[i][j] ] );
|
||||
bs_center = sgCalcCenter( group_nodes );
|
||||
bs_radius = sgCalcBoundingRadius( bs_center, group_nodes );
|
||||
group_nodes.push_back( Point3D::fromSGVec3(wgs84_nodes[ strips_v[i][j] ]) );
|
||||
bs_center = sgCalcCenter( group_nodes ).toSGVec3d();
|
||||
bs_radius = sgCalcBoundingRadius( Point3D::fromSGVec3(bs_center), group_nodes );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#include <time.h>
|
||||
|
||||
#include <list>
|
||||
#include STL_STRING
|
||||
#include <string>
|
||||
|
||||
|
||||
|
||||
@@ -74,9 +74,9 @@ typedef group_list::const_iterator const_group_list_iterator;
|
||||
*
|
||||
* - prop_typecode: material_name | ???
|
||||
*
|
||||
* - nelements: SHORT (Gives us 65536 which ought to be enough, right?)
|
||||
* - nelements: USHORT (Gives us 65536 which ought to be enough, right?)
|
||||
*
|
||||
* - nproperties: SHORT
|
||||
* - nproperties: USHORT
|
||||
*
|
||||
* - *_typecode: CHAR
|
||||
*
|
||||
@@ -89,13 +89,13 @@ typedef group_list::const_iterator const_group_list_iterator;
|
||||
class SGBinObject {
|
||||
unsigned short version;
|
||||
|
||||
Point3D gbs_center;
|
||||
SGVec3d gbs_center;
|
||||
float gbs_radius;
|
||||
|
||||
point_list wgs84_nodes; // vertex list
|
||||
point_list colors; // color list
|
||||
point_list normals; // normal list
|
||||
point_list texcoords; // texture coordinate list
|
||||
std::vector<SGVec3d> wgs84_nodes; // vertex list
|
||||
std::vector<SGVec4f> colors; // color list
|
||||
std::vector<SGVec3f> normals; // normal list
|
||||
std::vector<SGVec2f> texcoords; // texture coordinate list
|
||||
|
||||
group_list pts_v; // points vertex index
|
||||
group_list pts_n; // points normal index
|
||||
@@ -125,23 +125,51 @@ public:
|
||||
|
||||
inline unsigned short get_version() const { return version; }
|
||||
|
||||
inline const Point3D& get_gbs_center() const { return gbs_center; }
|
||||
inline void set_gbs_center( const Point3D& p ) { gbs_center = p; }
|
||||
inline Point3D get_gbs_center() const { return Point3D::fromSGVec3(gbs_center); }
|
||||
inline void set_gbs_center( const Point3D& p ) { gbs_center = p.toSGVec3d(); }
|
||||
inline const SGVec3d& get_gbs_center2() const { return gbs_center; }
|
||||
inline void set_gbs_center( const SGVec3d& p ) { gbs_center = p; }
|
||||
|
||||
inline float get_gbs_radius() const { return gbs_radius; }
|
||||
inline void set_gbs_radius( float r ) { gbs_radius = r; }
|
||||
|
||||
inline const point_list& get_wgs84_nodes() const { return wgs84_nodes; }
|
||||
inline void set_wgs84_nodes( const point_list& n ) { wgs84_nodes = n; }
|
||||
inline const std::vector<SGVec3d>& get_wgs84_nodes() const
|
||||
{ return wgs84_nodes; }
|
||||
inline void set_wgs84_nodes( const std::vector<SGVec3d>& n )
|
||||
{ wgs84_nodes = n; }
|
||||
inline void set_wgs84_nodes( const point_list& n )
|
||||
{
|
||||
wgs84_nodes.resize(n.size());
|
||||
for (unsigned i = 0; i < wgs84_nodes.size(); ++i)
|
||||
wgs84_nodes[i] = n[i].toSGVec3d();
|
||||
}
|
||||
|
||||
inline const point_list& get_colors() const { return colors; }
|
||||
inline void set_colors( const point_list& c ) { colors = c; }
|
||||
inline const std::vector<SGVec4f>& get_colors() const { return colors; }
|
||||
inline void set_colors( const std::vector<SGVec4f>& c ) { colors = c; }
|
||||
inline void set_colors( const point_list& c )
|
||||
{
|
||||
colors.resize(c.size());
|
||||
for (unsigned i = 0; i < colors.size(); ++i)
|
||||
colors[i] = SGVec4f(c[i].toSGVec3f(), 1);
|
||||
}
|
||||
|
||||
inline const point_list& get_normals() const { return normals; }
|
||||
inline void set_normals( const point_list& n ) { normals = n; }
|
||||
inline const std::vector<SGVec3f>& get_normals() const { return normals; }
|
||||
inline void set_normals( const std::vector<SGVec3f>& n ) { normals = n; }
|
||||
inline void set_normals( const point_list& n )
|
||||
{
|
||||
normals.resize(n.size());
|
||||
for (unsigned i = 0; i < normals.size(); ++i)
|
||||
normals[i] = n[i].toSGVec3f();
|
||||
}
|
||||
|
||||
inline const point_list& get_texcoords() const { return texcoords; }
|
||||
inline void set_texcoords( const point_list& t ) { texcoords = t; }
|
||||
inline const std::vector<SGVec2f>& get_texcoords() const { return texcoords; }
|
||||
inline void set_texcoords( const std::vector<SGVec2f>& t ) { texcoords = t; }
|
||||
inline void set_texcoords( const point_list& t )
|
||||
{
|
||||
texcoords.resize(t.size());
|
||||
for (unsigned i = 0; i < texcoords.size(); ++i)
|
||||
texcoords[i] = t[i].toSGVec2f();
|
||||
}
|
||||
|
||||
inline const group_list& get_pts_v() const { return pts_v; }
|
||||
inline void set_pts_v( const group_list& g ) { pts_v = g; }
|
||||
|
||||
@@ -23,24 +23,26 @@
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include STL_STRING
|
||||
#include <string>
|
||||
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
# include <io.h>
|
||||
#endif
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include <simgear/misc/stdint.hxx>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#include "sg_file.hxx"
|
||||
|
||||
SG_USING_STD(string);
|
||||
using std::string;
|
||||
|
||||
|
||||
SGFile::SGFile( const string &file) {
|
||||
SGFile::SGFile(const string &file, int repeat_)
|
||||
: file_name(file), fp(-1), eof_flag(true), repeat(repeat_), iteration(0)
|
||||
{
|
||||
set_type( sgFileType );
|
||||
file_name = file;
|
||||
eof_flag = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -82,7 +84,20 @@ int SGFile::read( char *buf, int length ) {
|
||||
// read a chunk
|
||||
ssize_t result = ::read( fp, buf, length );
|
||||
if ( length > 0 && result == 0 ) {
|
||||
eof_flag = true;
|
||||
if (repeat < 0 || iteration < repeat - 1) {
|
||||
iteration++;
|
||||
// loop reading the file, unless it is empty
|
||||
off_t fileLen = ::lseek(fp, 0, SEEK_CUR);
|
||||
if (fileLen == 0) {
|
||||
eof_flag = true;
|
||||
return 0;
|
||||
} else {
|
||||
::lseek(fp, 0, SEEK_SET);
|
||||
return ::read(fp, buf, length);
|
||||
}
|
||||
} else {
|
||||
eof_flag = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -96,7 +111,13 @@ int SGFile::readline( char *buf, int length ) {
|
||||
// read a chunk
|
||||
ssize_t result = ::read( fp, buf, length );
|
||||
if ( length > 0 && result == 0 ) {
|
||||
eof_flag = true;
|
||||
if ((repeat < 0 || iteration < repeat - 1) && pos != 0) {
|
||||
iteration++;
|
||||
pos = ::lseek(fp, 0, SEEK_SET);
|
||||
result = ::read(fp, buf, length);
|
||||
} else {
|
||||
eof_flag = true;
|
||||
}
|
||||
}
|
||||
|
||||
// find the end of line and reset position
|
||||
@@ -129,7 +150,7 @@ int SGFile::write( const char *buf, const int length ) {
|
||||
|
||||
// write null terminated string to a file
|
||||
int SGFile::writestring( const char *str ) {
|
||||
int length = strlen( str );
|
||||
int length = std::strlen( str );
|
||||
return write( str, length );
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
#include "iochannel.hxx"
|
||||
|
||||
SG_USING_STD(string);
|
||||
using std::string;
|
||||
|
||||
|
||||
/**
|
||||
@@ -55,6 +55,10 @@ class SGFile : public SGIOChannel {
|
||||
string file_name;
|
||||
int fp;
|
||||
bool eof_flag;
|
||||
// Number of repetitions to play. -1 means loop infinitely.
|
||||
const int repeat;
|
||||
int iteration; // number of current repetition,
|
||||
// starting at 0
|
||||
|
||||
public:
|
||||
|
||||
@@ -64,8 +68,9 @@ public:
|
||||
* name. This file is not opened immediately, but instead will be
|
||||
* opened when the open() method is called.
|
||||
* @param file name of file to open
|
||||
* @param repeat On eof restart at the beginning of the file
|
||||
*/
|
||||
SGFile( const string& file );
|
||||
SGFile( const string& file, int repeat_ = 1 );
|
||||
|
||||
/** Destructor */
|
||||
~SGFile();
|
||||
|
||||
@@ -20,17 +20,19 @@
|
||||
//
|
||||
// $Id$
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include STL_STRING
|
||||
#include <string>
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/serial/serial.hxx>
|
||||
|
||||
#include "sg_serial.hxx"
|
||||
|
||||
SG_USING_STD(string);
|
||||
using std::string;
|
||||
|
||||
|
||||
SGSerial::SGSerial( const string& device_name, const string& baud_rate ) :
|
||||
@@ -57,7 +59,7 @@ bool SGSerial::open( const SGProtocolDir d ) {
|
||||
|
||||
// cout << "fd = " << port.fd << endl;
|
||||
|
||||
if ( ! port.set_baud( atoi( baud.c_str() ) ) ) {
|
||||
if ( ! port.set_baud( std::atoi( baud.c_str() ) ) ) {
|
||||
SG_LOG( SG_IO, SG_ALERT, "Error setting baud: " << baud );
|
||||
return false;
|
||||
}
|
||||
@@ -80,7 +82,7 @@ int SGSerial::read( char *buf, int length ) {
|
||||
result = port.read_port( buf_ptr, length - save_len );
|
||||
|
||||
if ( result + save_len == length ) {
|
||||
strncpy( buf, save_buf, length );
|
||||
std::strncpy( buf, save_buf, length );
|
||||
save_len = 0;
|
||||
|
||||
return length;
|
||||
@@ -114,7 +116,7 @@ int SGSerial::readline( char *buf, int length ) {
|
||||
// we found an end of line
|
||||
|
||||
// copy to external buffer
|
||||
strncpy( buf, save_buf, result );
|
||||
std::strncpy( buf, save_buf, result );
|
||||
buf[result] = '\0';
|
||||
SG_LOG( SG_IO, SG_INFO, "fg_serial line = " << buf );
|
||||
|
||||
@@ -142,7 +144,7 @@ int SGSerial::write( const char *buf, const int length ) {
|
||||
|
||||
// write null terminated string to port
|
||||
int SGSerial::writestring( const char *str ) {
|
||||
int length = strlen( str );
|
||||
int length = std::strlen( str );
|
||||
return write( str, length );
|
||||
}
|
||||
|
||||
|
||||
@@ -36,17 +36,11 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
// #ifdef SG_HAVE_STD_INCLUDES
|
||||
// # include <ctime>
|
||||
// #else
|
||||
// # include <time.h>
|
||||
// #endif
|
||||
|
||||
#include <simgear/serial/serial.hxx>
|
||||
|
||||
#include "iochannel.hxx"
|
||||
|
||||
SG_USING_STD(string);
|
||||
using std::string;
|
||||
|
||||
/**
|
||||
* A serial I/O class based on SGIOChannel.
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
#include STL_IOSTREAM
|
||||
#include <iostream>
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
|
||||
@@ -34,14 +34,14 @@
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include STL_STRING
|
||||
#include <string>
|
||||
|
||||
#include <simgear/math/sg_types.hxx>
|
||||
#include <simgear/io/iochannel.hxx>
|
||||
|
||||
#include <plib/netSocket.h>
|
||||
|
||||
SG_USING_STD(string);
|
||||
using std::string;
|
||||
|
||||
#define SG_MAX_SOCKET_QUEUE 32
|
||||
|
||||
|
||||
@@ -36,12 +36,12 @@
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include STL_STRING
|
||||
#include <string>
|
||||
|
||||
#include <simgear/math/sg_types.hxx>
|
||||
#include <simgear/io/iochannel.hxx>
|
||||
|
||||
SG_USING_STD(string);
|
||||
using std::string;
|
||||
|
||||
/**
|
||||
* A UDP socket I/O class based on SGIOChannel and plib/net.
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include STL_IOSTREAM
|
||||
#include <iostream>
|
||||
|
||||
#include "sg_socket.hxx"
|
||||
#include "lowlevel.hxx"
|
||||
@@ -10,8 +14,8 @@ static const int sgEndianTest = 1;
|
||||
#define sgIsLittleEndian (*((char *) &sgEndianTest ) != 0)
|
||||
#define sgIsBigEndian (*((char *) &sgEndianTest ) == 0)
|
||||
|
||||
SG_USING_STD(cout);
|
||||
SG_USING_STD(endl);
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
|
||||
int main() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <simgear/compiler.h>
|
||||
#include STL_IOSTREAM
|
||||
#include <iostream>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
@@ -7,6 +7,8 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#include "sg_socket.hxx"
|
||||
@@ -49,7 +51,7 @@ TcpClient::process()
|
||||
|
||||
sprintf( wbuf, "hello world\n" );
|
||||
int length = channel->writestring( wbuf );
|
||||
cout << "writestring returned " << length << "\n";
|
||||
std::cout << "writestring returned " << length << "\n";
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -67,7 +69,7 @@ main()
|
||||
TcpClient client( "localhost", "5500" );
|
||||
if (!client.open())
|
||||
{
|
||||
cout << "client open failed\n";
|
||||
std::cout << "client open failed\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#include <simgear/compiler.h>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include STL_STRING
|
||||
#include STL_IOSTREAM
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#include "sg_socket.hxx"
|
||||
|
||||
SG_USING_STD(string);
|
||||
SG_USING_STD(cout);
|
||||
using std::string;
|
||||
using std::cout;
|
||||
|
||||
class TcpServer
|
||||
{
|
||||
|
||||
@@ -13,7 +13,7 @@ noinst_PROGRAMS = testmagvar
|
||||
testmagvar_SOURCES = testmagvar.cxx
|
||||
|
||||
testmagvar_LDADD = \
|
||||
$(top_builddir)/simgear/magvar/libsgmagvar.a \
|
||||
libsgmagvar.a \
|
||||
$(base_LIBS)
|
||||
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
|
||||
@@ -23,6 +23,19 @@
|
||||
//
|
||||
// Put in some bullet-proofing to handle magnetic and geographic poles.
|
||||
// 3/28/2000 EAW
|
||||
//
|
||||
// Updated coefficient arrays to use the current WMM2005 model,
|
||||
// (valid between 2005.0 and 2010.0)
|
||||
// Also removed unused variables and corrected earth radii constants
|
||||
// to the values for WGS84 and WMM2005.
|
||||
// Reference:
|
||||
// McLean, S., S. Macmillan, S. Maus, V. Lesur, A.
|
||||
// Thomson, and D. Dater, December 2004, The
|
||||
// US/UK World Magnetic Model for 2005-2010,
|
||||
// NOAA Technical Report NESDIS/NGDC-1.
|
||||
//
|
||||
// 25/10/2006 Wim Van Hoydonck -- wim.van.hoydonck@gmail.com
|
||||
//
|
||||
|
||||
// The routine uses a spherical harmonic expansion of the magnetic
|
||||
// potential up to twelfth order, together with its time variation, as
|
||||
@@ -73,76 +86,72 @@
|
||||
|
||||
#include "coremag.hxx"
|
||||
|
||||
static const double a = 6378.137; /* semi-major axis (equatorial radius) of WGS84 ellipsoid */
|
||||
static const double b = 6356.7523142; /* semi-minor axis referenced to the WGS84 ellipsoid */
|
||||
static const double r_0 = 6371.2; /* standard Earth magnetic reference radius */
|
||||
|
||||
static const double pi = 3.14159265358979;
|
||||
static const double a = 6378.16; /* major radius (km) IAU66 ellipsoid */
|
||||
static const double f = 1.0 / 298.25; /* inverse flattening IAU66 ellipsoid */
|
||||
static const double b = 6378.16 * (1.0 -1.0 / 298.25 );
|
||||
/* minor radius b=a*(1-f) */
|
||||
static const double r_0 = 6371.2; /* "mean radius" for spherical harmonic expansion */
|
||||
|
||||
static double gnm_wmm2000[13][13] =
|
||||
static double gnm_wmm2005[13][13] =
|
||||
{
|
||||
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{-29616.0, -1722.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{-2266.7, 3070.2, 1677.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{1322.4, -2291.5, 1255.9, 724.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{932.1, 786.3, 250.6, -401.5, 106.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{-211.9, 351.6, 220.8, -134.5, -168.8, -13.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{73.8, 68.2, 74.1, -163.5, -3.8, 17.1, -85.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{77.4, -73.9, 2.2, 35.7, 7.3, 5.2, 8.4, -1.5, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{23.3, 7.3, -8.5, -6.6, -16.9, 8.6, 4.9, -7.8, -7.6, 0.0, 0.0, 0.0, 0.0},
|
||||
{5.7, 8.5, 2.0, -9.8, 7.6, -7.0, -2.0, 9.2, -2.2, -6.6, 0.0, 0.0, 0.0},
|
||||
{-2.2, -5.7, 1.6, -3.7, -0.6, 4.1, 2.2, 2.2, 4.6, 2.3, 0.1, 0.0, 0.0},
|
||||
{3.3, -1.1, -2.4, 2.6, -1.3, -1.7, -0.6, 0.4, 0.7, -0.3, 2.3, 4.2, 0.0},
|
||||
{-1.5, -0.2, -0.3, 0.5, 0.2, 0.9, -1.4, 0.6, -0.6, -1.0, -0.3, 0.3, 0.4},
|
||||
{-29556.8, -1671.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{-2340.6, 3046.9, 1657.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{1335.4, -2305.1, 1246.7, 674.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{919.8, 798.1, 211.3, -379.4, 100.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{-227.4, 354.6, 208.7, -136.5, -168.3, -14.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{73.2, 69.7, 76.7, -151.2, -14.9, 14.6, -86.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{80.1, -74.5, -1.4, 38.5, 12.4, 9.5, 5.7, 1.8, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{24.9, 7.7, -11.6, -6.9, -18.2, 10.0, 9.2, -11.6, -5.2, 0.0, 0.0, 0.0, 0.0},
|
||||
{5.6, 9.9, 3.5, -7.0, 5.1, -10.8, -1.3, 8.8, -6.7, -9.1, 0.0, 0.0, 0.0},
|
||||
{-2.3, -6.3, 1.6, -2.6, 0.0, 3.1, 0.4, 2.1, 3.9, -0.1, -2.3, 0.0, 0.0},
|
||||
{2.8, -1.6, -1.7, 1.7, -0.1, 0.1, -0.7, 0.7, 1.8, 0.0, 1.1, 4.1, 0.0},
|
||||
{-2.4, -0.4, 0.2, 0.8, -0.3, 1.1, -0.5, 0.4, -0.3, -0.3, -0.1, -0.3, -0.1},
|
||||
};
|
||||
|
||||
static double hnm_wmm2000[13][13]=
|
||||
static double hnm_wmm2005[13][13]=
|
||||
{
|
||||
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 5194.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -2484.8, -467.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -224.7, 293.0, -486.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 273.3, -227.9, 120.9, -302.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 42.0, 173.8, -135.0, -38.6, 105.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -17.4, 61.2, 63.2, -62.9, 0.2, 43.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -62.3, -24.5, 8.9, 23.4, 15.0, -27.6, -7.8, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 12.4, -20.8, 8.4, -21.2, 15.5, 9.1, -15.5, -5.4, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -20.4, 13.9, 12.0, -6.2, -8.6, 9.4, 5.0, -8.4, 3.2, 0.0, 0.0, 0.0},
|
||||
{0.0, 0.9, -0.7, 3.9, 4.8, -5.3, -1.0, -2.4, 1.3, -2.3, -6.4, 0.0, 0.0},
|
||||
{0.0, -1.5, 0.7, -1.1, -2.3, 1.3, -0.6, -2.8, -1.6, -0.1, -1.9, 1.4, 0.0},
|
||||
{0.0, -1.0, 0.7, 2.2, -2.5, -0.2, 0.0, -0.2, 0.0, 0.2, -0.9, -0.2, 1.0},
|
||||
{0.0, 5079.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -2594.7, -516.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -199.9, 269.3, -524.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 281.5, -226.0, 145.8, -304.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 42.4, 179.8, -123.0, -19.5, 103.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -20.3, 54.7, 63.6, -63.4, -0.1, 50.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -61.5, -22.4, 7.2, 25.4, 11.0, -26.4, -5.1, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 11.2, -21.0, 9.6, -19.8, 16.1, 7.7, -12.9, -0.2, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -20.1, 12.9, 12.6, -6.7, -8.1, 8.0, 2.9, -7.9, 6.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 2.4, 0.2, 4.4, 4.8, -6.5, -1.1, -3.4, -0.8, -2.3, -7.9, 0.0, 0.0},
|
||||
{0.0, 0.3, 1.2, -0.8, -2.5, 0.9, -0.6, -2.7, -0.9, -1.3, -2.0, -1.2, 0.0},
|
||||
{0.0, -0.4, 0.3, 2.4, -2.6, 0.6, 0.3, 0.0, 0.0, 0.3, -0.9, -0.4, 0.8},
|
||||
};
|
||||
|
||||
static double gtnm_wmm2000[13][13]=
|
||||
static double gtnm_wmm2005[13][13]=
|
||||
{
|
||||
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{14.7, 11.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{-13.6, -0.7, -1.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.3, -4.3, 0.9, -8.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{-1.6, 0.9, -7.6, 2.2, -3.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{-0.9, -0.2, -2.5, -2.7, -0.9, 1.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{1.2, 0.2, 1.7, 1.6, -0.1, -0.3, 0.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{-0.4, -0.8, -0.2, 1.1, 0.4, 0.0, -0.2, -0.2, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{-0.3, 0.6, -0.8, 0.3, -0.2, 0.5, 0.0, -0.6, 0.1, 0.0, 0.0, 0.0, 0.0},
|
||||
{8.0, 10.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{-15.1, -7.8, -0.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.4, -2.6, -1.2, -6.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{-2.5, 2.8, -7.0, 6.2, -3.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{-2.8, 0.7, -3.2, -1.1, 0.1, -0.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{-0.7, 0.4, -0.3, 2.3, -2.1, -0.6, 1.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.2, -0.1, -0.3, 1.1, 0.6, 0.5, -0.4, 0.6, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.1, 0.3, -0.4, 0.3, -0.3, 0.2, 0.4, -0.7, 0.4, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
};
|
||||
|
||||
static double htnm_wmm2000[13][13]=
|
||||
static double htnm_wmm2005[13][13]=
|
||||
{
|
||||
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -20.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -21.5, -9.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 6.4, -1.3, -13.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 2.3, 0.7, 3.7, -0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 0.0, 2.1, 2.3, 3.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -0.3, -1.7, -0.9, -1.0, -0.1, 1.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 1.4, 0.2, 0.7, 0.4, -0.3, -0.8, -0.1, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -0.5, 0.1, -0.2, 0.0, 0.1, -0.1, 0.3, 0.2, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -20.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -23.2, -14.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 5.0, -7.0, -0.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 2.2, 1.6, 5.8, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 0.0, 1.7, 2.1, 4.8, -1.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -0.6, -1.9, -0.4, -0.5, -0.3, 0.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 0.6, 0.4, 0.2, 0.3, -0.8, -0.2, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, -0.2, 0.1, 0.3, 0.4, 0.1, -0.2, 0.4, 0.4, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
@@ -186,8 +195,8 @@ double calc_magvar( double lat, double lon, double h, long dat, double* field )
|
||||
{
|
||||
/* output field B_r,B_th,B_phi,B_x,B_y,B_z */
|
||||
int n,m;
|
||||
/* reference dates */
|
||||
long date0_wmm2000 = yymmdd_to_julian_days(0,1,1);
|
||||
/* reference date for current model is 1 januari 2005 */
|
||||
long date0_wmm2005 = yymmdd_to_julian_days(5,1,1);
|
||||
|
||||
double yearfrac,sr,r,theta,c,s,psi,fn,fn_0,B_r,B_theta,B_phi,X,Y,Z;
|
||||
double sinpsi, cospsi, inv_s;
|
||||
@@ -272,13 +281,14 @@ double calc_magvar( double lat, double lon, double h, long dat, double* field )
|
||||
}
|
||||
}
|
||||
|
||||
/* compute gnm, hnm at dat */
|
||||
/* WMM2000 */
|
||||
yearfrac = (dat - date0_wmm2000) / 365.25;
|
||||
/* compute Gauss coefficients gnm and hnm of degree n and order m for the desired time
|
||||
achieved by adjusting the coefficients at time t0 for linear secular variation */
|
||||
/* WMM2005 */
|
||||
yearfrac = (dat - date0_wmm2005) / 365.25;
|
||||
for ( n = 1; n <= nmax; n++ ) {
|
||||
for ( m = 0; m <= nmax; m++ ) {
|
||||
gnm[n][m] = gnm_wmm2000[n][m] + yearfrac * gtnm_wmm2000[n][m];
|
||||
hnm[n][m] = hnm_wmm2000[n][m] + yearfrac * htnm_wmm2000[n][m];
|
||||
gnm[n][m] = gnm_wmm2005[n][m] + yearfrac * gtnm_wmm2005[n][m];
|
||||
hnm[n][m] = hnm_wmm2005[n][m] + yearfrac * htnm_wmm2005[n][m];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,7 +323,7 @@ double calc_magvar( double lat, double lon, double h, long dat, double* field )
|
||||
}
|
||||
|
||||
/* Find geodetic field components: */
|
||||
psi = theta - ((pi / 2.0) - lat);
|
||||
psi = theta - ((M_PI / 2.0) - lat);
|
||||
sinpsi = sin(psi);
|
||||
cospsi = cos(psi);
|
||||
X = -B_theta * cospsi - B_r * sinpsi;
|
||||
@@ -340,7 +350,7 @@ double SGMagVarOrig( double lat, double lon, double h, long dat, double* field )
|
||||
/* output field B_r,B_th,B_phi,B_x,B_y,B_z */
|
||||
int n,m;
|
||||
/* reference dates */
|
||||
long date0_wmm2000 = yymmdd_to_julian_days(0,1,1);
|
||||
long date0_wmm2005 = yymmdd_to_julian_days(5,1,1);
|
||||
|
||||
double yearfrac,sr,r,theta,c,s,psi,fn,B_r,B_theta,B_phi,X,Y,Z;
|
||||
|
||||
@@ -397,12 +407,12 @@ double SGMagVarOrig( double lat, double lon, double h, long dat, double* field )
|
||||
}
|
||||
|
||||
/* compute gnm, hnm at dat */
|
||||
/* WMM2000 */
|
||||
yearfrac = (dat - date0_wmm2000) / 365.25;
|
||||
/* WMM2005 */
|
||||
yearfrac = (dat - date0_wmm2005) / 365.25;
|
||||
for ( n = 1; n <= nmax; n++ ) {
|
||||
for ( m = 0; m <= nmax; m++ ) {
|
||||
gnm[n][m] = gnm_wmm2000[n][m] + yearfrac * gtnm_wmm2000[n][m];
|
||||
hnm[n][m] = hnm_wmm2000[n][m] + yearfrac * htnm_wmm2000[n][m];
|
||||
gnm[n][m] = gnm_wmm2005[n][m] + yearfrac * gtnm_wmm2005[n][m];
|
||||
hnm[n][m] = hnm_wmm2005[n][m] + yearfrac * htnm_wmm2005[n][m];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
includedir = @includedir@/math
|
||||
|
||||
noinst_PROGRAMS = SGMathTest
|
||||
check_PROGRAMS = SGMathTest
|
||||
check_PROGRAMS = SGMathTest SGGeometryTest
|
||||
TESTS = $(check_PROGRAMS)
|
||||
|
||||
SGMathTest_SOURCES = SGMathTest.cxx
|
||||
SGMathTest_LDADD = libsgmath.a $(base_LIBS)
|
||||
|
||||
SGGeometryTest_SOURCES = SGGeometryTest.cxx
|
||||
SGGeometryTest_LDADD = libsgmath.a $(base_LIBS)
|
||||
|
||||
lib_LIBRARIES = libsgmath.a
|
||||
|
||||
@@ -16,33 +17,39 @@ include_HEADERS = \
|
||||
point3d.hxx \
|
||||
polar3d.hxx \
|
||||
sg_geodesy.hxx \
|
||||
sg_memory.h \
|
||||
sg_random.h \
|
||||
sg_types.hxx \
|
||||
vector.hxx \
|
||||
fastmath.hxx \
|
||||
Math.hxx \
|
||||
SGBox.hxx \
|
||||
SGCMath.hxx \
|
||||
SGGeoc.hxx \
|
||||
SGGeod.hxx \
|
||||
SGGeodesy.hxx \
|
||||
SGGeometry.hxx \
|
||||
SGGeometryFwd.hxx \
|
||||
SGIntersect.hxx \
|
||||
SGLimits.hxx \
|
||||
SGLineSegment.hxx \
|
||||
SGMatrix.hxx \
|
||||
SGMath.hxx \
|
||||
SGMathFwd.hxx \
|
||||
SGMisc.hxx \
|
||||
SGPlane.hxx \
|
||||
SGQuat.hxx \
|
||||
SGVec4.hxx \
|
||||
SGVec3.hxx
|
||||
|
||||
|
||||
EXTRA_DIST = linintp2.h linintp2.inl sphrintp.h sphrintp.inl
|
||||
SGRay.hxx \
|
||||
SGSphere.hxx \
|
||||
SGTriangle.hxx \
|
||||
SGVec2.hxx \
|
||||
SGVec3.hxx \
|
||||
SGVec4.hxx
|
||||
|
||||
libsgmath_a_SOURCES = \
|
||||
interpolater.cxx \
|
||||
leastsqs.cxx \
|
||||
polar3d.cxx \
|
||||
sg_geodesy.cxx \
|
||||
sg_random.c \
|
||||
vector.cxx \
|
||||
fastmath.cxx \
|
||||
SGGeod.cxx \
|
||||
SGGeodesy.cxx
|
||||
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
|
||||
23
simgear/math/Math.hxx
Normal file
23
simgear/math/Math.hxx
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef SIMGEAR_MATH_MATH_HXX
|
||||
#define SIMGEAR_MATH_MATH_HXX 1
|
||||
namespace simgear
|
||||
{
|
||||
namespace math
|
||||
{
|
||||
/** Linear interpolation between two values.
|
||||
*/
|
||||
template<typename T>
|
||||
inline T lerp(const T& x, const T& y, double alpha)
|
||||
{
|
||||
return x * (1.0 - alpha) + y * alpha;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline T lerp(const T& x, const T& y, float alpha)
|
||||
{
|
||||
return x * (1.0f - alpha) + y * alpha;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
107
simgear/math/SGBox.hxx
Normal file
107
simgear/math/SGBox.hxx
Normal file
@@ -0,0 +1,107 @@
|
||||
// Copyright (C) 2006 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
|
||||
#ifndef SGBox_H
|
||||
#define SGBox_H
|
||||
|
||||
template<typename T>
|
||||
class SGBox {
|
||||
public:
|
||||
SGBox() :
|
||||
_min(SGLimits<T>::max(), SGLimits<T>::max(), SGLimits<T>::max()),
|
||||
_max(-SGLimits<T>::max(), -SGLimits<T>::max(), -SGLimits<T>::max())
|
||||
{ }
|
||||
void setMin(const SGVec3<T>& min)
|
||||
{ _min = min; }
|
||||
const SGVec3<T>& getMin() const
|
||||
{ return _min; }
|
||||
|
||||
void setMax(const SGVec3<T>& max)
|
||||
{ _max = max; }
|
||||
const SGVec3<T>& getMax() const
|
||||
{ return _max; }
|
||||
|
||||
// Only works for floating point types
|
||||
SGVec3<T> getCenter() const
|
||||
{ return T(0.5)*(_min + _max); }
|
||||
|
||||
// Only valid for nonempty boxes
|
||||
SGVec3<T> getSize() const
|
||||
{ return _max - _min; }
|
||||
|
||||
T getVolume() const
|
||||
{
|
||||
if (empty())
|
||||
return 0;
|
||||
return (_max[0] - _min[0])*(_max[1] - _min[1])*(_max[2] - _min[2]);
|
||||
}
|
||||
|
||||
const bool empty() const
|
||||
{ return !valid(); }
|
||||
|
||||
bool valid() const
|
||||
{
|
||||
if (_max[0] < _min[0])
|
||||
return false;
|
||||
if (_max[1] < _min[1])
|
||||
return false;
|
||||
if (_max[2] < _min[2])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
_min[0] = SGLimits<T>::max();
|
||||
_min[1] = SGLimits<T>::max();
|
||||
_min[2] = SGLimits<T>::max();
|
||||
_max[0] = -SGLimits<T>::max();
|
||||
_max[1] = -SGLimits<T>::max();
|
||||
_max[2] = -SGLimits<T>::max();
|
||||
}
|
||||
|
||||
void expandBy(const SGVec3<T>& v)
|
||||
{ _min = min(_min, v); _max = max(_max, v); }
|
||||
|
||||
void expandBy(const SGBox<T>& b)
|
||||
{ _min = min(_min, b._min); _max = max(_max, b._max); }
|
||||
|
||||
// Note that this only works if the box is nonmepty
|
||||
unsigned getBroadestAxis() const
|
||||
{
|
||||
SGVec3d size = getSize();
|
||||
if (size[1] <= size[0] && size[2] <= size[0])
|
||||
return 0;
|
||||
else if (size[2] <= size[1])
|
||||
return 1;
|
||||
else
|
||||
return 2;
|
||||
}
|
||||
|
||||
private:
|
||||
SGVec3<T> _min;
|
||||
SGVec3<T> _max;
|
||||
};
|
||||
|
||||
/// Output to an ostream
|
||||
template<typename char_type, typename traits_type, typename T>
|
||||
inline
|
||||
std::basic_ostream<char_type, traits_type>&
|
||||
operator<<(std::basic_ostream<char_type, traits_type>& s, const SGBox<T>& box)
|
||||
{ return s << "min = " << box.getMin() << ", max = " << box.getMax(); }
|
||||
|
||||
#endif
|
||||
25
simgear/math/SGCMath.hxx
Normal file
25
simgear/math/SGCMath.hxx
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright (C) 2006 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
|
||||
#ifndef SGCMath_H
|
||||
#define SGCMath_H
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#endif
|
||||
@@ -27,12 +27,6 @@ class SGGeoc {
|
||||
public:
|
||||
/// Default constructor, initializes the instance to lat = lon = lat = 0
|
||||
SGGeoc(void);
|
||||
/// Initialize from a cartesian vector assumed to be in meters
|
||||
/// Note that this conversion is relatively expensive to compute
|
||||
SGGeoc(const SGVec3<double>& cart);
|
||||
/// Initialize from a geodetic position
|
||||
/// Note that this conversion is relatively expensive to compute
|
||||
SGGeoc(const SGGeod& geod);
|
||||
|
||||
/// Factory from angular values in radians and radius in ft
|
||||
static SGGeoc fromRadFt(double lon, double lat, double radius);
|
||||
@@ -42,6 +36,13 @@ public:
|
||||
static SGGeoc fromRadM(double lon, double lat, double radius);
|
||||
/// Factory from angular values in degrees and radius in m
|
||||
static SGGeoc fromDegM(double lon, double lat, double radius);
|
||||
/// Factory to convert position from a cartesian position assumed to be
|
||||
/// in wgs84 measured in meters
|
||||
/// Note that this conversion is relatively expensive to compute
|
||||
static SGGeoc fromCart(const SGVec3<double>& cart);
|
||||
/// Factory to convert position from a geodetic position
|
||||
/// Note that this conversion is relatively expensive to compute
|
||||
static SGGeoc fromGeod(const SGGeod& geod);
|
||||
|
||||
/// Return the geocentric longitude in radians
|
||||
double getLongitudeRad(void) const;
|
||||
@@ -73,6 +74,11 @@ public:
|
||||
/// Set the geocentric radius from the argument given in feet
|
||||
void setRadiusFt(double radius);
|
||||
|
||||
SGGeoc advanceRadM(double course, double distance) const;
|
||||
static double courseRad(const SGGeoc& from, const SGGeoc& to);
|
||||
static double courseDeg(const SGGeoc& from, const SGGeoc& to);
|
||||
static double distanceM(const SGGeoc& from, const SGGeoc& to);
|
||||
|
||||
private:
|
||||
/// This one is private since construction is not unique if you do
|
||||
/// not know the units of the arguments, use the factory methods for
|
||||
@@ -103,20 +109,6 @@ SGGeoc::SGGeoc(double lon, double lat, double radius) :
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
SGGeoc::SGGeoc(const SGVec3<double>& cart)
|
||||
{
|
||||
SGGeodesy::SGCartToGeoc(cart, *this);
|
||||
}
|
||||
|
||||
inline
|
||||
SGGeoc::SGGeoc(const SGGeod& geod)
|
||||
{
|
||||
SGVec3<double> cart;
|
||||
SGGeodesy::SGGeodToCart(geod, cart);
|
||||
SGGeodesy::SGCartToGeoc(cart, *this);
|
||||
}
|
||||
|
||||
inline
|
||||
SGGeoc
|
||||
SGGeoc::fromRadFt(double lon, double lat, double radius)
|
||||
@@ -165,6 +157,26 @@ SGGeoc::fromDegM(double lon, double lat, double radius)
|
||||
#endif
|
||||
}
|
||||
|
||||
inline
|
||||
SGGeoc
|
||||
SGGeoc::fromCart(const SGVec3<double>& cart)
|
||||
{
|
||||
SGGeoc geoc;
|
||||
SGGeodesy::SGCartToGeoc(cart, geoc);
|
||||
return geoc;
|
||||
}
|
||||
|
||||
inline
|
||||
SGGeoc
|
||||
SGGeoc::fromGeod(const SGGeod& geod)
|
||||
{
|
||||
SGVec3<double> cart;
|
||||
SGGeodesy::SGGeodToCart(geod, cart);
|
||||
SGGeoc geoc;
|
||||
SGGeodesy::SGCartToGeoc(cart, geoc);
|
||||
return geoc;
|
||||
}
|
||||
|
||||
inline
|
||||
double
|
||||
SGGeoc::getLongitudeRad(void) const
|
||||
@@ -194,7 +206,7 @@ SGGeoc::getLongitudeDeg(void) const
|
||||
#ifdef SG_GEOC_NATIVE_DEGREE
|
||||
return _lon;
|
||||
#else
|
||||
return _lon*SGD_DEGREES_TO_RADIANS;
|
||||
return _lon*SGD_RADIANS_TO_DEGREES;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -205,7 +217,7 @@ SGGeoc::setLongitudeDeg(double lon)
|
||||
#ifdef SG_GEOC_NATIVE_DEGREE
|
||||
_lon = lon;
|
||||
#else
|
||||
_lon = lon*SGD_RADIANS_TO_DEGREES;
|
||||
_lon = lon*SGD_DEGREES_TO_RADIANS;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -238,7 +250,7 @@ SGGeoc::getLatitudeDeg(void) const
|
||||
#ifdef SG_GEOC_NATIVE_DEGREE
|
||||
return _lat;
|
||||
#else
|
||||
return _lat*SGD_DEGREES_TO_RADIANS;
|
||||
return _lat*SGD_RADIANS_TO_DEGREES;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -249,7 +261,7 @@ SGGeoc::setLatitudeDeg(double lat)
|
||||
#ifdef SG_GEOC_NATIVE_DEGREE
|
||||
_lat = lat;
|
||||
#else
|
||||
_lat = lat*SGD_RADIANS_TO_DEGREES;
|
||||
_lat = lat*SGD_DEGREES_TO_RADIANS;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -281,6 +293,36 @@ SGGeoc::setRadiusFt(double radius)
|
||||
_radius = radius*SG_FEET_TO_METER;
|
||||
}
|
||||
|
||||
inline
|
||||
SGGeoc
|
||||
SGGeoc::advanceRadM(double course, double distance) const
|
||||
{
|
||||
SGGeoc result;
|
||||
SGGeodesy::advanceRadM(*this, course, distance, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline
|
||||
double
|
||||
SGGeoc::courseRad(const SGGeoc& from, const SGGeoc& to)
|
||||
{
|
||||
return SGGeodesy::courseRad(from, to);
|
||||
}
|
||||
|
||||
inline
|
||||
double
|
||||
SGGeoc::courseDeg(const SGGeoc& from, const SGGeoc& to)
|
||||
{
|
||||
return SGMiscd::rad2deg(courseRad(from, to));
|
||||
}
|
||||
|
||||
inline
|
||||
double
|
||||
SGGeoc::distanceM(const SGGeoc& from, const SGGeoc& to)
|
||||
{
|
||||
return SGGeodesy::distanceM(from, to);
|
||||
}
|
||||
|
||||
/// Output to an ostream
|
||||
template<typename char_type, typename traits_type>
|
||||
inline
|
||||
|
||||
51
simgear/math/SGGeod.cxx
Normal file
51
simgear/math/SGGeod.cxx
Normal file
@@ -0,0 +1,51 @@
|
||||
// Copyright (C) 2008 Tim Moore timoore@redhat.com
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
|
||||
#include "SGMath.hxx"
|
||||
|
||||
osg::Matrix SGGeod::makeSimulationFrameRelative()
|
||||
{
|
||||
SGQuatd hlOr = SGQuatd::fromLonLat(*this);
|
||||
return osg::Matrix(hlOr.osg());
|
||||
}
|
||||
|
||||
osg::Matrix SGGeod::makeSimulationFrame()
|
||||
{
|
||||
osg::Matrix result(makeSimulationFrameRelative());
|
||||
SGVec3d coord;
|
||||
SGGeodesy::SGGeodToCart(*this, coord);
|
||||
result.setTrans(coord.osg());
|
||||
return result;
|
||||
}
|
||||
|
||||
osg::Matrix SGGeod::makeZUpFrameRelative()
|
||||
{
|
||||
osg::Matrix result(makeSimulationFrameRelative());
|
||||
// 180 degree rotation around Y axis
|
||||
osg::Quat flip(0.0, 1.0, 0.0, 0.0);
|
||||
result.preMult(osg::Matrix(flip));
|
||||
return result;
|
||||
}
|
||||
|
||||
osg::Matrix SGGeod::makeZUpFrame()
|
||||
{
|
||||
osg::Matrix result(makeZUpFrameRelative());
|
||||
SGVec3d coord;
|
||||
SGGeodesy::SGGeodToCart(*this, coord);
|
||||
result.setTrans(coord.osg());
|
||||
return result;
|
||||
}
|
||||
@@ -20,6 +20,8 @@
|
||||
|
||||
#include <simgear/constants.h>
|
||||
|
||||
#include <osg/Matrix>
|
||||
|
||||
// #define SG_GEOD_NATIVE_DEGREE
|
||||
|
||||
/// Class representing a geodetic location
|
||||
@@ -27,12 +29,6 @@ class SGGeod {
|
||||
public:
|
||||
/// Default constructor, initializes the instance to lat = lon = elev = 0
|
||||
SGGeod(void);
|
||||
/// Initialize from a cartesian vector assumed to be in meters
|
||||
/// Note that this conversion is relatively expensive to compute
|
||||
SGGeod(const SGVec3<double>& cart);
|
||||
/// Initialize from a geocentric position
|
||||
/// Note that this conversion is relatively expensive to compute
|
||||
SGGeod(const SGGeoc& geoc);
|
||||
|
||||
/// Factory from angular values in radians and elevation is 0
|
||||
static SGGeod fromRad(double lon, double lat);
|
||||
@@ -46,6 +42,13 @@ public:
|
||||
static SGGeod fromRadM(double lon, double lat, double elevation);
|
||||
/// Factory from angular values in degrees and elevation in m
|
||||
static SGGeod fromDegM(double lon, double lat, double elevation);
|
||||
/// Factory to convert position from a cartesian position assumed to be
|
||||
/// in wgs84 measured in meters
|
||||
/// Note that this conversion is relatively expensive to compute
|
||||
static SGGeod fromCart(const SGVec3<double>& cart);
|
||||
/// Factory to convert position from a geocentric position
|
||||
/// Note that this conversion is relatively expensive to compute
|
||||
static SGGeod fromGeoc(const SGGeoc& geoc);
|
||||
|
||||
/// Return the geodetic longitude in radians
|
||||
double getLongitudeRad(void) const;
|
||||
@@ -77,6 +80,18 @@ public:
|
||||
/// Set the geodetic elevation from the argument given in feet
|
||||
void setElevationFt(double elevation);
|
||||
|
||||
// Create a local coordinate frame in the earth-centered frame of
|
||||
// reference. X points north, Z points down.
|
||||
// makeSimulationFrameRelative() only includes rotation.
|
||||
|
||||
osg::Matrix makeSimulationFrameRelative();
|
||||
osg::Matrix makeSimulationFrame();
|
||||
|
||||
// Create a Z-up local coordinate frame in the earth-centered frame
|
||||
// of reference. This is what scenery models, etc. expect.
|
||||
// makeZUpFrameRelative() only includes rotation.
|
||||
osg::Matrix makeZUpFrameRelative();
|
||||
osg::Matrix makeZUpFrame();
|
||||
private:
|
||||
/// This one is private since construction is not unique if you do
|
||||
/// not know the units of the arguments. Use the factory methods for
|
||||
@@ -107,20 +122,6 @@ SGGeod::SGGeod(double lon, double lat, double elevation) :
|
||||
{
|
||||
}
|
||||
|
||||
inline
|
||||
SGGeod::SGGeod(const SGVec3<double>& cart)
|
||||
{
|
||||
SGGeodesy::SGCartToGeod(cart, *this);
|
||||
}
|
||||
|
||||
inline
|
||||
SGGeod::SGGeod(const SGGeoc& geoc)
|
||||
{
|
||||
SGVec3<double> cart;
|
||||
SGGeodesy::SGGeocToCart(geoc, cart);
|
||||
SGGeodesy::SGCartToGeod(cart, *this);
|
||||
}
|
||||
|
||||
inline
|
||||
SGGeod
|
||||
SGGeod::fromRad(double lon, double lat)
|
||||
@@ -191,6 +192,26 @@ SGGeod::fromDegM(double lon, double lat, double elevation)
|
||||
#endif
|
||||
}
|
||||
|
||||
inline
|
||||
SGGeod
|
||||
SGGeod::fromCart(const SGVec3<double>& cart)
|
||||
{
|
||||
SGGeod geod;
|
||||
SGGeodesy::SGCartToGeod(cart, geod);
|
||||
return geod;
|
||||
}
|
||||
|
||||
inline
|
||||
SGGeod
|
||||
SGGeod::fromGeoc(const SGGeoc& geoc)
|
||||
{
|
||||
SGVec3<double> cart;
|
||||
SGGeodesy::SGGeocToCart(geoc, cart);
|
||||
SGGeod geod;
|
||||
SGGeodesy::SGCartToGeod(cart, geod);
|
||||
return geod;
|
||||
}
|
||||
|
||||
inline
|
||||
double
|
||||
SGGeod::getLongitudeRad(void) const
|
||||
|
||||
@@ -155,3 +155,346 @@ SGGeodesy::SGGeocToCart(const SGGeoc& geoc, SGVec3<double>& cart)
|
||||
double clon = cos(lon);
|
||||
cart = geoc.getRadiusM()*SGVec3<double>(clat*clon, clat*slon, slat);
|
||||
}
|
||||
|
||||
// Notes:
|
||||
//
|
||||
// The XYZ/cartesian coordinate system in use puts the X axis through
|
||||
// zero lat/lon (off west Africa), the Z axis through the north pole,
|
||||
// and the Y axis through 90 degrees longitude (in the Indian Ocean).
|
||||
//
|
||||
// All latitude and longitude values are in radians. Altitude is in
|
||||
// meters, with zero on the WGS84 ellipsoid.
|
||||
//
|
||||
// The code below makes use of the notion of "squashed" space. This
|
||||
// is a 2D cylindrical coordinate system where the radius from the Z
|
||||
// axis is multiplied by SQUASH; the earth in this space is a perfect
|
||||
// circle with a radius of POLRAD.
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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
|
||||
|
||||
static inline double M0( double e2 ) {
|
||||
//double e4 = e2*e2;
|
||||
return SGMiscd::pi()*0.5*(1.0 - e2*( 1.0/4.0 + e2*( 3.0/64.0 +
|
||||
e2*(5.0/256.0) )));
|
||||
}
|
||||
|
||||
|
||||
// given, lat1, lon1, az1 and distance (s), calculate lat2, lon2
|
||||
// and az2. Lat, lon, and azimuth are in degrees. distance in meters
|
||||
static int _geo_direct_wgs_84 ( double lat1, double lon1, double az1,
|
||||
double s, double *lat2, double *lon2,
|
||||
double *az2 )
|
||||
{
|
||||
double a = SGGeodesy::EQURAD, rf = SGGeodesy::iFLATTENING;
|
||||
double 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 = SGMiscd::deg2rad(lat1), lam1 = SGMiscd::deg2rad(lon1);
|
||||
double sinphi1 = sin(phi1), cosphi1 = cos(phi1);
|
||||
double azm1 = SGMiscd::deg2rad(az1);
|
||||
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( SGLimitsd::min() < fabs(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 = SGMiscd::rad2deg(atan2(rnumer,denom));
|
||||
|
||||
// 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 = SGMiscd::rad2deg(lam1+dlam);
|
||||
if (*lon2 > 180.0 ) *lon2 -= 360.0;
|
||||
if (*lon2 < -180.0 ) *lon2 += 360.0;
|
||||
|
||||
// AZIMUTH - FROM NORTH
|
||||
*az2 = SGMiscd::rad2deg(atan2(-sinaz,temp));
|
||||
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 );
|
||||
double zero = 0.0f;
|
||||
return _geo_direct_wgs_84( zero, lon1, paz, dM, lat2, lon2, az2 );
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
SGGeodesy::direct(const SGGeod& p1, double course1,
|
||||
double distance, SGGeod& p2, double& course2)
|
||||
{
|
||||
double lat2, lon2;
|
||||
int ret = _geo_direct_wgs_84(p1.getLatitudeDeg(), p1.getLongitudeDeg(),
|
||||
course1, distance, &lat2, &lon2, &course2);
|
||||
p2.setLatitudeDeg(lat2);
|
||||
p2.setLongitudeDeg(lon2);
|
||||
p2.setElevationM(0);
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
// given lat1, lon1, lat2, lon2, calculate starting and ending
|
||||
// az1, az2 and distance (s). Lat, lon, and azimuth are in degrees.
|
||||
// distance in meters
|
||||
static int _geo_inverse_wgs_84( double lat1, double lon1, double lat2,
|
||||
double lon2, double *az1, double *az2,
|
||||
double *s )
|
||||
{
|
||||
double a = SGGeodesy::EQURAD, rf = SGGeodesy::iFLATTENING;
|
||||
int iter=0;
|
||||
double 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 = SGMiscd::deg2rad(lat1), lam1 = SGMiscd::deg2rad(lon1);
|
||||
double sinphi1 = sin(phi1), cosphi1 = cos(phi1);
|
||||
double phi2 = SGMiscd::deg2rad(lat2), lam2 = SGMiscd::deg2rad(lon2);
|
||||
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( 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
|
||||
double _lon1 = lon1 + 180.0f;
|
||||
int k = _geo_inverse_wgs_84( lat1, lon1, lat1, _lon1,
|
||||
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( lat1,lon1, lat1,lon2, az1,az2, &s1 );
|
||||
_geo_inverse_wgs_84( 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) > SGMiscd::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 = SGMiscd::rad2deg(atan2(rnumer,denom));
|
||||
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 = SGMiscd::rad2deg(atan2(rnumer,denom));
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
SGGeodesy::inverse(const SGGeod& p1, const SGGeod& p2, double& course1,
|
||||
double& course2, double& distance)
|
||||
{
|
||||
int ret = _geo_inverse_wgs_84(p1.getLatitudeDeg(), p1.getLongitudeDeg(),
|
||||
p2.getLatitudeDeg(), p2.getLongitudeDeg(),
|
||||
&course1, &course2, &distance);
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
/// Geocentric routines
|
||||
|
||||
void
|
||||
SGGeodesy::advanceRadM(const SGGeoc& geoc, double course, double distance,
|
||||
SGGeoc& result)
|
||||
{
|
||||
result.setRadiusM(geoc.getRadiusM());
|
||||
|
||||
// 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
|
||||
|
||||
distance *= SG_METER_TO_NM * SG_NM_TO_RAD;
|
||||
|
||||
double sinDistance = sin(distance);
|
||||
double cosDistance = cos(distance);
|
||||
|
||||
double sinLat = sin(geoc.getLatitudeRad()) * cosDistance +
|
||||
cos(geoc.getLatitudeRad()) * sinDistance * cos(course);
|
||||
sinLat = SGMiscd::clip(sinLat, -1, 1);
|
||||
result.setLatitudeRad(asin(sinLat));
|
||||
double cosLat = cos(result.getLatitudeRad());
|
||||
|
||||
|
||||
if (cosLat <= SGLimitsd::min()) {
|
||||
// endpoint a pole
|
||||
result.setLongitudeRad(geoc.getLongitudeRad());
|
||||
} else {
|
||||
double tmp = SGMiscd::clip(sin(course) * sinDistance / cosLat, -1, 1);
|
||||
double lon = SGMiscd::normalizeAngle(geoc.getLongitudeRad() - asin( tmp ));
|
||||
result.setLongitudeRad(lon);
|
||||
}
|
||||
}
|
||||
|
||||
double
|
||||
SGGeodesy::courseRad(const SGGeoc& from, const SGGeoc& to)
|
||||
{
|
||||
double diffLon = to.getLongitudeRad() - from.getLongitudeRad();
|
||||
|
||||
double sinLatFrom = sin(from.getLatitudeRad());
|
||||
double cosLatFrom = cos(from.getLatitudeRad());
|
||||
|
||||
double sinLatTo = sin(to.getLatitudeRad());
|
||||
double cosLatTo = cos(to.getLatitudeRad());
|
||||
|
||||
double x = cosLatTo*sin(diffLon);
|
||||
double y = cosLatFrom*sinLatTo - sinLatFrom*cosLatTo*cos(diffLon);
|
||||
|
||||
// guard atan2 returning NaN's
|
||||
if (fabs(x) <= SGLimitsd::min() && fabs(y) <= SGLimitsd::min())
|
||||
return 0;
|
||||
|
||||
double c = atan2(x, y);
|
||||
if (c >= 0)
|
||||
return SGMiscd::twopi() - c;
|
||||
else
|
||||
return -c;
|
||||
}
|
||||
|
||||
double
|
||||
SGGeodesy::distanceM(const SGGeoc& from, const SGGeoc& to)
|
||||
{
|
||||
// d = 2*asin(sqrt((sin((lat1-lat2)/2))^2 +
|
||||
// cos(lat1)*cos(lat2)*(sin((lon1-lon2)/2))^2))
|
||||
double cosLatFrom = cos(from.getLatitudeRad());
|
||||
double cosLatTo = cos(to.getLatitudeRad());
|
||||
double tmp1 = sin(0.5*(from.getLatitudeRad() - to.getLatitudeRad()));
|
||||
double tmp2 = sin(0.5*(from.getLongitudeRad() - to.getLongitudeRad()));
|
||||
double square = tmp1*tmp1 + cosLatFrom*cosLatTo*tmp2*tmp2;
|
||||
double s = SGMiscd::min(sqrt(SGMiscd::max(square, 0)), 1);
|
||||
return 2 * asin(s) * SG_RAD_TO_NM * SG_NM_TO_METER;
|
||||
}
|
||||
|
||||
@@ -18,12 +18,6 @@
|
||||
#ifndef SGGeodesy_H
|
||||
#define SGGeodesy_H
|
||||
|
||||
class SGGeoc;
|
||||
class SGGeod;
|
||||
|
||||
template<typename T>
|
||||
class SGVec3;
|
||||
|
||||
class SGGeodesy {
|
||||
public:
|
||||
// Hard numbers from the WGS84 standard.
|
||||
@@ -51,6 +45,19 @@ public:
|
||||
/// Takes a geocentric coordinate data and returns the cartesian
|
||||
/// coordinates.
|
||||
static void SGGeocToCart(const SGGeoc& geoc, SGVec3<double>& cart);
|
||||
|
||||
// Geodetic course/distance computation
|
||||
static bool direct(const SGGeod& p1, double course1,
|
||||
double distance, SGGeod& p2, double& course2);
|
||||
|
||||
static bool inverse(const SGGeod& p1, const SGGeod& p2, double& course1,
|
||||
double& course2, double& distance);
|
||||
|
||||
// Geocentric course/distance computation
|
||||
static void advanceRadM(const SGGeoc& geoc, double course, double distance,
|
||||
SGGeoc& result);
|
||||
static double courseRad(const SGGeoc& from, const SGGeoc& to);
|
||||
static double distanceM(const SGGeoc& from, const SGGeoc& to);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
38
simgear/math/SGGeometry.hxx
Normal file
38
simgear/math/SGGeometry.hxx
Normal file
@@ -0,0 +1,38 @@
|
||||
// Copyright (C) 2006 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
|
||||
#ifndef SGGeometry_HXX
|
||||
#define SGGeometry_HXX
|
||||
|
||||
// Required ...
|
||||
#include "SGMath.hxx"
|
||||
|
||||
// Make sure all is defined
|
||||
#include "SGGeometryFwd.hxx"
|
||||
|
||||
// Geometric primitives we know about
|
||||
#include "SGBox.hxx"
|
||||
#include "SGSphere.hxx"
|
||||
#include "SGRay.hxx"
|
||||
#include "SGLineSegment.hxx"
|
||||
#include "SGPlane.hxx"
|
||||
#include "SGTriangle.hxx"
|
||||
|
||||
// Intersection tests
|
||||
#include "SGIntersect.hxx"
|
||||
|
||||
#endif
|
||||
51
simgear/math/SGGeometryFwd.hxx
Normal file
51
simgear/math/SGGeometryFwd.hxx
Normal file
@@ -0,0 +1,51 @@
|
||||
// Copyright (C) 2006 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
|
||||
#ifndef SGGeometryFwd_HXX
|
||||
#define SGGeometryFwd_HXX
|
||||
|
||||
template<typename T>
|
||||
class SGBox;
|
||||
typedef SGBox<float> SGBoxf;
|
||||
typedef SGBox<double> SGBoxd;
|
||||
|
||||
template<typename T>
|
||||
class SGSphere;
|
||||
typedef SGSphere<float> SGSpheref;
|
||||
typedef SGSphere<double> SGSphered;
|
||||
|
||||
template<typename T>
|
||||
class SGRay;
|
||||
typedef SGRay<float> SGRayf;
|
||||
typedef SGRay<double> SGRayd;
|
||||
|
||||
template<typename T>
|
||||
class SGLineSegment;
|
||||
typedef SGLineSegment<float> SGLineSegmentf;
|
||||
typedef SGLineSegment<double> SGLineSegmentd;
|
||||
|
||||
template<typename T>
|
||||
class SGPlane;
|
||||
typedef SGPlane<float> SGPlanef;
|
||||
typedef SGPlane<double> SGPlaned;
|
||||
|
||||
template<typename T>
|
||||
class SGTriangle;
|
||||
typedef SGTriangle<float> SGTrianglef;
|
||||
typedef SGTriangle<double> SGTriangled;
|
||||
|
||||
#endif
|
||||
442
simgear/math/SGGeometryTest.cxx
Normal file
442
simgear/math/SGGeometryTest.cxx
Normal file
@@ -0,0 +1,442 @@
|
||||
// Copyright (C) 2006 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
|
||||
#include "SGGeometry.hxx"
|
||||
#include "sg_random.h"
|
||||
|
||||
template<typename T>
|
||||
SGVec3<T> rndVec3(void)
|
||||
{
|
||||
return SGVec3<T>(sg_random(), sg_random(), sg_random());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool
|
||||
TriangleLineIntersectionTest(void)
|
||||
{
|
||||
unsigned nTests = 100000;
|
||||
unsigned failedCount = 0;
|
||||
for (unsigned i = 0; i < nTests; ++i) {
|
||||
SGVec3<T> v0 = rndVec3<T>();
|
||||
SGVec3<T> v1 = rndVec3<T>();
|
||||
SGVec3<T> v2 = rndVec3<T>();
|
||||
|
||||
SGTriangle<T> tri(v0, v1, v2);
|
||||
|
||||
// generate random coeficients
|
||||
T u = 4*sg_random() - 2;
|
||||
T v = 4*sg_random() - 2;
|
||||
T t = 4*sg_random() - 2;
|
||||
|
||||
SGVec3<T> isectpt = v0 + u*(v1 - v0) + v*(v2 - v0);
|
||||
|
||||
SGLineSegment<T> lineSegment;
|
||||
SGVec3<T> dir = rndVec3<T>();
|
||||
|
||||
SGVec3<T> isectres;
|
||||
lineSegment.set(isectpt - t*dir, isectpt + (1 - t)*dir);
|
||||
|
||||
if (intersects(isectres, tri, lineSegment)) {
|
||||
if (0 <= u && 0 <= v && u+v <= 1 && 0 <= t && t <= 1) {
|
||||
if (!equivalent(isectres, isectpt)) {
|
||||
std::cout << "Failed line segment intersection test #" << i
|
||||
<< ": not equivalent!\nu = "
|
||||
<< u << ", v = " << v << ", t = " << t
|
||||
<< "\n" << tri << "\n" << lineSegment << std::endl;
|
||||
++failedCount;
|
||||
}
|
||||
} else {
|
||||
std::cout << "Failed line segment intersection test #" << i
|
||||
<< ": false positive!\nu = "
|
||||
<< u << ", v = " << v << ", t = " << t
|
||||
<< "\n" << tri << "\n" << lineSegment << std::endl;
|
||||
++failedCount;
|
||||
}
|
||||
} else {
|
||||
if (0 <= u && 0 <= v && u+v <= 1 && 0 <= t && t <= 1) {
|
||||
std::cout << "Failed line segment intersection test #" << i
|
||||
<< ": false negative!\nu = "
|
||||
<< u << ", v = " << v << ", t = " << t
|
||||
<< "\n" << tri << "\n" << lineSegment << std::endl;
|
||||
++failedCount;
|
||||
}
|
||||
}
|
||||
|
||||
SGRay<T> ray;
|
||||
ray.set(isectpt - t*dir, dir);
|
||||
if (intersects(isectres, tri, ray)) {
|
||||
if (0 <= u && 0 <= v && u+v <= 1 && 0 <= t) {
|
||||
if (!equivalent(isectres, isectpt)) {
|
||||
std::cout << "Failed ray intersection test #" << i
|
||||
<< ": not equivalent!\nu = "
|
||||
<< u << ", v = " << v << ", t = " << t
|
||||
<< "\n" << tri << "\n" << ray << std::endl;
|
||||
++failedCount;
|
||||
}
|
||||
} else {
|
||||
std::cout << "Failed ray intersection test #" << i
|
||||
<< ": false positive!\nu = "
|
||||
<< u << ", v = " << v << ", t = " << t
|
||||
<< "\n" << tri << "\n" << ray << std::endl;
|
||||
++failedCount;
|
||||
}
|
||||
} else {
|
||||
if (0 <= u && 0 <= v && u+v <= 1 && 0 <= t) {
|
||||
std::cout << "Failed ray intersection test #" << i
|
||||
<< ": false negative !\nu = "
|
||||
<< u << ", v = " << v << ", t = " << t
|
||||
<< "\n" << tri << "\n" << ray << std::endl;
|
||||
++failedCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nTests < 100*failedCount) {
|
||||
std::cout << "Failed ray intersection tests: " << failedCount
|
||||
<< " tests out of " << nTests
|
||||
<< " went wrong. Abort!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Some crude handmade test
|
||||
SGVec3<T> v0 = SGVec3<T>(0, 0, 0);
|
||||
SGVec3<T> v1 = SGVec3<T>(1, 0, 0);
|
||||
SGVec3<T> v2 = SGVec3<T>(0, 1, 0);
|
||||
|
||||
SGTriangle<T> tri(v0, v1, v2);
|
||||
|
||||
SGRay<T> ray;
|
||||
ray.set(SGVec3<T>(0, 0, 1), SGVec3<T>(0.1, 0.1, -1));
|
||||
if (!intersects(tri, ray)) {
|
||||
std::cout << "Failed test #1!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
ray.set(SGVec3<T>(0, 0, 1), SGVec3<T>(0, 0, -1));
|
||||
if (!intersects(tri, ray)) {
|
||||
std::cout << "Failed test #2!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
SGLineSegment<T> lineSegment;
|
||||
lineSegment.set(SGVec3<T>(0, 0, 1), SGVec3<T>(0.1, 0.1, -1));
|
||||
if (!intersects(tri, lineSegment)) {
|
||||
std::cout << "Failed test #3!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
lineSegment.set(SGVec3<T>(0, 0, 1), SGVec3<T>(0, 0, -1));
|
||||
if (!intersects(tri, lineSegment)) {
|
||||
std::cout << "Failed test #4!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
lineSegment.set(SGVec3<T>(0, 0, 1), SGVec3<T>(0, 1, -1));
|
||||
if (!intersects(tri, lineSegment)) {
|
||||
std::cout << "Failed test #5!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
lineSegment.set(SGVec3<T>(0, 0, 1), SGVec3<T>(1, 0, -1));
|
||||
if (!intersects(tri, lineSegment)) {
|
||||
std::cout << "Failed test #6!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
lineSegment.set(SGVec3<T>(0, 0, 1), SGVec3<T>(1, 1, -1));
|
||||
if (!intersects(tri, lineSegment)) {
|
||||
std::cout << "Failed test #7!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// is exactly in the plane
|
||||
// FIXME: cannot detect that yet ??
|
||||
// lineSegment.set(SGVec3<T>(0, 0, 0), SGVec3<T>(1, 0, 0));
|
||||
// if (!intersects(tri, lineSegment)) {
|
||||
// std::cout << "Failed test #8!" << std::endl;
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// is exactly in the plane
|
||||
// FIXME: cannot detect that yet ??
|
||||
// lineSegment.set(SGVec3<T>(-1, 0, 0), SGVec3<T>(1, 0, 0));
|
||||
// if (!intersects(tri, lineSegment)) {
|
||||
// std::cout << "Failed test #9!" << std::endl;
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// is exactly paralell to the plane
|
||||
// FIXME: cannot detect that yet ??
|
||||
// lineSegment.set(SGVec3<T>(-1, 1, 0), SGVec3<T>(1, 1, 0));
|
||||
// if (intersects(tri, lineSegment)) {
|
||||
// std::cout << "Failed test #10!" << std::endl;
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// should fail since the line segment poins slightly beyond the triangle
|
||||
lineSegment.set(SGVec3<T>(0, 0, 1), SGVec3<T>(1, 1, -0.9));
|
||||
if (intersects(tri, lineSegment)) {
|
||||
std::cout << "Failed test #11!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
lineSegment.set(SGVec3<T>(0, 0, 1), SGVec3<T>(0, -0.1, -1));
|
||||
if (intersects(tri, lineSegment)) {
|
||||
std::cout << "Failed test #12!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
lineSegment.set(SGVec3<T>(0, 0, 1), SGVec3<T>(-0.1, -0.1, -1));
|
||||
if (intersects(tri, lineSegment)) {
|
||||
std::cout << "Failed test #13!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
lineSegment.set(SGVec3<T>(0, 0, 1), SGVec3<T>(-0.1, 0, -1));
|
||||
if (intersects(tri, lineSegment)) {
|
||||
std::cout << "Failed test #14!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool
|
||||
SphereLineIntersectionTest(void)
|
||||
{
|
||||
unsigned nTests = 100000;
|
||||
unsigned failedCount = 0;
|
||||
for (unsigned i = 0; i < nTests; ++i) {
|
||||
SGVec3<T> center = rndVec3<T>();
|
||||
T radius = 2*sg_random();
|
||||
SGSphere<T> sphere(center, radius);
|
||||
|
||||
SGVec3<T> offset = normalize(rndVec3<T>());
|
||||
T t = 4*sg_random();
|
||||
|
||||
// This one is the point we use to judge if the test should fail or not
|
||||
SGVec3<T> base = center + t*offset;
|
||||
|
||||
SGVec3<T> per = perpendicular(offset);
|
||||
SGVec3<T> start = base + 4*sg_random()*per;
|
||||
SGVec3<T> end = base - 4*sg_random()*per;
|
||||
|
||||
SGLineSegment<T> lineSegment;
|
||||
lineSegment.set(start, end);
|
||||
if (intersects(sphere, lineSegment)) {
|
||||
if (radius < t) {
|
||||
std::cout << "Failed sphere line intersection test #" << i
|
||||
<< ": false positive!\nt = " << t << "\n"
|
||||
<< sphere << "\n" << lineSegment << std::endl;
|
||||
++failedCount;
|
||||
}
|
||||
} else {
|
||||
if (t <= radius) {
|
||||
std::cout << "Failed sphere line intersection test #" << i
|
||||
<< ": false negative!\nt = " << t << "\n"
|
||||
<< sphere << "\n" << lineSegment << std::endl;
|
||||
++failedCount;
|
||||
}
|
||||
}
|
||||
|
||||
SGRay<T> ray;
|
||||
ray.set(start, end - start);
|
||||
if (intersects(sphere, ray)) {
|
||||
if (radius < t) {
|
||||
std::cout << "Failed sphere line intersection test #" << i
|
||||
<< ": false positive!\nt = " << t << "\n"
|
||||
<< sphere << "\n" << ray << std::endl;
|
||||
++failedCount;
|
||||
}
|
||||
} else {
|
||||
if (t <= radius) {
|
||||
std::cout << "Failed sphere line intersection test #" << i
|
||||
<< ": false negative!\nt = " << t << "\n"
|
||||
<< sphere << "\n" << ray << std::endl;
|
||||
++failedCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nTests < 100*failedCount) {
|
||||
std::cout << "Failed sphere line intersection tests: " << failedCount
|
||||
<< " tests out of " << nTests
|
||||
<< " went wrong. Abort!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
failedCount = 0;
|
||||
for (unsigned i = 0; i < nTests; ++i) {
|
||||
SGVec3<T> center = rndVec3<T>();
|
||||
T radius = 2*sg_random();
|
||||
SGSphere<T> sphere(center, radius);
|
||||
|
||||
SGVec3<T> offset = normalize(rndVec3<T>());
|
||||
T t = 4*sg_random();
|
||||
|
||||
// This one is the point we use to judge if the test should fail or not
|
||||
SGVec3<T> base = center + t*offset;
|
||||
|
||||
SGVec3<T> start = base;
|
||||
SGVec3<T> end = base + 2*sg_random()*offset;
|
||||
|
||||
SGLineSegment<T> lineSegment;
|
||||
lineSegment.set(start, end);
|
||||
if (intersects(sphere, lineSegment)) {
|
||||
if (radius < t) {
|
||||
std::cout << "Failed sphere line intersection test #" << i
|
||||
<< ": false positive!\nt = " << t << "\n"
|
||||
<< sphere << "\n" << lineSegment << std::endl;
|
||||
++failedCount;
|
||||
}
|
||||
} else {
|
||||
if (t <= radius) {
|
||||
std::cout << "Failed sphere line intersection test #" << i
|
||||
<< ": false negative!\nt = " << t << "\n"
|
||||
<< sphere << "\n" << lineSegment << std::endl;
|
||||
++failedCount;
|
||||
}
|
||||
}
|
||||
|
||||
SGRay<T> ray;
|
||||
ray.set(start, end - start);
|
||||
if (intersects(sphere, ray)) {
|
||||
if (radius < t) {
|
||||
std::cout << "Failed sphere line intersection test #" << i
|
||||
<< ": false positive!\nt = " << t << "\n"
|
||||
<< sphere << "\n" << ray << std::endl;
|
||||
++failedCount;
|
||||
}
|
||||
} else {
|
||||
if (t <= radius) {
|
||||
std::cout << "Failed sphere line intersection test #" << i
|
||||
<< ": false negative!\nt = " << t << "\n"
|
||||
<< sphere << "\n" << ray << std::endl;
|
||||
++failedCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nTests < 100*failedCount) {
|
||||
std::cout << "Failed sphere line intersection tests: " << failedCount
|
||||
<< " tests out of " << nTests
|
||||
<< " went wrong. Abort!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool
|
||||
BoxLineIntersectionTest(void)
|
||||
{
|
||||
// ok, bad test case coverage, but better than nothing ...
|
||||
|
||||
unsigned nTests = 100000;
|
||||
unsigned failedCount = 0;
|
||||
for (unsigned i = 0; i < nTests; ++i) {
|
||||
SGBox<T> box;
|
||||
box.expandBy(rndVec3<T>());
|
||||
box.expandBy(rndVec3<T>());
|
||||
|
||||
SGVec3<T> center = box.getCenter();
|
||||
|
||||
// This one is the point we use to judge if the test should fail or not
|
||||
SGVec3<T> base = rndVec3<T>();
|
||||
SGVec3<T> dir = base - center;
|
||||
|
||||
SGLineSegment<T> lineSegment;
|
||||
lineSegment.set(base, base + dir);
|
||||
if (intersects(box, lineSegment)) {
|
||||
if (!intersects(box, base)) {
|
||||
std::cout << "Failed box line intersection test #" << i
|
||||
<< ": false positive!\n"
|
||||
<< box << "\n" << lineSegment << std::endl;
|
||||
++failedCount;
|
||||
}
|
||||
} else {
|
||||
if (intersects(box, base)) {
|
||||
std::cout << "Failed box line intersection test #" << i
|
||||
<< ": false negative!\n"
|
||||
<< box << "\n" << lineSegment << std::endl;
|
||||
++failedCount;
|
||||
}
|
||||
}
|
||||
|
||||
SGRay<T> ray;
|
||||
ray.set(base, dir);
|
||||
if (intersects(box, ray)) {
|
||||
if (!intersects(box, base)) {
|
||||
std::cout << "Failed box line intersection test #" << i
|
||||
<< ": false positive!\n"
|
||||
<< box << "\n" << ray << std::endl;
|
||||
++failedCount;
|
||||
}
|
||||
} else {
|
||||
if (intersects(box, base)) {
|
||||
std::cout << "Failed box line intersection test #" << i
|
||||
<< ": false negative!\n"
|
||||
<< box << "\n" << ray << std::endl;
|
||||
++failedCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nTests < 100*failedCount) {
|
||||
std::cout << "Failed box line intersection tests: " << failedCount
|
||||
<< " tests out of " << nTests
|
||||
<< " went wrong. Abort!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
std::cout << "Testing Geometry intersection routines.\n"
|
||||
<< "Some of these tests can fail due to roundoff problems...\n"
|
||||
<< "Dont worry if only a few of them fail..." << std::endl;
|
||||
|
||||
if (!TriangleLineIntersectionTest<float>())
|
||||
return EXIT_FAILURE;
|
||||
if (!TriangleLineIntersectionTest<double>())
|
||||
return EXIT_FAILURE;
|
||||
|
||||
if (!SphereLineIntersectionTest<float>())
|
||||
return EXIT_FAILURE;
|
||||
if (!SphereLineIntersectionTest<double>())
|
||||
return EXIT_FAILURE;
|
||||
|
||||
if (!BoxLineIntersectionTest<float>())
|
||||
return EXIT_FAILURE;
|
||||
if (!BoxLineIntersectionTest<double>())
|
||||
return EXIT_FAILURE;
|
||||
|
||||
std::cout << "Successfully passed all tests!" << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
627
simgear/math/SGIntersect.hxx
Normal file
627
simgear/math/SGIntersect.hxx
Normal file
@@ -0,0 +1,627 @@
|
||||
// Copyright (C) 2006 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
|
||||
#ifndef SGIntersect_HXX
|
||||
#define SGIntersect_HXX
|
||||
|
||||
template<typename T>
|
||||
inline bool
|
||||
intersects(const SGBox<T>& box, const SGSphere<T>& sphere)
|
||||
{
|
||||
if (sphere.empty())
|
||||
return false;
|
||||
// Is more or less trivially included in the next tests
|
||||
// if (box.empty())
|
||||
// return false;
|
||||
|
||||
if (sphere.getCenter().x() < box.getMin().x() - sphere.getRadius())
|
||||
return false;
|
||||
if (sphere.getCenter().y() < box.getMin().y() - sphere.getRadius())
|
||||
return false;
|
||||
if (sphere.getCenter().z() < box.getMin().z() - sphere.getRadius())
|
||||
return false;
|
||||
|
||||
if (box.getMax().x() + sphere.getRadius() < sphere.getCenter().x())
|
||||
return false;
|
||||
if (box.getMax().y() + sphere.getRadius() < sphere.getCenter().y())
|
||||
return false;
|
||||
if (box.getMax().z() + sphere.getRadius() < sphere.getCenter().z())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
// make it symmetric
|
||||
template<typename T>
|
||||
inline bool
|
||||
intersects(const SGSphere<T>& sphere, const SGBox<T>& box)
|
||||
{ return intersects(box, sphere); }
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline bool
|
||||
intersects(const SGVec3<T>& v, const SGBox<T>& box)
|
||||
{
|
||||
if (v[0] < box.getMin()[0])
|
||||
return false;
|
||||
if (box.getMax()[0] < v[0])
|
||||
return false;
|
||||
if (v[1] < box.getMin()[1])
|
||||
return false;
|
||||
if (box.getMax()[1] < v[1])
|
||||
return false;
|
||||
if (v[2] < box.getMin()[2])
|
||||
return false;
|
||||
if (box.getMax()[2] < v[2])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
template<typename T>
|
||||
inline bool
|
||||
intersects(const SGBox<T>& box, const SGVec3<T>& v)
|
||||
{ return intersects(v, box); }
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline bool
|
||||
intersects(const SGRay<T>& ray, const SGPlane<T>& plane)
|
||||
{
|
||||
// We compute the intersection point
|
||||
// x = origin + \alpha*direction
|
||||
// from the ray origin and non nomalized direction.
|
||||
// For 0 <= \alpha the ray intersects the infinite plane.
|
||||
// The intersection point x can also be written
|
||||
// x = n*dist + y
|
||||
// where n is the planes normal, dist is the distance of the plane from
|
||||
// the origin in normal direction and y is ana aproriate vector
|
||||
// perpendicular to n.
|
||||
// Equate the x values and take the scalar product with the plane normal n.
|
||||
// dot(n, origin) + \alpha*dot(n, direction) = dist
|
||||
// We can now compute alpha from the above equation.
|
||||
// \alpha = (dist - dot(n, origin))/dot(n, direction)
|
||||
|
||||
// The negative numerator for the \alpha expression
|
||||
T num = plane.getPositiveDist();
|
||||
num -= dot(plane.getNormal(), ray.getOrigin());
|
||||
|
||||
// If the numerator is zero, we have the rays origin included in the plane
|
||||
if (fabs(num) <= SGLimits<T>::min())
|
||||
return true;
|
||||
|
||||
// The denominator for the \alpha expression
|
||||
T den = dot(plane.getNormal(), ray.getDirection());
|
||||
|
||||
// If we get here, we already know that the rays origin is not included
|
||||
// in the plane. Thus if we have a zero denominator we have
|
||||
// a ray paralell to the plane. That is no intersection.
|
||||
if (fabs(den) <= SGLimits<T>::min())
|
||||
return false;
|
||||
|
||||
// We would now compute \alpha = num/den and compare with 0 and 1.
|
||||
// But to avoid that expensive division, check equation multiplied by
|
||||
// the denominator.
|
||||
T alphaDen = copysign(1, den)*num;
|
||||
if (alphaDen < 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
// make it symmetric
|
||||
template<typename T>
|
||||
inline bool
|
||||
intersects(const SGPlane<T>& plane, const SGRay<T>& ray)
|
||||
{ return intersects(ray, plane); }
|
||||
|
||||
template<typename T>
|
||||
inline bool
|
||||
intersects(SGVec3<T>& dst, const SGRay<T>& ray, const SGPlane<T>& plane)
|
||||
{
|
||||
// We compute the intersection point
|
||||
// x = origin + \alpha*direction
|
||||
// from the ray origin and non nomalized direction.
|
||||
// For 0 <= \alpha the ray intersects the infinite plane.
|
||||
// The intersection point x can also be written
|
||||
// x = n*dist + y
|
||||
// where n is the planes normal, dist is the distance of the plane from
|
||||
// the origin in normal direction and y is ana aproriate vector
|
||||
// perpendicular to n.
|
||||
// Equate the x values and take the scalar product with the plane normal n.
|
||||
// dot(n, origin) + \alpha*dot(n, direction) = dist
|
||||
// We can now compute alpha from the above equation.
|
||||
// \alpha = (dist - dot(n, origin))/dot(n, direction)
|
||||
|
||||
// The negative numerator for the \alpha expression
|
||||
T num = plane.getPositiveDist();
|
||||
num -= dot(plane.getNormal(), ray.getOrigin());
|
||||
|
||||
// If the numerator is zero, we have the rays origin included in the plane
|
||||
if (fabs(num) <= SGLimits<T>::min()) {
|
||||
dst = ray.getOrigin();
|
||||
return true;
|
||||
}
|
||||
|
||||
// The denominator for the \alpha expression
|
||||
T den = dot(plane.getNormal(), ray.getDirection());
|
||||
|
||||
// If we get here, we already know that the rays origin is not included
|
||||
// in the plane. Thus if we have a zero denominator we have
|
||||
// a ray paralell to the plane. That is no intersection.
|
||||
if (fabs(den) <= SGLimits<T>::min())
|
||||
return false;
|
||||
|
||||
// We would now compute \alpha = num/den and compare with 0 and 1.
|
||||
// But to avoid that expensive division, check equation multiplied by
|
||||
// the denominator.
|
||||
T alpha = num/den;
|
||||
if (alpha < 0)
|
||||
return false;
|
||||
|
||||
dst = ray.getOrigin() + alpha*ray.getDirection();
|
||||
return true;
|
||||
}
|
||||
// make it symmetric
|
||||
template<typename T>
|
||||
inline bool
|
||||
intersects(SGVec3<T>& dst, const SGPlane<T>& plane, const SGRay<T>& ray)
|
||||
{ return intersects(dst, ray, plane); }
|
||||
|
||||
template<typename T>
|
||||
inline bool
|
||||
intersects(const SGLineSegment<T>& lineSegment, const SGPlane<T>& plane)
|
||||
{
|
||||
// We compute the intersection point
|
||||
// x = origin + \alpha*direction
|
||||
// from the line segments origin and non nomalized direction.
|
||||
// For 0 <= \alpha <= 1 the line segment intersects the infinite plane.
|
||||
// The intersection point x can also be written
|
||||
// x = n*dist + y
|
||||
// where n is the planes normal, dist is the distance of the plane from
|
||||
// the origin in normal direction and y is ana aproriate vector
|
||||
// perpendicular to n.
|
||||
// Equate the x values and take the scalar product with the plane normal n.
|
||||
// dot(n, origin) + \alpha*dot(n, direction) = dist
|
||||
// We can now compute alpha from the above equation.
|
||||
// \alpha = (dist - dot(n, origin))/dot(n, direction)
|
||||
|
||||
// The negative numerator for the \alpha expression
|
||||
T num = plane.getPositiveDist();
|
||||
num -= dot(plane.getNormal(), lineSegment.getOrigin());
|
||||
|
||||
// If the numerator is zero, we have the lines origin included in the plane
|
||||
if (fabs(num) <= SGLimits<T>::min())
|
||||
return true;
|
||||
|
||||
// The denominator for the \alpha expression
|
||||
T den = dot(plane.getNormal(), lineSegment.getDirection());
|
||||
|
||||
// If we get here, we already know that the lines origin is not included
|
||||
// in the plane. Thus if we have a zero denominator we have
|
||||
// a line paralell to the plane. That is no intersection.
|
||||
if (fabs(den) <= SGLimits<T>::min())
|
||||
return false;
|
||||
|
||||
// We would now compute \alpha = num/den and compare with 0 and 1.
|
||||
// But to avoid that expensive division, compare equations
|
||||
// multiplied by |den|. Note that copysign is usually a compiler intrinsic
|
||||
// that expands in assembler code that not even stalls the cpus pipes.
|
||||
T alphaDen = copysign(1, den)*num;
|
||||
if (alphaDen < 0)
|
||||
return false;
|
||||
if (den < alphaDen)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
// make it symmetric
|
||||
template<typename T>
|
||||
inline bool
|
||||
intersects(const SGPlane<T>& plane, const SGLineSegment<T>& lineSegment)
|
||||
{ return intersects(lineSegment, plane); }
|
||||
|
||||
template<typename T>
|
||||
inline bool
|
||||
intersects(SGVec3<T>& dst, const SGLineSegment<T>& lineSegment, const SGPlane<T>& plane)
|
||||
{
|
||||
// We compute the intersection point
|
||||
// x = origin + \alpha*direction
|
||||
// from the line segments origin and non nomalized direction.
|
||||
// For 0 <= \alpha <= 1 the line segment intersects the infinite plane.
|
||||
// The intersection point x can also be written
|
||||
// x = n*dist + y
|
||||
// where n is the planes normal, dist is the distance of the plane from
|
||||
// the origin in normal direction and y is an aproriate vector
|
||||
// perpendicular to n.
|
||||
// Equate the x values and take the scalar product with the plane normal n.
|
||||
// dot(n, origin) + \alpha*dot(n, direction) = dist
|
||||
// We can now compute alpha from the above equation.
|
||||
// \alpha = (dist - dot(n, origin))/dot(n, direction)
|
||||
|
||||
// The negative numerator for the \alpha expression
|
||||
T num = plane.getPositiveDist();
|
||||
num -= dot(plane.getNormal(), lineSegment.getOrigin());
|
||||
|
||||
// If the numerator is zero, we have the lines origin included in the plane
|
||||
if (fabs(num) <= SGLimits<T>::min()) {
|
||||
dst = lineSegment.getOrigin();
|
||||
return true;
|
||||
}
|
||||
|
||||
// The denominator for the \alpha expression
|
||||
T den = dot(plane.getNormal(), lineSegment.getDirection());
|
||||
|
||||
// If we get here, we already know that the lines origin is not included
|
||||
// in the plane. Thus if we have a zero denominator we have
|
||||
// a line paralell to the plane. That is: no intersection.
|
||||
if (fabs(den) <= SGLimits<T>::min())
|
||||
return false;
|
||||
|
||||
// We would now compute \alpha = num/den and compare with 0 and 1.
|
||||
// But to avoid that expensive division, check equation multiplied by
|
||||
// the denominator. FIXME: shall we do so? or compute like that?
|
||||
T alpha = num/den;
|
||||
if (alpha < 0)
|
||||
return false;
|
||||
if (1 < alpha)
|
||||
return false;
|
||||
|
||||
dst = lineSegment.getOrigin() + alpha*lineSegment.getDirection();
|
||||
return true;
|
||||
}
|
||||
// make it symmetric
|
||||
template<typename T>
|
||||
inline bool
|
||||
intersects(SGVec3<T>& dst, const SGPlane<T>& plane, const SGLineSegment<T>& lineSegment)
|
||||
{ return intersects(dst, lineSegment, plane); }
|
||||
|
||||
|
||||
// Distance of a line segment to a point
|
||||
template<typename T>
|
||||
inline T
|
||||
distSqr(const SGLineSegment<T>& lineSeg, const SGVec3<T>& p)
|
||||
{
|
||||
SGVec3<T> ps = p - lineSeg.getStart();
|
||||
|
||||
T psdotdir = dot(ps, lineSeg.getDirection());
|
||||
if (psdotdir <= 0)
|
||||
return dot(ps, ps);
|
||||
|
||||
SGVec3<T> pe = p - lineSeg.getEnd();
|
||||
if (0 <= dot(pe, lineSeg.getDirection()))
|
||||
return dot(pe, pe);
|
||||
|
||||
return dot(ps, ps) - psdotdir*psdotdir/dot(lineSeg.getDirection(), lineSeg.getDirection());
|
||||
}
|
||||
// make it symmetric
|
||||
template<typename T>
|
||||
inline T
|
||||
distSqr(const SGVec3<T>& p, const SGLineSegment<T>& lineSeg)
|
||||
{ return distSqr(lineSeg, p); }
|
||||
// with sqrt
|
||||
template<typename T>
|
||||
inline T
|
||||
dist(const SGVec3<T>& p, const SGLineSegment<T>& lineSeg)
|
||||
{ return sqrt(distSqr(lineSeg, p)); }
|
||||
template<typename T>
|
||||
inline T
|
||||
dist(const SGLineSegment<T>& lineSeg, const SGVec3<T>& p)
|
||||
{ return sqrt(distSqr(lineSeg, p)); }
|
||||
|
||||
template<typename T>
|
||||
inline bool
|
||||
intersects(const SGRay<T>& ray, const SGSphere<T>& sphere)
|
||||
{
|
||||
// See Tomas Akeniene - Moeller/Eric Haines: Real Time Rendering,
|
||||
// second edition, page 571
|
||||
SGVec3<T> l = sphere.getCenter() - ray.getOrigin();
|
||||
T s = dot(l, ray.getDirection());
|
||||
T l2 = dot(l, l);
|
||||
|
||||
T r2 = sphere.getRadius2();
|
||||
if (s < 0 && l2 > r2)
|
||||
return false;
|
||||
|
||||
T d2 = dot(ray.getDirection(), ray.getDirection());
|
||||
// The original test would read
|
||||
// T m2 = l2 - s*s/d2;
|
||||
// if (m2 > r2)
|
||||
// return false;
|
||||
// but to avoid the expensive division, we multiply by d2
|
||||
T m2 = d2*l2 - s*s;
|
||||
if (m2 > d2*r2)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
// make it symmetric
|
||||
template<typename T>
|
||||
inline bool
|
||||
intersects(const SGSphere<T>& sphere, const SGRay<T>& ray)
|
||||
{ return intersects(ray, sphere); }
|
||||
|
||||
template<typename T>
|
||||
inline bool
|
||||
intersects(const SGLineSegment<T>& lineSegment, const SGSphere<T>& sphere)
|
||||
{
|
||||
// See Tomas Akeniene - Moeller/Eric Haines: Real Time Rendering,
|
||||
// second edition, page 571
|
||||
SGVec3<T> l = sphere.getCenter() - lineSegment.getStart();
|
||||
T ld = length(lineSegment.getDirection());
|
||||
T s = dot(l, lineSegment.getDirection())/ld;
|
||||
T l2 = dot(l, l);
|
||||
|
||||
T r2 = sphere.getRadius2();
|
||||
if (s < 0 && l2 > r2)
|
||||
return false;
|
||||
|
||||
T m2 = l2 - s*s;
|
||||
if (m2 > r2)
|
||||
return false;
|
||||
|
||||
T q = sqrt(r2 - m2);
|
||||
T t = s - q;
|
||||
if (ld < t)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
// make it symmetric
|
||||
template<typename T>
|
||||
inline bool
|
||||
intersects(const SGSphere<T>& sphere, const SGLineSegment<T>& lineSegment)
|
||||
{ return intersects(lineSegment, sphere); }
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline bool
|
||||
// FIXME do not use that default argument later. Just for development now
|
||||
intersects(SGVec3<T>& x, const SGTriangle<T>& tri, const SGRay<T>& ray, T eps = 0)
|
||||
{
|
||||
// See Tomas Akeniene - Moeller/Eric Haines: Real Time Rendering
|
||||
|
||||
// Method based on the observation that we are looking for a
|
||||
// point x that can be expressed in terms of the triangle points
|
||||
// x = v_0 + u*(v_1 - v_0) + v*(v_2 - v_0)
|
||||
// with 0 <= u, v and u + v <= 1.
|
||||
// OTOH it could be expressed in terms of the ray
|
||||
// x = o + t*d
|
||||
// Now we can compute u, v and t.
|
||||
SGVec3<T> p = cross(ray.getDirection(), tri.getEdge(1));
|
||||
|
||||
T denom = dot(p, tri.getEdge(0));
|
||||
T signDenom = copysign(1, denom);
|
||||
|
||||
SGVec3<T> s = ray.getOrigin() - tri.getBaseVertex();
|
||||
SGVec3<T> q = cross(s, tri.getEdge(0));
|
||||
// Now t would read
|
||||
// t = 1/denom*dot(q, tri.getEdge(1));
|
||||
// To avoid an expensive division we multiply by |denom|
|
||||
T tDenom = signDenom*dot(q, tri.getEdge(1));
|
||||
if (tDenom < 0)
|
||||
return false;
|
||||
// For line segment we would test against
|
||||
// if (1 < t)
|
||||
// return false;
|
||||
// with the original t. The multiplied test would read
|
||||
// if (absDenom < tDenom)
|
||||
// return false;
|
||||
|
||||
T absDenom = fabs(denom);
|
||||
T absDenomEps = absDenom*eps;
|
||||
|
||||
// T u = 1/denom*dot(p, s);
|
||||
T u = signDenom*dot(p, s);
|
||||
if (u < -absDenomEps)
|
||||
return false;
|
||||
// T v = 1/denom*dot(q, d);
|
||||
// if (v < -eps)
|
||||
// return false;
|
||||
T v = signDenom*dot(q, ray.getDirection());
|
||||
if (v < -absDenomEps)
|
||||
return false;
|
||||
|
||||
if (u + v > absDenom + absDenomEps)
|
||||
return false;
|
||||
|
||||
// return if paralell ??? FIXME what if paralell and in plane?
|
||||
// may be we are ok below than anyway??
|
||||
if (absDenom <= SGLimits<T>::min())
|
||||
return false;
|
||||
|
||||
x = ray.getOrigin();
|
||||
// if we have survived here it could only happen with denom == 0
|
||||
// that the point is already in plane. Then return the origin ...
|
||||
if (SGLimitsd::min() < absDenom)
|
||||
x += (tDenom/absDenom)*ray.getDirection();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline bool
|
||||
intersects(const SGTriangle<T>& tri, const SGRay<T>& ray, T eps = 0)
|
||||
{
|
||||
// FIXME: for now just wrap the other method. When that has prooven
|
||||
// well optimized, implement that special case
|
||||
SGVec3<T> dummy;
|
||||
return intersects(dummy, tri, ray, eps);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline bool
|
||||
// FIXME do not use that default argument later. Just for development now
|
||||
intersects(SGVec3<T>& x, const SGTriangle<T>& tri, const SGLineSegment<T>& lineSegment, T eps = 0)
|
||||
{
|
||||
// See Tomas Akeniene - Moeller/Eric Haines: Real Time Rendering
|
||||
|
||||
// Method based on the observation that we are looking for a
|
||||
// point x that can be expressed in terms of the triangle points
|
||||
// x = v_0 + u*(v_1 - v_0) + v*(v_2 - v_0)
|
||||
// with 0 <= u, v and u + v <= 1.
|
||||
// OTOH it could be expressed in terms of the lineSegment
|
||||
// x = o + t*d
|
||||
// Now we can compute u, v and t.
|
||||
SGVec3<T> p = cross(lineSegment.getDirection(), tri.getEdge(1));
|
||||
|
||||
T denom = dot(p, tri.getEdge(0));
|
||||
T signDenom = copysign(1, denom);
|
||||
|
||||
SGVec3<T> s = lineSegment.getStart() - tri.getBaseVertex();
|
||||
SGVec3<T> q = cross(s, tri.getEdge(0));
|
||||
// Now t would read
|
||||
// t = 1/denom*dot(q, tri.getEdge(1));
|
||||
// To avoid an expensive division we multiply by |denom|
|
||||
T tDenom = signDenom*dot(q, tri.getEdge(1));
|
||||
if (tDenom < 0)
|
||||
return false;
|
||||
// For line segment we would test against
|
||||
// if (1 < t)
|
||||
// return false;
|
||||
// with the original t. The multiplied test reads
|
||||
T absDenom = fabs(denom);
|
||||
if (absDenom < tDenom)
|
||||
return false;
|
||||
|
||||
// take the CPU accuracy in account
|
||||
T absDenomEps = absDenom*eps;
|
||||
|
||||
// T u = 1/denom*dot(p, s);
|
||||
T u = signDenom*dot(p, s);
|
||||
if (u < -absDenomEps)
|
||||
return false;
|
||||
// T v = 1/denom*dot(q, d);
|
||||
// if (v < -eps)
|
||||
// return false;
|
||||
T v = signDenom*dot(q, lineSegment.getDirection());
|
||||
if (v < -absDenomEps)
|
||||
return false;
|
||||
|
||||
if (u + v > absDenom + absDenomEps)
|
||||
return false;
|
||||
|
||||
// return if paralell ??? FIXME what if paralell and in plane?
|
||||
// may be we are ok below than anyway??
|
||||
if (absDenom <= SGLimits<T>::min())
|
||||
return false;
|
||||
|
||||
x = lineSegment.getStart();
|
||||
// if we have survived here it could only happen with denom == 0
|
||||
// that the point is already in plane. Then return the origin ...
|
||||
if (SGLimitsd::min() < absDenom)
|
||||
x += (tDenom/absDenom)*lineSegment.getDirection();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline bool
|
||||
intersects(const SGTriangle<T>& tri, const SGLineSegment<T>& lineSegment, T eps = 0)
|
||||
{
|
||||
// FIXME: for now just wrap the othr method. When that has prooven
|
||||
// well optimized, implement that special case
|
||||
SGVec3<T> dummy;
|
||||
return intersects(dummy, tri, lineSegment, eps);
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline bool
|
||||
intersects(const SGVec3<T>& v, const SGSphere<T>& sphere)
|
||||
{
|
||||
if (sphere.empty())
|
||||
return false;
|
||||
return distSqr(v, sphere.getCenter()) <= sphere.getRadius2();
|
||||
}
|
||||
template<typename T>
|
||||
inline bool
|
||||
intersects(const SGSphere<T>& sphere, const SGVec3<T>& v)
|
||||
{ return intersects(v, sphere); }
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline bool
|
||||
intersects(const SGBox<T>& box, const SGLineSegment<T>& lineSegment)
|
||||
{
|
||||
// See Tomas Akeniene - Moeller/Eric Haines: Real Time Rendering
|
||||
|
||||
SGVec3<T> c = lineSegment.getCenter() - box.getCenter();
|
||||
SGVec3<T> w = 0.5*lineSegment.getDirection();
|
||||
SGVec3<T> v(fabs(w.x()), fabs(w.y()), fabs(w.z()));
|
||||
SGVec3<T> h = 0.5*box.getSize();
|
||||
|
||||
if (fabs(c[0]) > v[0] + h[0])
|
||||
return false;
|
||||
if (fabs(c[1]) > v[1] + h[1])
|
||||
return false;
|
||||
if (fabs(c[2]) > v[2] + h[2])
|
||||
return false;
|
||||
|
||||
if (fabs(c[1]*w[2] - c[2]*w[1]) > h[1]*v[2] + h[2]*v[1])
|
||||
return false;
|
||||
if (fabs(c[0]*w[2] - c[2]*w[0]) > h[0]*v[2] + h[2]*v[0])
|
||||
return false;
|
||||
if (fabs(c[0]*w[1] - c[1]*w[0]) > h[0]*v[1] + h[1]*v[0])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
template<typename T>
|
||||
inline bool
|
||||
intersects(const SGLineSegment<T>& lineSegment, const SGBox<T>& box)
|
||||
{ return intersects(box, lineSegment); }
|
||||
|
||||
template<typename T>
|
||||
inline bool
|
||||
intersects(const SGBox<T>& box, const SGRay<T>& ray)
|
||||
{
|
||||
// See Tomas Akeniene - Moeller/Eric Haines: Real Time Rendering
|
||||
|
||||
for (unsigned i = 0; i < 3; ++i) {
|
||||
T cMin = box.getMin()[i];
|
||||
T cMax = box.getMax()[i];
|
||||
|
||||
T cOrigin = ray.getOrigin()[i];
|
||||
|
||||
T cDir = ray.getDirection()[i];
|
||||
if (fabs(cDir) <= SGLimits<T>::min()) {
|
||||
if (cOrigin < cMin)
|
||||
return false;
|
||||
if (cMax < cOrigin)
|
||||
return false;
|
||||
}
|
||||
|
||||
T nearr = - SGLimits<T>::max();
|
||||
T farr = SGLimits<T>::max();
|
||||
|
||||
T T1 = (cMin - cOrigin) / cDir;
|
||||
T T2 = (cMax - cOrigin) / cDir;
|
||||
if (T1 > T2) std::swap (T1, T2);/* since T1 intersection with near plane */
|
||||
if (T1 > nearr) nearr = T1; /* want largest Tnear */
|
||||
if (T2 < farr) farr = T2; /* want smallest Tfarr */
|
||||
if (nearr > farr) // farr box is missed
|
||||
return false;
|
||||
if (farr < 0) // box is behind ray
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
// make it symmetric
|
||||
template<typename T>
|
||||
inline bool
|
||||
intersects(const SGRay<T>& ray, const SGBox<T>& box)
|
||||
{ return intersects(box, ray); }
|
||||
|
||||
#endif
|
||||
@@ -26,7 +26,4 @@
|
||||
template<typename T>
|
||||
class SGLimits : public std::numeric_limits<T> {};
|
||||
|
||||
typedef SGLimits<float> SGLimitsf;
|
||||
typedef SGLimits<double> SGLimitsd;
|
||||
|
||||
#endif
|
||||
|
||||
62
simgear/math/SGLineSegment.hxx
Normal file
62
simgear/math/SGLineSegment.hxx
Normal file
@@ -0,0 +1,62 @@
|
||||
// Copyright (C) 2006 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
|
||||
#ifndef SGLineSegment_H
|
||||
#define SGLineSegment_H
|
||||
|
||||
template<typename T>
|
||||
class SGLineSegment {
|
||||
public:
|
||||
SGLineSegment()
|
||||
{ }
|
||||
SGLineSegment(const SGVec3<T>& start, const SGVec3<T>& end) :
|
||||
_start(start),
|
||||
_direction(end - start)
|
||||
{ }
|
||||
|
||||
void set(const SGVec3<T>& start, const SGVec3<T>& end)
|
||||
{ _start = start; _direction = end - start; }
|
||||
|
||||
const SGVec3<T>& getStart() const
|
||||
{ return _start; }
|
||||
SGVec3<T> getEnd() const
|
||||
{ return _start + _direction; }
|
||||
const SGVec3<T>& getDirection() const
|
||||
{ return _direction; }
|
||||
SGVec3<T> getNormalizedDirection() const
|
||||
{ return normalize(getDirection()); }
|
||||
|
||||
SGVec3<T> getCenter() const
|
||||
{ return _start + T(0.5)*_direction; }
|
||||
|
||||
private:
|
||||
SGVec3<T> _start;
|
||||
SGVec3<T> _direction;
|
||||
};
|
||||
|
||||
/// Output to an ostream
|
||||
template<typename char_type, typename traits_type, typename T>
|
||||
inline
|
||||
std::basic_ostream<char_type, traits_type>&
|
||||
operator<<(std::basic_ostream<char_type, traits_type>& s,
|
||||
const SGLineSegment<T>& lineSegment)
|
||||
{
|
||||
return s << "line segment: start = " << lineSegment.getStart()
|
||||
<< ", end = " << lineSegment.getEnd();
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -21,15 +21,25 @@
|
||||
/// Just include them all
|
||||
|
||||
#include <iosfwd>
|
||||
// FIXME, make it compile on IRIX
|
||||
|
||||
//#include <osg/GL>
|
||||
//#undef GLUT_APIENTRY_DEFINED // GL/glut.h undef APIENTRY when this symbol is defined. osg/GL defines it (?).
|
||||
// This probably would work if we didn't use plib/pu.h that include GL/glut.h
|
||||
// on its side.
|
||||
|
||||
#include "SGMathFwd.hxx"
|
||||
|
||||
#include "SGCMath.hxx"
|
||||
#include "SGLimits.hxx"
|
||||
#include "SGMisc.hxx"
|
||||
#include "SGGeodesy.hxx"
|
||||
#include "SGVec2.hxx"
|
||||
#include "SGVec3.hxx"
|
||||
#include "SGVec4.hxx"
|
||||
#include "SGQuat.hxx"
|
||||
#include "SGMatrix.hxx"
|
||||
#include "SGGeoc.hxx"
|
||||
#include "SGGeod.hxx"
|
||||
#include "SGQuat.hxx"
|
||||
#include "SGMatrix.hxx"
|
||||
|
||||
#endif
|
||||
|
||||
56
simgear/math/SGMathFwd.hxx
Normal file
56
simgear/math/SGMathFwd.hxx
Normal file
@@ -0,0 +1,56 @@
|
||||
// Copyright (C) 2006 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
|
||||
#ifndef SGMathFwd_H
|
||||
#define SGMathFwd_H
|
||||
|
||||
// All forward declarations in case they only need to be declared
|
||||
|
||||
class SGGeoc;
|
||||
class SGGeod;
|
||||
|
||||
template<typename T>
|
||||
class SGLimits;
|
||||
template<typename T>
|
||||
class SGMatrix;
|
||||
template<typename T>
|
||||
class SGMisc;
|
||||
template<typename T>
|
||||
class SGQuat;
|
||||
template<typename T>
|
||||
class SGVec2;
|
||||
template<typename T>
|
||||
class SGVec3;
|
||||
template<typename T>
|
||||
class SGVec4;
|
||||
|
||||
typedef SGLimits<float> SGLimitsf;
|
||||
typedef SGLimits<double> SGLimitsd;
|
||||
typedef SGMatrix<float> SGMatrixf;
|
||||
typedef SGMatrix<double> SGMatrixd;
|
||||
typedef SGMisc<float> SGMiscf;
|
||||
typedef SGMisc<double> SGMiscd;
|
||||
typedef SGQuat<float> SGQuatf;
|
||||
typedef SGQuat<double> SGQuatd;
|
||||
typedef SGVec2<float> SGVec2f;
|
||||
typedef SGVec2<double> SGVec2d;
|
||||
typedef SGVec3<float> SGVec3f;
|
||||
typedef SGVec3<double> SGVec3d;
|
||||
typedef SGVec4<float> SGVec4f;
|
||||
typedef SGVec4<double> SGVec4d;
|
||||
|
||||
#endif
|
||||
@@ -174,7 +174,9 @@ MatrixTest(void)
|
||||
// Create some test matrix
|
||||
SGVec3<T> v0(2, 7, 17);
|
||||
SGQuat<T> q0 = SGQuat<T>::fromAngleAxis(SGMisc<T>::pi(), normalize(v0));
|
||||
SGMatrix<T> m0(q0, v0);
|
||||
SGMatrix<T> m0;
|
||||
m0.postMultTranslate(v0);
|
||||
m0.postMultRotate(q0);
|
||||
|
||||
// Check the tqo forms of the inverse for that kind of special matrix
|
||||
SGMatrix<T> m1, m2;
|
||||
@@ -213,16 +215,16 @@ GeodesyTest(void)
|
||||
geod0 = SGGeod::fromDegM(30, 20, 17);
|
||||
|
||||
// Test the conversion routines to cartesian coordinates
|
||||
cart0 = geod0;
|
||||
geod1 = cart0;
|
||||
cart0 = SGVec3<double>::fromGeod(geod0);
|
||||
geod1 = SGGeod::fromCart(cart0);
|
||||
if (epsDeg < fabs(geod0.getLongitudeDeg() - geod1.getLongitudeDeg()) ||
|
||||
epsDeg < fabs(geod0.getLatitudeDeg() - geod1.getLatitudeDeg()) ||
|
||||
epsM < fabs(geod0.getElevationM() - geod1.getElevationM()))
|
||||
return false;
|
||||
|
||||
// Test the conversion routines to radial coordinates
|
||||
geoc0 = cart0;
|
||||
cart1 = geoc0;
|
||||
geoc0 = SGGeoc::fromCart(cart0);
|
||||
cart1 = SGVec3<double>::fromGeoc(geoc0);
|
||||
if (!equivalent(cart0, cart1))
|
||||
return false;
|
||||
|
||||
@@ -236,7 +238,9 @@ sgInterfaceTest(void)
|
||||
SGVec3f v3f = SGVec3f::e2();
|
||||
SGVec4f v4f = SGVec4f::e2();
|
||||
SGQuatf qf = SGQuatf::fromEulerRad(1.2, 1.3, -0.4);
|
||||
SGMatrixf mf(qf, v3f);
|
||||
SGMatrixf mf;
|
||||
mf.postMultTranslate(v3f);
|
||||
mf.postMultRotate(qf);
|
||||
|
||||
// Copy to and from plibs types check if result is equal,
|
||||
// test for exact equality
|
||||
@@ -283,7 +287,9 @@ sgdInterfaceTest(void)
|
||||
SGVec3d v3d = SGVec3d::e2();
|
||||
SGVec4d v4d = SGVec4d::e2();
|
||||
SGQuatd qd = SGQuatd::fromEulerRad(1.2, 1.3, -0.4);
|
||||
SGMatrixd md(qd, v3d);
|
||||
SGMatrixd md;
|
||||
md.postMultTranslate(v3d);
|
||||
md.postMultRotate(qd);
|
||||
|
||||
// Copy to and from plibs types check if result is equal,
|
||||
// test for exact equality
|
||||
@@ -346,8 +352,8 @@ main(void)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
// Check geodetic/geocentric/cartesian conversions
|
||||
// if (!GeodesyTest())
|
||||
// return EXIT_FAILURE;
|
||||
if (!GeodesyTest())
|
||||
return EXIT_FAILURE;
|
||||
|
||||
// Check interaction with sg*/sgd*
|
||||
if (!sgInterfaceTest())
|
||||
|
||||
@@ -22,9 +22,6 @@
|
||||
template<typename T>
|
||||
struct TransNegRef;
|
||||
|
||||
template<typename T>
|
||||
class SGMatrix;
|
||||
|
||||
/// 3D Matrix Class
|
||||
template<typename T>
|
||||
class SGMatrix {
|
||||
@@ -66,14 +63,13 @@ public:
|
||||
}
|
||||
|
||||
/// Constructor, build up a SGMatrix from a translation
|
||||
SGMatrix(const SGVec3<T>& trans)
|
||||
template<typename S>
|
||||
SGMatrix(const SGVec3<S>& trans)
|
||||
{ set(trans); }
|
||||
|
||||
/// Constructor, build up a SGMatrix from a rotation and a translation
|
||||
SGMatrix(const SGQuat<T>& quat, const SGVec3<T>& trans)
|
||||
{ set(quat, trans); }
|
||||
/// Constructor, build up a SGMatrix from a rotation and a translation
|
||||
SGMatrix(const SGQuat<T>& quat)
|
||||
template<typename S>
|
||||
SGMatrix(const SGQuat<S>& quat)
|
||||
{ set(quat); }
|
||||
|
||||
/// Copy constructor for a transposed negated matrix
|
||||
@@ -81,39 +77,22 @@ public:
|
||||
{ set(tm); }
|
||||
|
||||
/// Set from a tranlation
|
||||
void set(const SGVec3<T>& trans)
|
||||
template<typename S>
|
||||
void set(const SGVec3<S>& trans)
|
||||
{
|
||||
_data.flat[0] = 1; _data.flat[4] = 0;
|
||||
_data.flat[8] = 0; _data.flat[12] = -trans(0);
|
||||
_data.flat[8] = 0; _data.flat[12] = T(trans(0));
|
||||
_data.flat[1] = 0; _data.flat[5] = 1;
|
||||
_data.flat[9] = 0; _data.flat[13] = -trans(1);
|
||||
_data.flat[9] = 0; _data.flat[13] = T(trans(1));
|
||||
_data.flat[2] = 0; _data.flat[6] = 0;
|
||||
_data.flat[10] = 1; _data.flat[14] = -trans(2);
|
||||
_data.flat[10] = 1; _data.flat[14] = T(trans(2));
|
||||
_data.flat[3] = 0; _data.flat[7] = 0;
|
||||
_data.flat[11] = 0; _data.flat[15] = 1;
|
||||
}
|
||||
|
||||
/// Set from a scale/rotation and tranlation
|
||||
void set(const SGQuat<T>& quat, const SGVec3<T>& trans)
|
||||
{
|
||||
T w = quat.w(); T x = quat.x(); T y = quat.y(); T z = quat.z();
|
||||
T xx = x*x; T yy = y*y; T zz = z*z;
|
||||
T wx = w*x; T wy = w*y; T wz = w*z;
|
||||
T xy = x*y; T xz = x*z; T yz = y*z;
|
||||
_data.flat[0] = 1-2*(yy+zz); _data.flat[1] = 2*(xy-wz);
|
||||
_data.flat[2] = 2*(xz+wy); _data.flat[3] = 0;
|
||||
_data.flat[4] = 2*(xy+wz); _data.flat[5] = 1-2*(xx+zz);
|
||||
_data.flat[6] = 2*(yz-wx); _data.flat[7] = 0;
|
||||
_data.flat[8] = 2*(xz-wy); _data.flat[9] = 2*(yz+wx);
|
||||
_data.flat[10] = 1-2*(xx+yy); _data.flat[11] = 0;
|
||||
// Well, this one is ugly here, as that xform method on the current
|
||||
// object needs the above data to be already set ...
|
||||
SGVec3<T> t = xformVec(trans);
|
||||
_data.flat[12] = -t(0); _data.flat[13] = -t(1);
|
||||
_data.flat[14] = -t(2); _data.flat[15] = 1;
|
||||
}
|
||||
/// Set from a scale/rotation and tranlation
|
||||
void set(const SGQuat<T>& quat)
|
||||
template<typename S>
|
||||
void set(const SGQuat<S>& quat)
|
||||
{
|
||||
T w = quat.w(); T x = quat.x(); T y = quat.y(); T z = quat.z();
|
||||
T xx = x*x; T yy = y*y; T zz = z*z;
|
||||
@@ -202,6 +181,45 @@ public:
|
||||
/// Inplace matrix multiplication, post multiply
|
||||
SGMatrix& operator*=(const SGMatrix<T>& m2);
|
||||
|
||||
template<typename S>
|
||||
SGMatrix& preMultTranslate(const SGVec3<S>& t)
|
||||
{
|
||||
for (unsigned i = 0; i < SGMatrix<T>::nCols-1; ++i)
|
||||
(*this)(i,3) += T(t(i));
|
||||
return *this;
|
||||
}
|
||||
template<typename S>
|
||||
SGMatrix& postMultTranslate(const SGVec3<S>& t)
|
||||
{
|
||||
SGVec4<T> col3((*this)(0,3), (*this)(1,3), (*this)(2,3), (*this)(3,3));
|
||||
for (unsigned i = 0; i < SGMatrix<T>::nCols-1; ++i) {
|
||||
SGVec4<T> tmp((*this)(0,3), (*this)(1,3), (*this)(2,3), (*this)(3,3));
|
||||
col3 += T(t(i))*tmp;
|
||||
}
|
||||
(*this)(0,3) = col3(0); (*this)(1,3) = col3(1);
|
||||
(*this)(2,3) = col3(2); (*this)(3,3) = col3(3);
|
||||
return *this;
|
||||
}
|
||||
|
||||
SGMatrix& preMultRotate(const SGQuat<T>& r)
|
||||
{
|
||||
for (unsigned i = 0; i < SGMatrix<T>::nCols; ++i) {
|
||||
SGVec3<T> col((*this)(0,i), (*this)(1,i), (*this)(2,i));
|
||||
col = r.transform(col);
|
||||
(*this)(0,i) = col(0); (*this)(1,i) = col(1); (*this)(2,i) = col(2);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
SGMatrix& postMultRotate(const SGQuat<T>& r)
|
||||
{
|
||||
for (unsigned i = 0; i < SGMatrix<T>::nCols; ++i) {
|
||||
SGVec3<T> col((*this)(i,0), (*this)(i,1), (*this)(i,2));
|
||||
col = r.backTransform(col);
|
||||
(*this)(i,0) = col(0); (*this)(i,1) = col(1); (*this)(i,2) = col(2);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
SGVec3<T> xformPt(const SGVec3<T>& pt) const
|
||||
{
|
||||
SGVec3<T> tpt;
|
||||
@@ -571,18 +589,14 @@ operator<<(std::basic_ostream<char_type, traits_type>& s, const SGMatrix<T>& m)
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Two classes doing actually the same on different types
|
||||
typedef SGMatrix<float> SGMatrixf;
|
||||
typedef SGMatrix<double> SGMatrixd;
|
||||
|
||||
inline
|
||||
SGMatrixf
|
||||
toMatrixf(const SGMatrixd& m)
|
||||
{
|
||||
return SGMatrixf((float)m(0,0), (float)m(0,1), (float)m(0,2), (float)m(0,3),
|
||||
(float)m(1,0), (float)m(1,1), (float)m(1,2), (float)m(1,3),
|
||||
(float)m(3,0), (float)m(2,1), (float)m(2,2), (float)m(2,3),
|
||||
(float)m(4,0), (float)m(4,1), (float)m(4,2), (float)m(4,3));
|
||||
(float)m(2,0), (float)m(2,1), (float)m(2,2), (float)m(2,3),
|
||||
(float)m(3,0), (float)m(3,1), (float)m(3,2), (float)m(3,3));
|
||||
}
|
||||
|
||||
inline
|
||||
@@ -591,8 +605,8 @@ toMatrixd(const SGMatrixf& m)
|
||||
{
|
||||
return SGMatrixd(m(0,0), m(0,1), m(0,2), m(0,3),
|
||||
m(1,0), m(1,1), m(1,2), m(1,3),
|
||||
m(3,0), m(2,1), m(2,2), m(2,3),
|
||||
m(4,0), m(4,1), m(4,2), m(4,3));
|
||||
m(2,0), m(2,1), m(2,2), m(2,3),
|
||||
m(3,0), m(3,1), m(3,2), m(3,3));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -18,12 +18,12 @@
|
||||
#ifndef SGMisc_H
|
||||
#define SGMisc_H
|
||||
|
||||
#include <cmath>
|
||||
|
||||
template<typename T>
|
||||
class SGMisc {
|
||||
public:
|
||||
static T pi() { return T(3.1415926535897932384626433832795029L); }
|
||||
static T twopi() { return 2*T(3.1415926535897932384626433832795029L); }
|
||||
|
||||
static T min(const T& a, const T& b)
|
||||
{ return a < b ? a : b; }
|
||||
static T min(const T& a, const T& b, const T& c)
|
||||
@@ -36,6 +36,11 @@ public:
|
||||
{ return max(max(a, b), c); }
|
||||
static T max(const T& a, const T& b, const T& c, const T& d)
|
||||
{ return max(max(max(a, b), c), d); }
|
||||
|
||||
// clip the value of a to be in the range between and including _min and _max
|
||||
static T clip(const T& a, const T& _min, const T& _max)
|
||||
{ return max(_min, min(_max, a)); }
|
||||
|
||||
static int sign(const T& a)
|
||||
{
|
||||
if (a < -SGLimits<T>::min())
|
||||
@@ -51,6 +56,37 @@ public:
|
||||
static T deg2rad(const T& val)
|
||||
{ return val*pi()/180; }
|
||||
|
||||
// normalize the value to be in a range between [min, max[
|
||||
static T
|
||||
normalizePeriodic(const T& min, const T& max, const T& value)
|
||||
{
|
||||
T range = max - min;
|
||||
if (range < SGLimits<T>::min())
|
||||
return min;
|
||||
T normalized = value - range*floor((value - min)/range);
|
||||
// two security checks that can only happen due to roundoff
|
||||
if (value <= min)
|
||||
return min;
|
||||
if (max <= normalized)
|
||||
return min;
|
||||
return normalized;
|
||||
}
|
||||
|
||||
// normalize the angle to be in a range between [-pi, pi[
|
||||
static T
|
||||
normalizeAngle(const T& angle)
|
||||
{ return normalizePeriodic(-pi(), pi(), angle); }
|
||||
|
||||
// normalize the angle to be in a range between [0, 2pi[
|
||||
static T
|
||||
normalizeAngle2(const T& angle)
|
||||
{ return normalizePeriodic(0, twopi(), angle); }
|
||||
|
||||
static T round(const T& v)
|
||||
{ return floor(v + T(0.5)); }
|
||||
static int roundToInt(const T& v)
|
||||
{ return int(round(v)); }
|
||||
|
||||
#ifndef NDEBUG
|
||||
/// Returns true if v is a NaN value
|
||||
/// Use with care: allways code that you do not need to use that!
|
||||
@@ -71,7 +107,4 @@ public:
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef SGMisc<float> SGMiscf;
|
||||
typedef SGMisc<double> SGMiscd;
|
||||
|
||||
#endif
|
||||
|
||||
59
simgear/math/SGPlane.hxx
Normal file
59
simgear/math/SGPlane.hxx
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright (C) 2006 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
|
||||
#ifndef SGPlane_H
|
||||
#define SGPlane_H
|
||||
|
||||
template<typename T>
|
||||
class SGPlane {
|
||||
public:
|
||||
SGPlane()
|
||||
{ }
|
||||
SGPlane(const SGVec3<T>& normal, T dist) :
|
||||
_normal(normal), _dist(dist)
|
||||
{ }
|
||||
SGPlane(const SGVec3<T> vertices[3]) :
|
||||
_normal(normalize(cross(vertices[1] - vertices[0],
|
||||
vertices[2] - vertices[0]))),
|
||||
_dist(-dot(_normal, vertices[0]))
|
||||
{ }
|
||||
|
||||
void setNormal(const SGVec3<T>& normal)
|
||||
{ _normal = normal; }
|
||||
const SGVec3<T>& getNormal() const
|
||||
{ return _normal; }
|
||||
|
||||
void setDist(const T& dist)
|
||||
{ _dist = dist; }
|
||||
const T& getDist() const
|
||||
{ return _dist; }
|
||||
|
||||
/// That is the distance where we measure positive in direction of the normal
|
||||
T getPositiveDist() const
|
||||
{ return -_dist; }
|
||||
/// That is the distance where we measure positive in the oposite direction
|
||||
/// of the normal.
|
||||
const T& getNegativeDist() const
|
||||
{ return _dist; }
|
||||
|
||||
private:
|
||||
// That ordering is important because of one constructor
|
||||
SGVec3<T> _normal;
|
||||
T _dist;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -18,9 +18,50 @@
|
||||
#ifndef SGQuat_H
|
||||
#define SGQuat_H
|
||||
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
|
||||
#include <osg/Quat>
|
||||
|
||||
template<typename T>
|
||||
struct SGQuatStorage {
|
||||
/// Readonly raw storage interface
|
||||
const T (&data(void) const)[4]
|
||||
{ return _data; }
|
||||
/// Readonly raw storage interface
|
||||
T (&data(void))[4]
|
||||
{ return _data; }
|
||||
|
||||
void osg() const
|
||||
{ }
|
||||
|
||||
private:
|
||||
T _data[4];
|
||||
};
|
||||
|
||||
template<>
|
||||
struct SGQuatStorage<double> : public osg::Quat {
|
||||
/// Access raw data by index, the index is unchecked
|
||||
const double (&data(void) const)[4]
|
||||
{ return osg::Quat::_v; }
|
||||
/// Access raw data by index, the index is unchecked
|
||||
double (&data(void))[4]
|
||||
{ return osg::Quat::_v; }
|
||||
|
||||
const osg::Quat& osg() const
|
||||
{ return *this; }
|
||||
osg::Quat& osg()
|
||||
{ return *this; }
|
||||
};
|
||||
|
||||
/// 3D Vector Class
|
||||
template<typename T>
|
||||
class SGQuat {
|
||||
class SGQuat : protected SGQuatStorage<T> {
|
||||
public:
|
||||
typedef T value_type;
|
||||
|
||||
@@ -33,7 +74,7 @@ public:
|
||||
/// uninitialized values in the debug build very fast ...
|
||||
#ifndef NDEBUG
|
||||
for (unsigned i = 0; i < 4; ++i)
|
||||
_data[i] = SGLimits<T>::quiet_NaN();
|
||||
data()[i] = SGLimits<T>::quiet_NaN();
|
||||
#endif
|
||||
}
|
||||
/// Constructor. Initialize by the given values
|
||||
@@ -42,11 +83,13 @@ public:
|
||||
/// Constructor. Initialize by the content of a plain array,
|
||||
/// make sure it has at least 4 elements
|
||||
explicit SGQuat(const T* d)
|
||||
{ _data[0] = d[0]; _data[1] = d[1]; _data[2] = d[2]; _data[3] = d[3]; }
|
||||
{ data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; data()[3] = d[3]; }
|
||||
explicit SGQuat(const osg::Quat& d)
|
||||
{ data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; data()[3] = d[3]; }
|
||||
|
||||
/// Return a unit quaternion
|
||||
static SGQuat unit(void)
|
||||
{ return fromRealImag(1, SGVec3<T>(0)); }
|
||||
{ return fromRealImag(1, SGVec3<T>(0, 0, 0)); }
|
||||
|
||||
/// Return a quaternion from euler angles
|
||||
static SGQuat fromEulerRad(T z, T y, T x)
|
||||
@@ -87,13 +130,17 @@ public:
|
||||
static SGQuat fromHeadAttBankDeg(T h, T a, T b)
|
||||
{ return fromEulerDeg(h, a, b); }
|
||||
|
||||
/// Return a quaternion rotation the the horizontal local frame from given
|
||||
/// longitude and latitude
|
||||
/// Return a quaternion rotation from the earth centered to the
|
||||
/// simulation usual horizontal local frame from given
|
||||
/// longitude and latitude.
|
||||
/// The horizontal local frame used in simulations is the frame with x-axis
|
||||
/// pointing north, the y-axis pointing eastwards and the z axis
|
||||
/// pointing downwards.
|
||||
static SGQuat fromLonLatRad(T lon, T lat)
|
||||
{
|
||||
SGQuat q;
|
||||
T zd2 = T(0.5)*lon;
|
||||
T yd2 = T(-0.25)*SGMisc<value_type>::pi() - T(0.5)*lat;
|
||||
T yd2 = T(-0.25)*SGMisc<T>::pi() - T(0.5)*lat;
|
||||
T Szd2 = sin(zd2);
|
||||
T Syd2 = sin(yd2);
|
||||
T Czd2 = cos(zd2);
|
||||
@@ -104,11 +151,50 @@ public:
|
||||
q.z() = Szd2*Cyd2;
|
||||
return q;
|
||||
}
|
||||
|
||||
/// Return a quaternion rotation the the horizontal local frame from given
|
||||
/// longitude and latitude
|
||||
/// Like the above provided for convenience
|
||||
static SGQuat fromLonLatDeg(T lon, T lat)
|
||||
{ return fromLonLatRad(SGMisc<T>::deg2rad(lon), SGMisc<T>::deg2rad(lat)); }
|
||||
/// Like the above provided for convenience
|
||||
static SGQuat fromLonLat(const SGGeod& geod)
|
||||
{ return fromLonLatRad(geod.getLongitudeRad(), geod.getLatitudeRad()); }
|
||||
|
||||
/// Return a quaternion rotation from the earth centered to the
|
||||
/// OpenGL/viewer horizontal local frame from given longitude and latitude.
|
||||
/// This frame matches the usual OpenGL axis directions. That is the target
|
||||
/// frame has an x-axis pointing eastwards, y-axis pointing up and y z-axis
|
||||
/// pointing south.
|
||||
static SGQuat viewHLRad(T lon, T lat)
|
||||
{
|
||||
// That bails down to a 3-2-1 euler sequence lon+pi/2, 0, -lat-pi
|
||||
// what is here is again the hand optimized version ...
|
||||
SGQuat q;
|
||||
T xd2 = -T(0.5)*lat - T(0.5)*SGMisc<T>::pi();
|
||||
T zd2 = T(0.5)*lon + T(0.25)*SGMisc<T>::pi();
|
||||
T Szd2 = sin(zd2);
|
||||
T Sxd2 = sin(xd2);
|
||||
T Czd2 = cos(zd2);
|
||||
T Cxd2 = cos(xd2);
|
||||
q.w() = Cxd2*Czd2;
|
||||
q.x() = Sxd2*Czd2;
|
||||
q.y() = Sxd2*Szd2;
|
||||
q.z() = Cxd2*Szd2;
|
||||
return q;
|
||||
}
|
||||
/// Like the above provided for convenience
|
||||
static SGQuat viewHLDeg(T lon, T lat)
|
||||
{ return viewHLRad(SGMisc<T>::deg2rad(lon), SGMisc<T>::deg2rad(lat)); }
|
||||
/// Like the above provided for convenience
|
||||
static SGQuat viewHL(const SGGeod& geod)
|
||||
{ return viewHLRad(geod.getLongitudeRad(), geod.getLatitudeRad()); }
|
||||
|
||||
/// Convert a quaternion rotation from the simulation frame
|
||||
/// to the view (OpenGL) frame. That is it just swaps the axis part of
|
||||
/// this current quaternion.
|
||||
/// That proves useful when you want to use the euler 3-2-1 sequence
|
||||
/// for the usual heading/pitch/roll sequence within the context of
|
||||
/// OpenGL/viewer frames.
|
||||
static SGQuat simToView(const SGQuat& q)
|
||||
{ return SGQuat(q.y(), -q.z(), -q.x(), q.w()); }
|
||||
|
||||
/// Create a quaternion from the angle axis representation
|
||||
static SGQuat fromAngleAxis(T angle, const SGVec3<T>& axis)
|
||||
@@ -132,14 +218,100 @@ public:
|
||||
return fromRealImag(cos(angle2), T(sin(angle2)/nAxis)*axis);
|
||||
}
|
||||
|
||||
static SGQuat fromRotateTo(const SGVec3<T>& from, const SGVec3<T>& to)
|
||||
{
|
||||
T nfrom = norm(from);
|
||||
T nto = norm(to);
|
||||
if (nfrom < SGLimits<T>::min() || nto < SGLimits<T>::min())
|
||||
return SGQuat::unit();
|
||||
|
||||
return SGQuat::fromRotateToNorm((1/nfrom)*from, (1/nto)*to);
|
||||
}
|
||||
|
||||
// FIXME more finegrained error behavour.
|
||||
static SGQuat fromRotateTo(const SGVec3<T>& v1, unsigned i1,
|
||||
const SGVec3<T>& v2, unsigned i2)
|
||||
{
|
||||
T nrmv1 = norm(v1);
|
||||
T nrmv2 = norm(v2);
|
||||
if (nrmv1 < SGLimits<T>::min() || nrmv2 < SGLimits<T>::min())
|
||||
return SGQuat::unit();
|
||||
|
||||
SGVec3<T> nv1 = (1/nrmv1)*v1;
|
||||
SGVec3<T> nv2 = (1/nrmv2)*v2;
|
||||
T dv1v2 = dot(nv1, nv2);
|
||||
if (fabs(fabs(dv1v2)-1) < SGLimits<T>::epsilon())
|
||||
return SGQuat::unit();
|
||||
|
||||
// The target vector for the first rotation
|
||||
SGVec3<T> nto1 = SGVec3<T>::zeros();
|
||||
SGVec3<T> nto2 = SGVec3<T>::zeros();
|
||||
nto1[i1] = 1;
|
||||
nto2[i2] = 1;
|
||||
|
||||
// The first rotation can be done with the usual routine.
|
||||
SGQuat q = SGQuat::fromRotateToNorm(nv1, nto1);
|
||||
|
||||
// The rotation axis for the second rotation is the
|
||||
// target for the first one, so the rotation axis is nto1
|
||||
// We need to get the angle.
|
||||
|
||||
// Make nv2 exactly orthogonal to nv1.
|
||||
nv2 = normalize(nv2 - dv1v2*nv1);
|
||||
|
||||
SGVec3<T> tnv2 = q.transform(nv2);
|
||||
T cosang = dot(nto2, tnv2);
|
||||
T cos05ang = T(0.5+0.5*cosang);
|
||||
if (cos05ang <= 0)
|
||||
cosang = T(0);
|
||||
cos05ang = sqrt(cos05ang);
|
||||
T sig = dot(nto1, cross(nto2, tnv2));
|
||||
T sin05ang = T(0.5-0.5*cosang);
|
||||
if (sin05ang <= 0)
|
||||
sin05ang = 0;
|
||||
sin05ang = copysign(sqrt(sin05ang), sig);
|
||||
q *= SGQuat::fromRealImag(cos05ang, sin05ang*nto1);
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
|
||||
// Return a quaternion which rotates the vector given by v
|
||||
// to the vector -v. Other directions are *not* preserved.
|
||||
static SGQuat fromChangeSign(const SGVec3<T>& v)
|
||||
{
|
||||
// The vector from points to the oposite direction than to.
|
||||
// Find a vector perpendicular to the vector to.
|
||||
T absv1 = fabs(v(0));
|
||||
T absv2 = fabs(v(1));
|
||||
T absv3 = fabs(v(2));
|
||||
|
||||
SGVec3<T> axis;
|
||||
if (absv2 < absv1 && absv3 < absv1) {
|
||||
T quot = v(1)/v(0);
|
||||
axis = (1/sqrt(1+quot*quot))*SGVec3<T>(quot, -1, 0);
|
||||
} else if (absv1 < absv2 && absv3 < absv2) {
|
||||
T quot = v(2)/v(1);
|
||||
axis = (1/sqrt(1+quot*quot))*SGVec3<T>(0, quot, -1);
|
||||
} else if (absv1 < absv3 && absv2 < absv3) {
|
||||
T quot = v(0)/v(2);
|
||||
axis = (1/sqrt(1+quot*quot))*SGVec3<T>(-1, 0, quot);
|
||||
} else {
|
||||
// The all zero case.
|
||||
return SGQuat::unit();
|
||||
}
|
||||
|
||||
return SGQuat::fromRealImag(0, axis);
|
||||
}
|
||||
|
||||
/// Return a quaternion from real and imaginary part
|
||||
static SGQuat fromRealImag(T r, const SGVec3<T>& i)
|
||||
{
|
||||
SGQuat q;
|
||||
q.w() = r;
|
||||
q.x() = i(0);
|
||||
q.y() = i(1);
|
||||
q.z() = i(2);
|
||||
q.x() = i.x();
|
||||
q.y() = i.y();
|
||||
q.z() = i.z();
|
||||
return q;
|
||||
}
|
||||
|
||||
@@ -150,36 +322,36 @@ public:
|
||||
/// write the euler angles into the references
|
||||
void getEulerRad(T& zRad, T& yRad, T& xRad) const
|
||||
{
|
||||
value_type sqrQW = w()*w();
|
||||
value_type sqrQX = x()*x();
|
||||
value_type sqrQY = y()*y();
|
||||
value_type sqrQZ = z()*z();
|
||||
T sqrQW = w()*w();
|
||||
T sqrQX = x()*x();
|
||||
T sqrQY = y()*y();
|
||||
T sqrQZ = z()*z();
|
||||
|
||||
value_type num = 2*(y()*z() + w()*x());
|
||||
value_type den = sqrQW - sqrQX - sqrQY + sqrQZ;
|
||||
if (fabs(den) < SGLimits<value_type>::min() &&
|
||||
fabs(num) < SGLimits<value_type>::min())
|
||||
T num = 2*(y()*z() + w()*x());
|
||||
T den = sqrQW - sqrQX - sqrQY + sqrQZ;
|
||||
if (fabs(den) < SGLimits<T>::min() &&
|
||||
fabs(num) < SGLimits<T>::min())
|
||||
xRad = 0;
|
||||
else
|
||||
xRad = atan2(num, den);
|
||||
|
||||
value_type tmp = 2*(x()*z() - w()*y());
|
||||
T tmp = 2*(x()*z() - w()*y());
|
||||
if (tmp < -1)
|
||||
yRad = 0.5*SGMisc<value_type>::pi();
|
||||
yRad = 0.5*SGMisc<T>::pi();
|
||||
else if (1 < tmp)
|
||||
yRad = -0.5*SGMisc<value_type>::pi();
|
||||
yRad = -0.5*SGMisc<T>::pi();
|
||||
else
|
||||
yRad = -asin(tmp);
|
||||
|
||||
num = 2*(x()*y() + w()*z());
|
||||
den = sqrQW + sqrQX - sqrQY - sqrQZ;
|
||||
if (fabs(den) < SGLimits<value_type>::min() &&
|
||||
fabs(num) < SGLimits<value_type>::min())
|
||||
if (fabs(den) < SGLimits<T>::min() &&
|
||||
fabs(num) < SGLimits<T>::min())
|
||||
zRad = 0;
|
||||
else {
|
||||
value_type psi = atan2(num, den);
|
||||
T psi = atan2(num, den);
|
||||
if (psi < 0)
|
||||
psi += 2*SGMisc<value_type>::pi();
|
||||
psi += 2*SGMisc<T>::pi();
|
||||
zRad = psi;
|
||||
}
|
||||
}
|
||||
@@ -222,67 +394,66 @@ public:
|
||||
|
||||
/// Access by index, the index is unchecked
|
||||
const T& operator()(unsigned i) const
|
||||
{ return _data[i]; }
|
||||
{ return data()[i]; }
|
||||
/// Access by index, the index is unchecked
|
||||
T& operator()(unsigned i)
|
||||
{ return _data[i]; }
|
||||
{ return data()[i]; }
|
||||
|
||||
/// Access raw data by index, the index is unchecked
|
||||
const T& operator[](unsigned i) const
|
||||
{ return _data[i]; }
|
||||
{ return data()[i]; }
|
||||
/// Access raw data by index, the index is unchecked
|
||||
T& operator[](unsigned i)
|
||||
{ return _data[i]; }
|
||||
{ return data()[i]; }
|
||||
|
||||
/// Access the x component
|
||||
const T& x(void) const
|
||||
{ return _data[0]; }
|
||||
{ return data()[0]; }
|
||||
/// Access the x component
|
||||
T& x(void)
|
||||
{ return _data[0]; }
|
||||
{ return data()[0]; }
|
||||
/// Access the y component
|
||||
const T& y(void) const
|
||||
{ return _data[1]; }
|
||||
{ return data()[1]; }
|
||||
/// Access the y component
|
||||
T& y(void)
|
||||
{ return _data[1]; }
|
||||
{ return data()[1]; }
|
||||
/// Access the z component
|
||||
const T& z(void) const
|
||||
{ return _data[2]; }
|
||||
{ return data()[2]; }
|
||||
/// Access the z component
|
||||
T& z(void)
|
||||
{ return _data[2]; }
|
||||
{ return data()[2]; }
|
||||
/// Access the w component
|
||||
const T& w(void) const
|
||||
{ return _data[3]; }
|
||||
{ return data()[3]; }
|
||||
/// Access the w component
|
||||
T& w(void)
|
||||
{ return _data[3]; }
|
||||
{ return data()[3]; }
|
||||
|
||||
/// Get the data pointer, usefull for interfacing with plib's sg*Vec
|
||||
const T* data(void) const
|
||||
{ return _data; }
|
||||
/// Get the data pointer, usefull for interfacing with plib's sg*Vec
|
||||
T* data(void)
|
||||
{ return _data; }
|
||||
/// Get the data pointer
|
||||
using SGQuatStorage<T>::data;
|
||||
|
||||
/// Readonly interface function to ssg's sgQuat/sgdQuat
|
||||
const T (&sg(void) const)[4]
|
||||
{ return _data; }
|
||||
{ return data(); }
|
||||
/// Interface function to ssg's sgQuat/sgdQuat
|
||||
T (&sg(void))[4]
|
||||
{ return _data; }
|
||||
{ return data(); }
|
||||
|
||||
/// Interface function to osg's Quat*
|
||||
using SGQuatStorage<T>::osg;
|
||||
|
||||
/// Inplace addition
|
||||
SGQuat& operator+=(const SGQuat& v)
|
||||
{ _data[0]+=v(0);_data[1]+=v(1);_data[2]+=v(2);_data[3]+=v(3);return *this; }
|
||||
{ data()[0]+=v(0);data()[1]+=v(1);data()[2]+=v(2);data()[3]+=v(3);return *this; }
|
||||
/// Inplace subtraction
|
||||
SGQuat& operator-=(const SGQuat& v)
|
||||
{ _data[0]-=v(0);_data[1]-=v(1);_data[2]-=v(2);_data[3]-=v(3);return *this; }
|
||||
{ data()[0]-=v(0);data()[1]-=v(1);data()[2]-=v(2);data()[3]-=v(3);return *this; }
|
||||
/// Inplace scalar multiplication
|
||||
template<typename S>
|
||||
SGQuat& operator*=(S s)
|
||||
{ _data[0] *= s; _data[1] *= s; _data[2] *= s; _data[3] *= s; return *this; }
|
||||
{ data()[0] *= s; data()[1] *= s; data()[2] *= s; data()[3] *= s; return *this; }
|
||||
/// Inplace scalar multiplication by 1/s
|
||||
template<typename S>
|
||||
SGQuat& operator/=(S s)
|
||||
@@ -294,18 +465,18 @@ public:
|
||||
/// frame rotated with the quaternion
|
||||
SGVec3<T> transform(const SGVec3<T>& v) const
|
||||
{
|
||||
value_type r = 2/dot(*this, *this);
|
||||
T r = 2/dot(*this, *this);
|
||||
SGVec3<T> qimag = imag(*this);
|
||||
value_type qr = real(*this);
|
||||
T qr = real(*this);
|
||||
return (r*qr*qr - 1)*v + (r*dot(qimag, v))*qimag - (r*qr)*cross(qimag, v);
|
||||
}
|
||||
/// Transform a vector from the coordinate frame rotated with the quaternion
|
||||
/// to the current coordinate frame
|
||||
SGVec3<T> backTransform(const SGVec3<T>& v) const
|
||||
{
|
||||
value_type r = 2/dot(*this, *this);
|
||||
T r = 2/dot(*this, *this);
|
||||
SGVec3<T> qimag = imag(*this);
|
||||
value_type qr = real(*this);
|
||||
T qr = real(*this);
|
||||
return (r*qr*qr - 1)*v + (r*dot(qimag, v))*qimag + (r*qr)*cross(qimag, v);
|
||||
}
|
||||
|
||||
@@ -318,7 +489,7 @@ public:
|
||||
|
||||
/// Return the time derivative of the quaternion given the angular velocity
|
||||
SGQuat
|
||||
derivative(const SGVec3<T>& angVel)
|
||||
derivative(const SGVec3<T>& angVel) const
|
||||
{
|
||||
SGQuat deriv;
|
||||
|
||||
@@ -331,8 +502,65 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
/// The actual data
|
||||
T _data[4];
|
||||
|
||||
// Private because it assumes normalized inputs.
|
||||
static SGQuat
|
||||
fromRotateToSmaller90Deg(T cosang,
|
||||
const SGVec3<T>& from, const SGVec3<T>& to)
|
||||
{
|
||||
// In this function we assume that the angle required to rotate from
|
||||
// the vector from to the vector to is <= 90 deg.
|
||||
// That is done so because of possible instabilities when we rotate more
|
||||
// then 90deg.
|
||||
|
||||
// Note that the next comment does actually cover a *more* *general* case
|
||||
// than we need in this function. That shows that this formula is even
|
||||
// valid for rotations up to 180deg.
|
||||
|
||||
// Because of the signs in the axis, it is sufficient to care for angles
|
||||
// in the interval [-pi,pi]. That means that 0.5*angle is in the interval
|
||||
// [-pi/2,pi/2]. But in that range the cosine is allways >= 0.
|
||||
// So we do not need to care for egative roots in the following equation:
|
||||
T cos05ang = sqrt(0.5+0.5*cosang);
|
||||
|
||||
|
||||
// Now our assumption of angles <= 90 deg comes in play.
|
||||
// For that reason, we know that cos05ang is not zero.
|
||||
// It is even more, we can see from the above formula that
|
||||
// sqrt(0.5) < cos05ang.
|
||||
|
||||
|
||||
// Compute the rotation axis, that is
|
||||
// sin(angle)*normalized rotation axis
|
||||
SGVec3<T> axis = cross(to, from);
|
||||
|
||||
// We need sin(0.5*angle)*normalized rotation axis.
|
||||
// So rescale with sin(0.5*x)/sin(x).
|
||||
// To do that we use the equation:
|
||||
// sin(x) = 2*sin(0.5*x)*cos(0.5*x)
|
||||
return SGQuat::fromRealImag( cos05ang, (1/(2*cos05ang))*axis);
|
||||
}
|
||||
|
||||
// Private because it assumes normalized inputs.
|
||||
static SGQuat
|
||||
fromRotateToNorm(const SGVec3<T>& from, const SGVec3<T>& to)
|
||||
{
|
||||
// To avoid instabilities with roundoff, we distinguish between rotations
|
||||
// with more then 90deg and rotations with less than 90deg.
|
||||
|
||||
// Compute the cosine of the angle.
|
||||
T cosang = dot(from, to);
|
||||
|
||||
// For the small ones do direct computation
|
||||
if (T(-0.5) < cosang)
|
||||
return SGQuat::fromRotateToSmaller90Deg(cosang, from, to);
|
||||
|
||||
// For larger rotations. first rotate from to -from.
|
||||
// Past that we will have a smaller angle again.
|
||||
SGQuat q1 = SGQuat::fromChangeSign(from);
|
||||
SGQuat q2 = SGQuat::fromRotateToSmaller90Deg(-cosang, -from, to);
|
||||
return q1*q2;
|
||||
}
|
||||
};
|
||||
|
||||
/// Unary +, do nothing ...
|
||||
@@ -552,10 +780,6 @@ std::basic_ostream<char_type, traits_type>&
|
||||
operator<<(std::basic_ostream<char_type, traits_type>& s, const SGQuat<T>& v)
|
||||
{ return s << "[ " << v(0) << ", " << v(1) << ", " << v(2) << ", " << v(3) << " ]"; }
|
||||
|
||||
/// Two classes doing actually the same on different types
|
||||
typedef SGQuat<float> SGQuatf;
|
||||
typedef SGQuat<double> SGQuatd;
|
||||
|
||||
inline
|
||||
SGQuatf
|
||||
toQuatf(const SGQuatd& v)
|
||||
|
||||
62
simgear/math/SGRay.hxx
Normal file
62
simgear/math/SGRay.hxx
Normal file
@@ -0,0 +1,62 @@
|
||||
// Copyright (C) 2006 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
|
||||
#ifndef SGRay_H
|
||||
#define SGRay_H
|
||||
|
||||
template<typename T>
|
||||
class SGRay {
|
||||
public:
|
||||
SGRay()
|
||||
{ }
|
||||
SGRay(const SGVec3<T>& origin, const SGVec3<T>& dir) :
|
||||
_origin(origin), _direction(dir)
|
||||
{ }
|
||||
|
||||
void set(const SGVec3<T>& origin, const SGVec3<T>& dir)
|
||||
{ _origin = origin; _direction = dir; }
|
||||
|
||||
void setOrigin(const SGVec3<T>& origin)
|
||||
{ _origin = origin; }
|
||||
const SGVec3<T>& getOrigin() const
|
||||
{ return _origin; }
|
||||
|
||||
void setDirection(const SGVec3<T>& direction)
|
||||
{ _direction = direction; }
|
||||
const SGVec3<T>& getDirection() const
|
||||
{ return _direction; }
|
||||
|
||||
SGVec3<T> getNormalizedDirection() const
|
||||
{ return normalize(getDirection()); }
|
||||
|
||||
private:
|
||||
SGVec3<T> _origin;
|
||||
SGVec3<T> _direction;
|
||||
};
|
||||
|
||||
/// Output to an ostream
|
||||
template<typename char_type, typename traits_type, typename T>
|
||||
inline
|
||||
std::basic_ostream<char_type, traits_type>&
|
||||
operator<<(std::basic_ostream<char_type, traits_type>& s,
|
||||
const SGRay<T>& ray)
|
||||
{
|
||||
return s << "ray: origin = " << ray.getOrigin()
|
||||
<< ", direction = " << ray.getDirection();
|
||||
}
|
||||
|
||||
#endif
|
||||
87
simgear/math/SGSphere.hxx
Normal file
87
simgear/math/SGSphere.hxx
Normal file
@@ -0,0 +1,87 @@
|
||||
// Copyright (C) 2006 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
|
||||
#ifndef SGSphere_H
|
||||
#define SGSphere_H
|
||||
|
||||
template<typename T>
|
||||
class SGSphere {
|
||||
public:
|
||||
SGSphere() :
|
||||
_radius(-1)
|
||||
{ }
|
||||
SGSphere(const SGVec3<T>& center, const T& radius) :
|
||||
_center(center),
|
||||
_radius(radius)
|
||||
{ }
|
||||
|
||||
const SGVec3<T>& getCenter() const
|
||||
{ return _center; }
|
||||
void setCenter(const SGVec3<T>& center)
|
||||
{ _center = center; }
|
||||
|
||||
const T& getRadius() const
|
||||
{ return _radius; }
|
||||
void setRadius(const T& radius)
|
||||
{ _radius = radius; }
|
||||
T getRadius2() const
|
||||
{ return _radius*_radius; }
|
||||
|
||||
const bool empty() const
|
||||
{ return !valid(); }
|
||||
|
||||
bool valid() const
|
||||
{ return 0 <= _radius; }
|
||||
|
||||
void clear()
|
||||
{ _radius = -1; }
|
||||
|
||||
void expandBy(const SGVec3<T>& v)
|
||||
{
|
||||
if (empty()) {
|
||||
_center = v;
|
||||
_radius = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
T dist2 = distSqr(_center, v);
|
||||
if (dist2 <= getRadius2())
|
||||
return;
|
||||
|
||||
T dist = sqrt(dist2);
|
||||
T newRadius = T(0.5)*(_radius + dist);
|
||||
_center += ((newRadius - _radius)/dist)*(v - _center);
|
||||
_radius = newRadius;
|
||||
}
|
||||
|
||||
private:
|
||||
SGVec3<T> _center;
|
||||
T _radius;
|
||||
};
|
||||
|
||||
/// Output to an ostream
|
||||
template<typename char_type, typename traits_type, typename T>
|
||||
inline
|
||||
std::basic_ostream<char_type, traits_type>&
|
||||
operator<<(std::basic_ostream<char_type, traits_type>& s,
|
||||
const SGSphere<T>& sphere)
|
||||
{
|
||||
return s << "center = " << sphere.getCenter()
|
||||
<< ", radius = " << sphere.getRadius();
|
||||
}
|
||||
|
||||
#endif
|
||||
101
simgear/math/SGTriangle.hxx
Normal file
101
simgear/math/SGTriangle.hxx
Normal file
@@ -0,0 +1,101 @@
|
||||
// Copyright (C) 2006 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
|
||||
#ifndef SGTriangle_H
|
||||
#define SGTrianlge_H
|
||||
|
||||
template<typename T>
|
||||
class SGTriangle {
|
||||
public:
|
||||
SGTriangle()
|
||||
{ }
|
||||
SGTriangle(const SGVec3<T>& v0, const SGVec3<T>& v1, const SGVec3<T>& v2)
|
||||
{ set(v0, v1, v2); }
|
||||
SGTriangle(const SGVec3<T> v[3])
|
||||
{ set(v); }
|
||||
|
||||
void set(const SGVec3<T>& v0, const SGVec3<T>& v1, const SGVec3<T>& v2)
|
||||
{
|
||||
_v0 = v0;
|
||||
_d[0] = v1 - v0;
|
||||
_d[1] = v2 - v0;
|
||||
}
|
||||
void set(const SGVec3<T> v[3])
|
||||
{
|
||||
_v0 = v[0];
|
||||
_d[0] = v[1] - v[0];
|
||||
_d[1] = v[2] - v[0];
|
||||
}
|
||||
|
||||
SGVec3d getCenter() const
|
||||
{
|
||||
SGBoxd box;
|
||||
box.expandBy(_v0);
|
||||
box.expandBy(_v0 + _d[0]);
|
||||
box.expandBy(_v0 + _d[1]);
|
||||
return box.getCenter();
|
||||
}
|
||||
|
||||
// note that the index is unchecked
|
||||
SGVec3<T> getVertex(unsigned i) const
|
||||
{
|
||||
if (0 < i)
|
||||
return _v0 + _d[i-1];
|
||||
return _v0;
|
||||
}
|
||||
/// return the normalized surface normal
|
||||
SGVec3<T> getNormal() const
|
||||
{ return normalize(cross(_d[0], _d[1])); }
|
||||
|
||||
const SGVec3<T>& getBaseVertex() const
|
||||
{ return _v0; }
|
||||
void setBaseVertex(const SGVec3<T>& v)
|
||||
{ _v0 = v; }
|
||||
const SGVec3<T>& getEdge(unsigned i) const
|
||||
{ return _d[i]; }
|
||||
void setEdge(unsigned i, const SGVec3<T>& d)
|
||||
{ _d[i] = d; }
|
||||
|
||||
// flip the positive side
|
||||
void flip()
|
||||
{
|
||||
SGVec3<T> tmp = _d[0];
|
||||
_d[0] = _d[1];
|
||||
_d[1] = tmp;
|
||||
}
|
||||
private:
|
||||
/// Store one vertex directly, _d is the offset of the other two
|
||||
/// vertices wrt the base vertex
|
||||
/// For fast intersection tests this format prooves usefull. For that same
|
||||
/// purpose also cache the cross product of the _d[i].
|
||||
SGVec3<T> _v0;
|
||||
SGVec3<T> _d[2];
|
||||
};
|
||||
|
||||
/// Output to an ostream
|
||||
template<typename char_type, typename traits_type, typename T>
|
||||
inline
|
||||
std::basic_ostream<char_type, traits_type>&
|
||||
operator<<(std::basic_ostream<char_type, traits_type>& s,
|
||||
const SGTriangle<T>& triangle)
|
||||
{
|
||||
return s << "triangle: v0 = " << triangle.getVertex(0)
|
||||
<< ", v1 = " << triangle.getVertex(1)
|
||||
<< ", v2 = " << triangle.getVertex(2);
|
||||
}
|
||||
|
||||
#endif
|
||||
409
simgear/math/SGVec2.hxx
Normal file
409
simgear/math/SGVec2.hxx
Normal file
@@ -0,0 +1,409 @@
|
||||
// Copyright (C) 2006 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
|
||||
#ifndef SGVec2_H
|
||||
#define SGVec2_H
|
||||
|
||||
#if defined ( __CYGWIN__ )
|
||||
#include <ieeefp.h>
|
||||
#endif
|
||||
|
||||
#include <osg/Vec2f>
|
||||
#include <osg/Vec2d>
|
||||
|
||||
template<typename T>
|
||||
struct SGVec2Storage {
|
||||
/// Readonly raw storage interface
|
||||
const T (&data(void) const)[2]
|
||||
{ return _data; }
|
||||
/// Readonly raw storage interface
|
||||
T (&data(void))[2]
|
||||
{ return _data; }
|
||||
|
||||
void osg() const
|
||||
{ }
|
||||
|
||||
private:
|
||||
T _data[2];
|
||||
};
|
||||
|
||||
template<>
|
||||
struct SGVec2Storage<float> : public osg::Vec2f {
|
||||
/// Access raw data by index, the index is unchecked
|
||||
const float (&data(void) const)[2]
|
||||
{ return osg::Vec2f::_v; }
|
||||
/// Access raw data by index, the index is unchecked
|
||||
float (&data(void))[2]
|
||||
{ return osg::Vec2f::_v; }
|
||||
|
||||
const osg::Vec2f& osg() const
|
||||
{ return *this; }
|
||||
osg::Vec2f& osg()
|
||||
{ return *this; }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct SGVec2Storage<double> : public osg::Vec2d {
|
||||
/// Access raw data by index, the index is unchecked
|
||||
const double (&data(void) const)[2]
|
||||
{ return osg::Vec2d::_v; }
|
||||
/// Access raw data by index, the index is unchecked
|
||||
double (&data(void))[2]
|
||||
{ return osg::Vec2d::_v; }
|
||||
|
||||
const osg::Vec2d& osg() const
|
||||
{ return *this; }
|
||||
osg::Vec2d& osg()
|
||||
{ return *this; }
|
||||
};
|
||||
|
||||
/// 2D Vector Class
|
||||
template<typename T>
|
||||
class SGVec2 : protected SGVec2Storage<T> {
|
||||
public:
|
||||
typedef T value_type;
|
||||
|
||||
/// Default constructor. Does not initialize at all.
|
||||
/// If you need them zero initialized, use SGVec2::zeros()
|
||||
SGVec2(void)
|
||||
{
|
||||
/// Initialize with nans in the debug build, that will guarantee to have
|
||||
/// a fast uninitialized default constructor in the release but shows up
|
||||
/// uninitialized values in the debug build very fast ...
|
||||
#ifndef NDEBUG
|
||||
for (unsigned i = 0; i < 2; ++i)
|
||||
data()[i] = SGLimits<T>::quiet_NaN();
|
||||
#endif
|
||||
}
|
||||
/// Constructor. Initialize by the given values
|
||||
SGVec2(T x, T y)
|
||||
{ data()[0] = x; data()[1] = y; }
|
||||
/// Constructor. Initialize by the content of a plain array,
|
||||
/// make sure it has at least 2 elements
|
||||
explicit SGVec2(const T* d)
|
||||
{ data()[0] = d[0]; data()[1] = d[1]; }
|
||||
explicit SGVec2(const osg::Vec2f& d)
|
||||
{ data()[0] = d[0]; data()[1] = d[1]; }
|
||||
explicit SGVec2(const osg::Vec2d& d)
|
||||
{ data()[0] = d[0]; data()[1] = d[1]; }
|
||||
|
||||
/// Access by index, the index is unchecked
|
||||
const T& operator()(unsigned i) const
|
||||
{ return data()[i]; }
|
||||
/// Access by index, the index is unchecked
|
||||
T& operator()(unsigned i)
|
||||
{ return data()[i]; }
|
||||
|
||||
/// Access raw data by index, the index is unchecked
|
||||
const T& operator[](unsigned i) const
|
||||
{ return data()[i]; }
|
||||
/// Access raw data by index, the index is unchecked
|
||||
T& operator[](unsigned i)
|
||||
{ return data()[i]; }
|
||||
|
||||
/// Access the x component
|
||||
const T& x(void) const
|
||||
{ return data()[0]; }
|
||||
/// Access the x component
|
||||
T& x(void)
|
||||
{ return data()[0]; }
|
||||
/// Access the y component
|
||||
const T& y(void) const
|
||||
{ return data()[1]; }
|
||||
/// Access the y component
|
||||
T& y(void)
|
||||
{ return data()[1]; }
|
||||
|
||||
/// Get the data pointer
|
||||
using SGVec2Storage<T>::data;
|
||||
|
||||
/// Readonly interface function to ssg's sgVec2/sgdVec2
|
||||
const T (&sg(void) const)[2]
|
||||
{ return data(); }
|
||||
/// Interface function to ssg's sgVec2/sgdVec2
|
||||
T (&sg(void))[2]
|
||||
{ return data(); }
|
||||
|
||||
/// Interface function to osg's Vec2*
|
||||
using SGVec2Storage<T>::osg;
|
||||
|
||||
/// Inplace addition
|
||||
SGVec2& operator+=(const SGVec2& v)
|
||||
{ data()[0] += v(0); data()[1] += v(1); return *this; }
|
||||
/// Inplace subtraction
|
||||
SGVec2& operator-=(const SGVec2& v)
|
||||
{ data()[0] -= v(0); data()[1] -= v(1); return *this; }
|
||||
/// Inplace scalar multiplication
|
||||
template<typename S>
|
||||
SGVec2& operator*=(S s)
|
||||
{ data()[0] *= s; data()[1] *= s; return *this; }
|
||||
/// Inplace scalar multiplication by 1/s
|
||||
template<typename S>
|
||||
SGVec2& operator/=(S s)
|
||||
{ return operator*=(1/T(s)); }
|
||||
|
||||
/// Return an all zero vector
|
||||
static SGVec2 zeros(void)
|
||||
{ return SGVec2(0, 0); }
|
||||
/// Return unit vectors
|
||||
static SGVec2 e1(void)
|
||||
{ return SGVec2(1, 0); }
|
||||
static SGVec2 e2(void)
|
||||
{ return SGVec2(0, 1); }
|
||||
};
|
||||
|
||||
/// Unary +, do nothing ...
|
||||
template<typename T>
|
||||
inline
|
||||
const SGVec2<T>&
|
||||
operator+(const SGVec2<T>& v)
|
||||
{ return v; }
|
||||
|
||||
/// Unary -, do nearly nothing
|
||||
template<typename T>
|
||||
inline
|
||||
SGVec2<T>
|
||||
operator-(const SGVec2<T>& v)
|
||||
{ return SGVec2<T>(-v(0), -v(1)); }
|
||||
|
||||
/// Binary +
|
||||
template<typename T>
|
||||
inline
|
||||
SGVec2<T>
|
||||
operator+(const SGVec2<T>& v1, const SGVec2<T>& v2)
|
||||
{ return SGVec2<T>(v1(0)+v2(0), v1(1)+v2(1)); }
|
||||
|
||||
/// Binary -
|
||||
template<typename T>
|
||||
inline
|
||||
SGVec2<T>
|
||||
operator-(const SGVec2<T>& v1, const SGVec2<T>& v2)
|
||||
{ return SGVec2<T>(v1(0)-v2(0), v1(1)-v2(1)); }
|
||||
|
||||
/// Scalar multiplication
|
||||
template<typename S, typename T>
|
||||
inline
|
||||
SGVec2<T>
|
||||
operator*(S s, const SGVec2<T>& v)
|
||||
{ return SGVec2<T>(s*v(0), s*v(1)); }
|
||||
|
||||
/// Scalar multiplication
|
||||
template<typename S, typename T>
|
||||
inline
|
||||
SGVec2<T>
|
||||
operator*(const SGVec2<T>& v, S s)
|
||||
{ return SGVec2<T>(s*v(0), s*v(1)); }
|
||||
|
||||
/// multiplication as a multiplicator, that is assume that the first vector
|
||||
/// represents a 2x2 diagonal matrix with the diagonal elements in the vector.
|
||||
/// Then the result is the product of that matrix times the second vector.
|
||||
template<typename T>
|
||||
inline
|
||||
SGVec2<T>
|
||||
mult(const SGVec2<T>& v1, const SGVec2<T>& v2)
|
||||
{ return SGVec2<T>(v1(0)*v2(0), v1(1)*v2(1)); }
|
||||
|
||||
/// component wise min
|
||||
template<typename T>
|
||||
inline
|
||||
SGVec2<T>
|
||||
min(const SGVec2<T>& v1, const SGVec2<T>& v2)
|
||||
{return SGVec2<T>(SGMisc<T>::min(v1(0), v2(0)), SGMisc<T>::min(v1(1), v2(1)));}
|
||||
template<typename S, typename T>
|
||||
inline
|
||||
SGVec2<T>
|
||||
min(const SGVec2<T>& v, S s)
|
||||
{ return SGVec2<T>(SGMisc<T>::min(s, v(0)), SGMisc<T>::min(s, v(1))); }
|
||||
template<typename S, typename T>
|
||||
inline
|
||||
SGVec2<T>
|
||||
min(S s, const SGVec2<T>& v)
|
||||
{ return SGVec2<T>(SGMisc<T>::min(s, v(0)), SGMisc<T>::min(s, v(1))); }
|
||||
|
||||
/// component wise max
|
||||
template<typename T>
|
||||
inline
|
||||
SGVec2<T>
|
||||
max(const SGVec2<T>& v1, const SGVec2<T>& v2)
|
||||
{return SGVec2<T>(SGMisc<T>::max(v1(0), v2(0)), SGMisc<T>::max(v1(1), v2(1)));}
|
||||
template<typename S, typename T>
|
||||
inline
|
||||
SGVec2<T>
|
||||
max(const SGVec2<T>& v, S s)
|
||||
{ return SGVec2<T>(SGMisc<T>::max(s, v(0)), SGMisc<T>::max(s, v(1))); }
|
||||
template<typename S, typename T>
|
||||
inline
|
||||
SGVec2<T>
|
||||
max(S s, const SGVec2<T>& v)
|
||||
{ return SGVec2<T>(SGMisc<T>::max(s, v(0)), SGMisc<T>::max(s, v(1))); }
|
||||
|
||||
/// Scalar dot product
|
||||
template<typename T>
|
||||
inline
|
||||
T
|
||||
dot(const SGVec2<T>& v1, const SGVec2<T>& v2)
|
||||
{ return v1(0)*v2(0) + v1(1)*v2(1); }
|
||||
|
||||
/// The euclidean norm of the vector, that is what most people call length
|
||||
template<typename T>
|
||||
inline
|
||||
T
|
||||
norm(const SGVec2<T>& v)
|
||||
{ return sqrt(dot(v, v)); }
|
||||
|
||||
/// The euclidean norm of the vector, that is what most people call length
|
||||
template<typename T>
|
||||
inline
|
||||
T
|
||||
length(const SGVec2<T>& v)
|
||||
{ return sqrt(dot(v, v)); }
|
||||
|
||||
/// The 1-norm of the vector, this one is the fastest length function we
|
||||
/// can implement on modern cpu's
|
||||
template<typename T>
|
||||
inline
|
||||
T
|
||||
norm1(const SGVec2<T>& v)
|
||||
{ return fabs(v(0)) + fabs(v(1)); }
|
||||
|
||||
/// The inf-norm of the vector
|
||||
template<typename T>
|
||||
inline
|
||||
T
|
||||
normI(const SGVec2<T>& v)
|
||||
{ return SGMisc<T>::max(fabs(v(0)), fabs(v(1))); }
|
||||
|
||||
/// The euclidean norm of the vector, that is what most people call length
|
||||
template<typename T>
|
||||
inline
|
||||
SGVec2<T>
|
||||
normalize(const SGVec2<T>& v)
|
||||
{ return (1/norm(v))*v; }
|
||||
|
||||
/// Return true if exactly the same
|
||||
template<typename T>
|
||||
inline
|
||||
bool
|
||||
operator==(const SGVec2<T>& v1, const SGVec2<T>& v2)
|
||||
{ return v1(0) == v2(0) && v1(1) == v2(1); }
|
||||
|
||||
/// Return true if not exactly the same
|
||||
template<typename T>
|
||||
inline
|
||||
bool
|
||||
operator!=(const SGVec2<T>& v1, const SGVec2<T>& v2)
|
||||
{ return ! (v1 == v2); }
|
||||
|
||||
/// Return true if smaller, good for putting that into a std::map
|
||||
template<typename T>
|
||||
inline
|
||||
bool
|
||||
operator<(const SGVec2<T>& v1, const SGVec2<T>& v2)
|
||||
{
|
||||
if (v1(0) < v2(0)) return true;
|
||||
else if (v2(0) < v1(0)) return false;
|
||||
else return (v1(1) < v2(1));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline
|
||||
bool
|
||||
operator<=(const SGVec2<T>& v1, const SGVec2<T>& v2)
|
||||
{
|
||||
if (v1(0) < v2(0)) return true;
|
||||
else if (v2(0) < v1(0)) return false;
|
||||
else return (v1(1) <= v2(1));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline
|
||||
bool
|
||||
operator>(const SGVec2<T>& v1, const SGVec2<T>& v2)
|
||||
{ return operator<(v2, v1); }
|
||||
|
||||
template<typename T>
|
||||
inline
|
||||
bool
|
||||
operator>=(const SGVec2<T>& v1, const SGVec2<T>& v2)
|
||||
{ return operator<=(v2, v1); }
|
||||
|
||||
/// Return true if equal to the relative tolerance tol
|
||||
template<typename T>
|
||||
inline
|
||||
bool
|
||||
equivalent(const SGVec2<T>& v1, const SGVec2<T>& v2, T rtol, T atol)
|
||||
{ return norm1(v1 - v2) < rtol*(norm1(v1) + norm1(v2)) + atol; }
|
||||
|
||||
/// Return true if equal to the relative tolerance tol
|
||||
template<typename T>
|
||||
inline
|
||||
bool
|
||||
equivalent(const SGVec2<T>& v1, const SGVec2<T>& v2, T rtol)
|
||||
{ return norm1(v1 - v2) < rtol*(norm1(v1) + norm1(v2)); }
|
||||
|
||||
/// Return true if about equal to roundoff of the underlying type
|
||||
template<typename T>
|
||||
inline
|
||||
bool
|
||||
equivalent(const SGVec2<T>& v1, const SGVec2<T>& v2)
|
||||
{
|
||||
T tol = 100*SGLimits<T>::epsilon();
|
||||
return equivalent(v1, v2, tol, tol);
|
||||
}
|
||||
|
||||
/// The euclidean distance of the two vectors
|
||||
template<typename T>
|
||||
inline
|
||||
T
|
||||
dist(const SGVec2<T>& v1, const SGVec2<T>& v2)
|
||||
{ return norm(v1 - v2); }
|
||||
|
||||
/// The squared euclidean distance of the two vectors
|
||||
template<typename T>
|
||||
inline
|
||||
T
|
||||
distSqr(const SGVec2<T>& v1, const SGVec2<T>& v2)
|
||||
{ SGVec2<T> tmp = v1 - v2; return dot(tmp, tmp); }
|
||||
|
||||
#ifndef NDEBUG
|
||||
template<typename T>
|
||||
inline
|
||||
bool
|
||||
isNaN(const SGVec2<T>& v)
|
||||
{
|
||||
return SGMisc<T>::isNaN(v(0)) || SGMisc<T>::isNaN(v(1));
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Output to an ostream
|
||||
template<typename char_type, typename traits_type, typename T>
|
||||
inline
|
||||
std::basic_ostream<char_type, traits_type>&
|
||||
operator<<(std::basic_ostream<char_type, traits_type>& s, const SGVec2<T>& v)
|
||||
{ return s << "[ " << v(0) << ", " << v(1) << " ]"; }
|
||||
|
||||
inline
|
||||
SGVec2f
|
||||
toVec2f(const SGVec2d& v)
|
||||
{ return SGVec2f((float)v(0), (float)v(1)); }
|
||||
|
||||
inline
|
||||
SGVec2d
|
||||
toVec2d(const SGVec2f& v)
|
||||
{ return SGVec2d(v(0), v(1)); }
|
||||
|
||||
#endif
|
||||
@@ -18,9 +18,58 @@
|
||||
#ifndef SGVec3_H
|
||||
#define SGVec3_H
|
||||
|
||||
#include <osg/Vec3f>
|
||||
#include <osg/Vec3d>
|
||||
|
||||
template<typename T>
|
||||
struct SGVec3Storage {
|
||||
/// Readonly raw storage interface
|
||||
const T (&data(void) const)[3]
|
||||
{ return _data; }
|
||||
/// Readonly raw storage interface
|
||||
T (&data(void))[3]
|
||||
{ return _data; }
|
||||
|
||||
void osg() const
|
||||
{ }
|
||||
|
||||
private:
|
||||
T _data[3];
|
||||
};
|
||||
|
||||
template<>
|
||||
struct SGVec3Storage<float> : public osg::Vec3f {
|
||||
/// Access raw data by index, the index is unchecked
|
||||
const float (&data(void) const)[3]
|
||||
{ return osg::Vec3f::_v; }
|
||||
/// Access raw data by index, the index is unchecked
|
||||
float (&data(void))[3]
|
||||
{ return osg::Vec3f::_v; }
|
||||
|
||||
const osg::Vec3f& osg() const
|
||||
{ return *this; }
|
||||
osg::Vec3f& osg()
|
||||
{ return *this; }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct SGVec3Storage<double> : public osg::Vec3d {
|
||||
/// Access raw data by index, the index is unchecked
|
||||
const double (&data(void) const)[3]
|
||||
{ return osg::Vec3d::_v; }
|
||||
/// Access raw data by index, the index is unchecked
|
||||
double (&data(void))[3]
|
||||
{ return osg::Vec3d::_v; }
|
||||
|
||||
const osg::Vec3d& osg() const
|
||||
{ return *this; }
|
||||
osg::Vec3d& osg()
|
||||
{ return *this; }
|
||||
};
|
||||
|
||||
/// 3D Vector Class
|
||||
template<typename T>
|
||||
class SGVec3 {
|
||||
class SGVec3 : protected SGVec3Storage<T> {
|
||||
public:
|
||||
typedef T value_type;
|
||||
|
||||
@@ -33,82 +82,79 @@ public:
|
||||
/// uninitialized values in the debug build very fast ...
|
||||
#ifndef NDEBUG
|
||||
for (unsigned i = 0; i < 3; ++i)
|
||||
_data[i] = SGLimits<T>::quiet_NaN();
|
||||
data()[i] = SGLimits<T>::quiet_NaN();
|
||||
#endif
|
||||
}
|
||||
/// Constructor. Initialize by the given values
|
||||
SGVec3(T x, T y, T z)
|
||||
{ _data[0] = x; _data[1] = y; _data[2] = z; }
|
||||
{ data()[0] = x; data()[1] = y; data()[2] = z; }
|
||||
/// Constructor. Initialize by the content of a plain array,
|
||||
/// make sure it has at least 3 elements
|
||||
explicit SGVec3(const T* data)
|
||||
{ _data[0] = data[0]; _data[1] = data[1]; _data[2] = data[2]; }
|
||||
/// Constructor. Initialize by a geodetic coordinate
|
||||
/// Note that this conversion is relatively expensive to compute
|
||||
SGVec3(const SGGeod& geod)
|
||||
{ SGGeodesy::SGGeodToCart(geod, *this); }
|
||||
/// Constructor. Initialize by a geocentric coordinate
|
||||
/// Note that this conversion is relatively expensive to compute
|
||||
SGVec3(const SGGeoc& geoc)
|
||||
{ SGGeodesy::SGGeocToCart(geoc, *this); }
|
||||
explicit SGVec3(const T* d)
|
||||
{ data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; }
|
||||
explicit SGVec3(const osg::Vec3f& d)
|
||||
{ data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; }
|
||||
explicit SGVec3(const osg::Vec3d& d)
|
||||
{ data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; }
|
||||
explicit SGVec3(const SGVec2<T>& v2, const T& v3 = 0)
|
||||
{ data()[0] = v2[0]; data()[1] = v2[1]; data()[2] = v3; }
|
||||
|
||||
/// Access by index, the index is unchecked
|
||||
const T& operator()(unsigned i) const
|
||||
{ return _data[i]; }
|
||||
{ return data()[i]; }
|
||||
/// Access by index, the index is unchecked
|
||||
T& operator()(unsigned i)
|
||||
{ return _data[i]; }
|
||||
{ return data()[i]; }
|
||||
|
||||
/// Access raw data by index, the index is unchecked
|
||||
const T& operator[](unsigned i) const
|
||||
{ return _data[i]; }
|
||||
{ return data()[i]; }
|
||||
/// Access raw data by index, the index is unchecked
|
||||
T& operator[](unsigned i)
|
||||
{ return _data[i]; }
|
||||
{ return data()[i]; }
|
||||
|
||||
/// Access the x component
|
||||
const T& x(void) const
|
||||
{ return _data[0]; }
|
||||
{ return data()[0]; }
|
||||
/// Access the x component
|
||||
T& x(void)
|
||||
{ return _data[0]; }
|
||||
{ return data()[0]; }
|
||||
/// Access the y component
|
||||
const T& y(void) const
|
||||
{ return _data[1]; }
|
||||
{ return data()[1]; }
|
||||
/// Access the y component
|
||||
T& y(void)
|
||||
{ return _data[1]; }
|
||||
{ return data()[1]; }
|
||||
/// Access the z component
|
||||
const T& z(void) const
|
||||
{ return _data[2]; }
|
||||
{ return data()[2]; }
|
||||
/// Access the z component
|
||||
T& z(void)
|
||||
{ return _data[2]; }
|
||||
{ return data()[2]; }
|
||||
|
||||
/// Get the data pointer
|
||||
const T* data(void) const
|
||||
{ return _data; }
|
||||
/// Get the data pointer
|
||||
T* data(void)
|
||||
{ return _data; }
|
||||
using SGVec3Storage<T>::data;
|
||||
|
||||
/// Readonly interface function to ssg's sgVec3/sgdVec3
|
||||
const T (&sg(void) const)[3]
|
||||
{ return _data; }
|
||||
{ return data(); }
|
||||
/// Interface function to ssg's sgVec3/sgdVec3
|
||||
T (&sg(void))[3]
|
||||
{ return _data; }
|
||||
{ return data(); }
|
||||
|
||||
/// Interface function to osg's Vec3*
|
||||
using SGVec3Storage<T>::osg;
|
||||
|
||||
/// Inplace addition
|
||||
SGVec3& operator+=(const SGVec3& v)
|
||||
{ _data[0] += v(0); _data[1] += v(1); _data[2] += v(2); return *this; }
|
||||
{ data()[0] += v(0); data()[1] += v(1); data()[2] += v(2); return *this; }
|
||||
/// Inplace subtraction
|
||||
SGVec3& operator-=(const SGVec3& v)
|
||||
{ _data[0] -= v(0); _data[1] -= v(1); _data[2] -= v(2); return *this; }
|
||||
{ data()[0] -= v(0); data()[1] -= v(1); data()[2] -= v(2); return *this; }
|
||||
/// Inplace scalar multiplication
|
||||
template<typename S>
|
||||
SGVec3& operator*=(S s)
|
||||
{ _data[0] *= s; _data[1] *= s; _data[2] *= s; return *this; }
|
||||
{ data()[0] *= s; data()[1] *= s; data()[2] *= s; return *this; }
|
||||
/// Inplace scalar multiplication by 1/s
|
||||
template<typename S>
|
||||
SGVec3& operator/=(S s)
|
||||
@@ -125,11 +171,54 @@ public:
|
||||
static SGVec3 e3(void)
|
||||
{ return SGVec3(0, 0, 1); }
|
||||
|
||||
private:
|
||||
/// The actual data
|
||||
T _data[3];
|
||||
/// Constructor. Initialize by a geodetic coordinate
|
||||
/// Note that this conversion is relatively expensive to compute
|
||||
static SGVec3 fromGeod(const SGGeod& geod);
|
||||
/// Constructor. Initialize by a geocentric coordinate
|
||||
/// Note that this conversion is relatively expensive to compute
|
||||
static SGVec3 fromGeoc(const SGGeoc& geoc);
|
||||
};
|
||||
|
||||
template<>
|
||||
inline
|
||||
SGVec3<double>
|
||||
SGVec3<double>::fromGeod(const SGGeod& geod)
|
||||
{
|
||||
SGVec3<double> cart;
|
||||
SGGeodesy::SGGeodToCart(geod, cart);
|
||||
return cart;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline
|
||||
SGVec3<float>
|
||||
SGVec3<float>::fromGeod(const SGGeod& geod)
|
||||
{
|
||||
SGVec3<double> cart;
|
||||
SGGeodesy::SGGeodToCart(geod, cart);
|
||||
return SGVec3<float>(cart(0), cart(1), cart(2));
|
||||
}
|
||||
|
||||
template<>
|
||||
inline
|
||||
SGVec3<double>
|
||||
SGVec3<double>::fromGeoc(const SGGeoc& geoc)
|
||||
{
|
||||
SGVec3<double> cart;
|
||||
SGGeodesy::SGGeocToCart(geoc, cart);
|
||||
return cart;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline
|
||||
SGVec3<float>
|
||||
SGVec3<float>::fromGeoc(const SGGeoc& geoc)
|
||||
{
|
||||
SGVec3<double> cart;
|
||||
SGGeodesy::SGGeocToCart(geoc, cart);
|
||||
return SGVec3<float>(cart(0), cart(1), cart(2));
|
||||
}
|
||||
|
||||
/// Unary +, do nothing ...
|
||||
template<typename T>
|
||||
inline
|
||||
@@ -172,6 +261,73 @@ SGVec3<T>
|
||||
operator*(const SGVec3<T>& v, S s)
|
||||
{ return SGVec3<T>(s*v(0), s*v(1), s*v(2)); }
|
||||
|
||||
/// multiplication as a multiplicator, that is assume that the first vector
|
||||
/// represents a 3x3 diagonal matrix with the diagonal elements in the vector.
|
||||
/// Then the result is the product of that matrix times the second vector.
|
||||
template<typename T>
|
||||
inline
|
||||
SGVec3<T>
|
||||
mult(const SGVec3<T>& v1, const SGVec3<T>& v2)
|
||||
{ return SGVec3<T>(v1(0)*v2(0), v1(1)*v2(1), v1(2)*v2(2)); }
|
||||
|
||||
/// component wise min
|
||||
template<typename T>
|
||||
inline
|
||||
SGVec3<T>
|
||||
min(const SGVec3<T>& v1, const SGVec3<T>& v2)
|
||||
{
|
||||
return SGVec3<T>(SGMisc<T>::min(v1(0), v2(0)),
|
||||
SGMisc<T>::min(v1(1), v2(1)),
|
||||
SGMisc<T>::min(v1(2), v2(2)));
|
||||
}
|
||||
template<typename S, typename T>
|
||||
inline
|
||||
SGVec3<T>
|
||||
min(const SGVec3<T>& v, S s)
|
||||
{
|
||||
return SGVec3<T>(SGMisc<T>::min(s, v(0)),
|
||||
SGMisc<T>::min(s, v(1)),
|
||||
SGMisc<T>::min(s, v(2)));
|
||||
}
|
||||
template<typename S, typename T>
|
||||
inline
|
||||
SGVec3<T>
|
||||
min(S s, const SGVec3<T>& v)
|
||||
{
|
||||
return SGVec3<T>(SGMisc<T>::min(s, v(0)),
|
||||
SGMisc<T>::min(s, v(1)),
|
||||
SGMisc<T>::min(s, v(2)));
|
||||
}
|
||||
|
||||
/// component wise max
|
||||
template<typename T>
|
||||
inline
|
||||
SGVec3<T>
|
||||
max(const SGVec3<T>& v1, const SGVec3<T>& v2)
|
||||
{
|
||||
return SGVec3<T>(SGMisc<T>::max(v1(0), v2(0)),
|
||||
SGMisc<T>::max(v1(1), v2(1)),
|
||||
SGMisc<T>::max(v1(2), v2(2)));
|
||||
}
|
||||
template<typename S, typename T>
|
||||
inline
|
||||
SGVec3<T>
|
||||
max(const SGVec3<T>& v, S s)
|
||||
{
|
||||
return SGVec3<T>(SGMisc<T>::max(s, v(0)),
|
||||
SGMisc<T>::max(s, v(1)),
|
||||
SGMisc<T>::max(s, v(2)));
|
||||
}
|
||||
template<typename S, typename T>
|
||||
inline
|
||||
SGVec3<T>
|
||||
max(S s, const SGVec3<T>& v)
|
||||
{
|
||||
return SGVec3<T>(SGMisc<T>::max(s, v(0)),
|
||||
SGMisc<T>::max(s, v(1)),
|
||||
SGMisc<T>::max(s, v(2)));
|
||||
}
|
||||
|
||||
/// Scalar dot product
|
||||
template<typename T>
|
||||
inline
|
||||
@@ -201,6 +357,13 @@ T
|
||||
norm1(const SGVec3<T>& v)
|
||||
{ return fabs(v(0)) + fabs(v(1)) + fabs(v(2)); }
|
||||
|
||||
/// The inf-norm of the vector
|
||||
template<typename T>
|
||||
inline
|
||||
T
|
||||
normI(const SGVec3<T>& v)
|
||||
{ return SGMisc<T>::max(fabs(v(0)), fabs(v(1)), fabs(v(2))); }
|
||||
|
||||
/// Vector cross product
|
||||
template<typename T>
|
||||
inline
|
||||
@@ -212,6 +375,31 @@ cross(const SGVec3<T>& v1, const SGVec3<T>& v2)
|
||||
v1(0)*v2(1) - v1(1)*v2(0));
|
||||
}
|
||||
|
||||
/// return any normalized vector perpendicular to v
|
||||
template<typename T>
|
||||
inline
|
||||
SGVec3<T>
|
||||
perpendicular(const SGVec3<T>& v)
|
||||
{
|
||||
T absv1 = fabs(v(0));
|
||||
T absv2 = fabs(v(1));
|
||||
T absv3 = fabs(v(2));
|
||||
|
||||
if (absv2 < absv1 && absv3 < absv1) {
|
||||
T quot = v(1)/v(0);
|
||||
return (1/sqrt(1+quot*quot))*SGVec3<T>(quot, -1, 0);
|
||||
} else if (absv3 < absv2) {
|
||||
T quot = v(2)/v(1);
|
||||
return (1/sqrt(1+quot*quot))*SGVec3<T>(0, quot, -1);
|
||||
} else if (SGLimits<T>::min() < absv3) {
|
||||
T quot = v(0)/v(2);
|
||||
return (1/sqrt(1+quot*quot))*SGVec3<T>(-1, 0, quot);
|
||||
} else {
|
||||
// the all zero case ...
|
||||
return SGVec3<T>(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/// The euclidean norm of the vector, that is what most people call length
|
||||
template<typename T>
|
||||
inline
|
||||
@@ -233,6 +421,43 @@ bool
|
||||
operator!=(const SGVec3<T>& v1, const SGVec3<T>& v2)
|
||||
{ return ! (v1 == v2); }
|
||||
|
||||
/// Return true if smaller, good for putting that into a std::map
|
||||
template<typename T>
|
||||
inline
|
||||
bool
|
||||
operator<(const SGVec3<T>& v1, const SGVec3<T>& v2)
|
||||
{
|
||||
if (v1(0) < v2(0)) return true;
|
||||
else if (v2(0) < v1(0)) return false;
|
||||
else if (v1(1) < v2(1)) return true;
|
||||
else if (v2(1) < v1(1)) return false;
|
||||
else return (v1(2) < v2(2));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline
|
||||
bool
|
||||
operator<=(const SGVec3<T>& v1, const SGVec3<T>& v2)
|
||||
{
|
||||
if (v1(0) < v2(0)) return true;
|
||||
else if (v2(0) < v1(0)) return false;
|
||||
else if (v1(1) < v2(1)) return true;
|
||||
else if (v2(1) < v1(1)) return false;
|
||||
else return (v1(2) <= v2(2));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline
|
||||
bool
|
||||
operator>(const SGVec3<T>& v1, const SGVec3<T>& v2)
|
||||
{ return operator<(v2, v1); }
|
||||
|
||||
template<typename T>
|
||||
inline
|
||||
bool
|
||||
operator>=(const SGVec3<T>& v1, const SGVec3<T>& v2)
|
||||
{ return operator<=(v2, v1); }
|
||||
|
||||
/// Return true if equal to the relative tolerance tol
|
||||
template<typename T>
|
||||
inline
|
||||
@@ -257,6 +482,20 @@ equivalent(const SGVec3<T>& v1, const SGVec3<T>& v2)
|
||||
return equivalent(v1, v2, tol, tol);
|
||||
}
|
||||
|
||||
/// The euclidean distance of the two vectors
|
||||
template<typename T>
|
||||
inline
|
||||
T
|
||||
dist(const SGVec3<T>& v1, const SGVec3<T>& v2)
|
||||
{ return norm(v1 - v2); }
|
||||
|
||||
/// The squared euclidean distance of the two vectors
|
||||
template<typename T>
|
||||
inline
|
||||
T
|
||||
distSqr(const SGVec3<T>& v1, const SGVec3<T>& v2)
|
||||
{ SGVec3<T> tmp = v1 - v2; return dot(tmp, tmp); }
|
||||
|
||||
#ifndef NDEBUG
|
||||
template<typename T>
|
||||
inline
|
||||
@@ -275,10 +514,6 @@ std::basic_ostream<char_type, traits_type>&
|
||||
operator<<(std::basic_ostream<char_type, traits_type>& s, const SGVec3<T>& v)
|
||||
{ return s << "[ " << v(0) << ", " << v(1) << ", " << v(2) << " ]"; }
|
||||
|
||||
/// Two classes doing actually the same on different types
|
||||
typedef SGVec3<float> SGVec3f;
|
||||
typedef SGVec3<double> SGVec3d;
|
||||
|
||||
inline
|
||||
SGVec3f
|
||||
toVec3f(const SGVec3d& v)
|
||||
|
||||
@@ -18,9 +18,58 @@
|
||||
#ifndef SGVec4_H
|
||||
#define SGVec4_H
|
||||
|
||||
#include <osg/Vec4f>
|
||||
#include <osg/Vec4d>
|
||||
|
||||
template<typename T>
|
||||
struct SGVec4Storage {
|
||||
/// Readonly raw storage interface
|
||||
const T (&data(void) const)[4]
|
||||
{ return _data; }
|
||||
/// Readonly raw storage interface
|
||||
T (&data(void))[4]
|
||||
{ return _data; }
|
||||
|
||||
void osg() const
|
||||
{ }
|
||||
|
||||
private:
|
||||
T _data[4];
|
||||
};
|
||||
|
||||
template<>
|
||||
struct SGVec4Storage<float> : public osg::Vec4f {
|
||||
/// Access raw data by index, the index is unchecked
|
||||
const float (&data(void) const)[4]
|
||||
{ return osg::Vec4f::_v; }
|
||||
/// Access raw data by index, the index is unchecked
|
||||
float (&data(void))[4]
|
||||
{ return osg::Vec4f::_v; }
|
||||
|
||||
const osg::Vec4f& osg() const
|
||||
{ return *this; }
|
||||
osg::Vec4f& osg()
|
||||
{ return *this; }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct SGVec4Storage<double> : public osg::Vec4d {
|
||||
/// Access raw data by index, the index is unchecked
|
||||
const double (&data(void) const)[4]
|
||||
{ return osg::Vec4d::_v; }
|
||||
/// Access raw data by index, the index is unchecked
|
||||
double (&data(void))[4]
|
||||
{ return osg::Vec4d::_v; }
|
||||
|
||||
const osg::Vec4d& osg() const
|
||||
{ return *this; }
|
||||
osg::Vec4d& osg()
|
||||
{ return *this; }
|
||||
};
|
||||
|
||||
/// 4D Vector Class
|
||||
template<typename T>
|
||||
class SGVec4 {
|
||||
class SGVec4 : protected SGVec4Storage<T> {
|
||||
public:
|
||||
typedef T value_type;
|
||||
|
||||
@@ -33,82 +82,86 @@ public:
|
||||
/// uninitialized values in the debug build very fast ...
|
||||
#ifndef NDEBUG
|
||||
for (unsigned i = 0; i < 4; ++i)
|
||||
_data[i] = SGLimits<T>::quiet_NaN();
|
||||
data()[i] = SGLimits<T>::quiet_NaN();
|
||||
#endif
|
||||
}
|
||||
/// Constructor. Initialize by the given values
|
||||
SGVec4(T x, T y, T z, T w)
|
||||
{ _data[0] = x; _data[1] = y; _data[2] = z; _data[3] = w; }
|
||||
{ data()[0] = x; data()[1] = y; data()[2] = z; data()[3] = w; }
|
||||
/// Constructor. Initialize by the content of a plain array,
|
||||
/// make sure it has at least 3 elements
|
||||
explicit SGVec4(const T* d)
|
||||
{ _data[0] = d[0]; _data[1] = d[1]; _data[2] = d[2]; _data[3] = d[3]; }
|
||||
{ data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; data()[3] = d[3]; }
|
||||
explicit SGVec4(const osg::Vec4f& d)
|
||||
{ data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; data()[3] = d[3]; }
|
||||
explicit SGVec4(const osg::Vec4d& d)
|
||||
{ data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; data()[3] = d[3]; }
|
||||
explicit SGVec4(const SGVec3<T>& v3, const T& v4 = 0)
|
||||
{ data()[0] = v3[0]; data()[1] = v3[1]; data()[2] = v3[2]; data()[3] = v4; }
|
||||
|
||||
|
||||
/// Access by index, the index is unchecked
|
||||
const T& operator()(unsigned i) const
|
||||
{ return _data[i]; }
|
||||
{ return data()[i]; }
|
||||
/// Access by index, the index is unchecked
|
||||
T& operator()(unsigned i)
|
||||
{ return _data[i]; }
|
||||
{ return data()[i]; }
|
||||
|
||||
/// Access raw data by index, the index is unchecked
|
||||
const T& operator[](unsigned i) const
|
||||
{ return _data[i]; }
|
||||
{ return data()[i]; }
|
||||
/// Access raw data by index, the index is unchecked
|
||||
T& operator[](unsigned i)
|
||||
{ return _data[i]; }
|
||||
{ return data()[i]; }
|
||||
|
||||
/// Access the x component
|
||||
const T& x(void) const
|
||||
{ return _data[0]; }
|
||||
{ return data()[0]; }
|
||||
/// Access the x component
|
||||
T& x(void)
|
||||
{ return _data[0]; }
|
||||
{ return data()[0]; }
|
||||
/// Access the y component
|
||||
const T& y(void) const
|
||||
{ return _data[1]; }
|
||||
{ return data()[1]; }
|
||||
/// Access the y component
|
||||
T& y(void)
|
||||
{ return _data[1]; }
|
||||
{ return data()[1]; }
|
||||
/// Access the z component
|
||||
const T& z(void) const
|
||||
{ return _data[2]; }
|
||||
{ return data()[2]; }
|
||||
/// Access the z component
|
||||
T& z(void)
|
||||
{ return _data[2]; }
|
||||
{ return data()[2]; }
|
||||
/// Access the x component
|
||||
const T& w(void) const
|
||||
{ return _data[3]; }
|
||||
{ return data()[3]; }
|
||||
/// Access the x component
|
||||
T& w(void)
|
||||
{ return _data[3]; }
|
||||
{ return data()[3]; }
|
||||
|
||||
/// Get the data pointer
|
||||
using SGVec4Storage<T>::data;
|
||||
|
||||
/// Get the data pointer, usefull for interfacing with plib's sg*Vec
|
||||
const T* data(void) const
|
||||
{ return _data; }
|
||||
/// Get the data pointer, usefull for interfacing with plib's sg*Vec
|
||||
T* data(void)
|
||||
{ return _data; }
|
||||
|
||||
/// Readonly interface function to ssg's sgVec3/sgdVec3
|
||||
/// Readonly interface function to ssg's sgVec4/sgdVec4
|
||||
const T (&sg(void) const)[4]
|
||||
{ return _data; }
|
||||
/// Interface function to ssg's sgVec3/sgdVec3
|
||||
{ return data(); }
|
||||
/// Interface function to ssg's sgVec4/sgdVec4
|
||||
T (&sg(void))[4]
|
||||
{ return _data; }
|
||||
{ return data(); }
|
||||
|
||||
/// Interface function to osg's Vec4*
|
||||
using SGVec4Storage<T>::osg;
|
||||
|
||||
/// Inplace addition
|
||||
SGVec4& operator+=(const SGVec4& v)
|
||||
{ _data[0]+=v(0);_data[1]+=v(1);_data[2]+=v(2);_data[3]+=v(3);return *this; }
|
||||
{ data()[0]+=v(0);data()[1]+=v(1);data()[2]+=v(2);data()[3]+=v(3);return *this; }
|
||||
/// Inplace subtraction
|
||||
SGVec4& operator-=(const SGVec4& v)
|
||||
{ _data[0]-=v(0);_data[1]-=v(1);_data[2]-=v(2);_data[3]-=v(3);return *this; }
|
||||
{ data()[0]-=v(0);data()[1]-=v(1);data()[2]-=v(2);data()[3]-=v(3);return *this; }
|
||||
/// Inplace scalar multiplication
|
||||
template<typename S>
|
||||
SGVec4& operator*=(S s)
|
||||
{ _data[0] *= s; _data[1] *= s; _data[2] *= s; _data[3] *= s; return *this; }
|
||||
{ data()[0] *= s; data()[1] *= s; data()[2] *= s; data()[3] *= s; return *this; }
|
||||
/// Inplace scalar multiplication by 1/s
|
||||
template<typename S>
|
||||
SGVec4& operator/=(S s)
|
||||
@@ -126,10 +179,6 @@ public:
|
||||
{ return SGVec4(0, 0, 1, 0); }
|
||||
static SGVec4 e4(void)
|
||||
{ return SGVec4(0, 0, 0, 1); }
|
||||
|
||||
private:
|
||||
/// The actual data
|
||||
T _data[4];
|
||||
};
|
||||
|
||||
/// Unary +, do nothing ...
|
||||
@@ -174,6 +223,79 @@ SGVec4<T>
|
||||
operator*(const SGVec4<T>& v, S s)
|
||||
{ return SGVec4<T>(s*v(0), s*v(1), s*v(2), s*v(3)); }
|
||||
|
||||
/// multiplication as a multiplicator, that is assume that the first vector
|
||||
/// represents a 4x4 diagonal matrix with the diagonal elements in the vector.
|
||||
/// Then the result is the product of that matrix times the second vector.
|
||||
template<typename T>
|
||||
inline
|
||||
SGVec4<T>
|
||||
mult(const SGVec4<T>& v1, const SGVec4<T>& v2)
|
||||
{ return SGVec4<T>(v1(0)*v2(0), v1(1)*v2(1), v1(2)*v2(2), v1(3)*v2(3)); }
|
||||
|
||||
/// component wise min
|
||||
template<typename T>
|
||||
inline
|
||||
SGVec4<T>
|
||||
min(const SGVec4<T>& v1, const SGVec4<T>& v2)
|
||||
{
|
||||
return SGVec4<T>(SGMisc<T>::min(v1(0), v2(0)),
|
||||
SGMisc<T>::min(v1(1), v2(1)),
|
||||
SGMisc<T>::min(v1(2), v2(2)),
|
||||
SGMisc<T>::min(v1(3), v2(3)));
|
||||
}
|
||||
template<typename S, typename T>
|
||||
inline
|
||||
SGVec4<T>
|
||||
min(const SGVec4<T>& v, S s)
|
||||
{
|
||||
return SGVec4<T>(SGMisc<T>::min(s, v(0)),
|
||||
SGMisc<T>::min(s, v(1)),
|
||||
SGMisc<T>::min(s, v(2)),
|
||||
SGMisc<T>::min(s, v(3)));
|
||||
}
|
||||
template<typename S, typename T>
|
||||
inline
|
||||
SGVec4<T>
|
||||
min(S s, const SGVec4<T>& v)
|
||||
{
|
||||
return SGVec4<T>(SGMisc<T>::min(s, v(0)),
|
||||
SGMisc<T>::min(s, v(1)),
|
||||
SGMisc<T>::min(s, v(2)),
|
||||
SGMisc<T>::min(s, v(3)));
|
||||
}
|
||||
|
||||
/// component wise max
|
||||
template<typename T>
|
||||
inline
|
||||
SGVec4<T>
|
||||
max(const SGVec4<T>& v1, const SGVec4<T>& v2)
|
||||
{
|
||||
return SGVec4<T>(SGMisc<T>::max(v1(0), v2(0)),
|
||||
SGMisc<T>::max(v1(1), v2(1)),
|
||||
SGMisc<T>::max(v1(2), v2(2)),
|
||||
SGMisc<T>::max(v1(3), v2(3)));
|
||||
}
|
||||
template<typename S, typename T>
|
||||
inline
|
||||
SGVec4<T>
|
||||
max(const SGVec4<T>& v, S s)
|
||||
{
|
||||
return SGVec4<T>(SGMisc<T>::max(s, v(0)),
|
||||
SGMisc<T>::max(s, v(1)),
|
||||
SGMisc<T>::max(s, v(2)),
|
||||
SGMisc<T>::max(s, v(3)));
|
||||
}
|
||||
template<typename S, typename T>
|
||||
inline
|
||||
SGVec4<T>
|
||||
max(S s, const SGVec4<T>& v)
|
||||
{
|
||||
return SGVec4<T>(SGMisc<T>::max(s, v(0)),
|
||||
SGMisc<T>::max(s, v(1)),
|
||||
SGMisc<T>::max(s, v(2)),
|
||||
SGMisc<T>::max(s, v(3)));
|
||||
}
|
||||
|
||||
/// Scalar dot product
|
||||
template<typename T>
|
||||
inline
|
||||
@@ -203,6 +325,13 @@ T
|
||||
norm1(const SGVec4<T>& v)
|
||||
{ return fabs(v(0)) + fabs(v(1)) + fabs(v(2)) + fabs(v(3)); }
|
||||
|
||||
/// The inf-norm of the vector
|
||||
template<typename T>
|
||||
inline
|
||||
T
|
||||
normI(const SGVec4<T>& v)
|
||||
{ return SGMisc<T>::max(fabs(v(0)), fabs(v(1)), fabs(v(2)), fabs(v(2))); }
|
||||
|
||||
/// The euclidean norm of the vector, that is what most people call length
|
||||
template<typename T>
|
||||
inline
|
||||
@@ -224,6 +353,47 @@ bool
|
||||
operator!=(const SGVec4<T>& v1, const SGVec4<T>& v2)
|
||||
{ return ! (v1 == v2); }
|
||||
|
||||
/// Return true if smaller, good for putting that into a std::map
|
||||
template<typename T>
|
||||
inline
|
||||
bool
|
||||
operator<(const SGVec4<T>& v1, const SGVec4<T>& v2)
|
||||
{
|
||||
if (v1(0) < v2(0)) return true;
|
||||
else if (v2(0) < v1(0)) return false;
|
||||
else if (v1(1) < v2(1)) return true;
|
||||
else if (v2(1) < v1(1)) return false;
|
||||
else if (v1(2) < v2(2)) return true;
|
||||
else if (v2(2) < v1(2)) return false;
|
||||
else return (v1(3) < v2(3));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline
|
||||
bool
|
||||
operator<=(const SGVec4<T>& v1, const SGVec4<T>& v2)
|
||||
{
|
||||
if (v1(0) < v2(0)) return true;
|
||||
else if (v2(0) < v1(0)) return false;
|
||||
else if (v1(1) < v2(1)) return true;
|
||||
else if (v2(1) < v1(1)) return false;
|
||||
else if (v1(2) < v2(2)) return true;
|
||||
else if (v2(2) < v1(2)) return false;
|
||||
else return (v1(3) <= v2(3));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline
|
||||
bool
|
||||
operator>(const SGVec4<T>& v1, const SGVec4<T>& v2)
|
||||
{ return operator<(v2, v1); }
|
||||
|
||||
template<typename T>
|
||||
inline
|
||||
bool
|
||||
operator>=(const SGVec4<T>& v1, const SGVec4<T>& v2)
|
||||
{ return operator<=(v2, v1); }
|
||||
|
||||
/// Return true if equal to the relative tolerance tol
|
||||
template<typename T>
|
||||
inline
|
||||
@@ -248,6 +418,20 @@ equivalent(const SGVec4<T>& v1, const SGVec4<T>& v2)
|
||||
return equivalent(v1, v2, tol, tol);
|
||||
}
|
||||
|
||||
/// The euclidean distance of the two vectors
|
||||
template<typename T>
|
||||
inline
|
||||
T
|
||||
dist(const SGVec4<T>& v1, const SGVec4<T>& v2)
|
||||
{ return norm(v1 - v2); }
|
||||
|
||||
/// The squared euclidean distance of the two vectors
|
||||
template<typename T>
|
||||
inline
|
||||
T
|
||||
distSqr(const SGVec4<T>& v1, const SGVec4<T>& v2)
|
||||
{ SGVec4<T> tmp = v1 - v2; return dot(tmp, tmp); }
|
||||
|
||||
#ifndef NDEBUG
|
||||
template<typename T>
|
||||
inline
|
||||
@@ -266,10 +450,6 @@ std::basic_ostream<char_type, traits_type>&
|
||||
operator<<(std::basic_ostream<char_type, traits_type>& s, const SGVec4<T>& v)
|
||||
{ return s << "[ " << v(0) << ", " << v(1) << ", " << v(2) << ", " << v(3) << " ]"; }
|
||||
|
||||
/// Two classes doing actually the same on different types
|
||||
typedef SGVec4<float> SGVec4f;
|
||||
typedef SGVec4<double> SGVec4d;
|
||||
|
||||
inline
|
||||
SGVec4f
|
||||
toVec4f(const SGVec4d& v)
|
||||
|
||||
@@ -1,291 +0,0 @@
|
||||
/*
|
||||
* \file fastmath.cxx
|
||||
* fast mathematics routines.
|
||||
*
|
||||
* Refferences:
|
||||
*
|
||||
* A Fast, Compact Approximation of the Exponential Function
|
||||
* Nicol N. Schraudolph
|
||||
* IDSIA, Lugano, Switzerland
|
||||
* http://www.inf.ethz.ch/~schraudo/pubs/exp.pdf
|
||||
*
|
||||
* Base-2 exp, Laurent de Soras
|
||||
* http://www.musicdsp.org/archive.php?classid=5#106
|
||||
*
|
||||
* Fast log() Function, by Laurent de Soras:
|
||||
* http://www.flipcode.com/cgi-bin/msg.cgi?showThread=Tip-Fastlogfunction&forum=totd&id=-1
|
||||
*
|
||||
* Sin, Cos, Tan approximation
|
||||
* http://www.musicdsp.org/showArchiveComment.php?ArchiveID=115
|
||||
*
|
||||
* fast floating point power computation:
|
||||
* http://playstation2-linux.com/download/adam/power.c
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
|
||||
#include <simgear/constants.h>
|
||||
|
||||
#include "fastmath.hxx"
|
||||
|
||||
/**
|
||||
* This function is on avarage 9 times faster than the system exp() function
|
||||
* and has an error of about 1.5%
|
||||
*/
|
||||
static union {
|
||||
double d;
|
||||
struct {
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
int i, j;
|
||||
#else
|
||||
int j, i;
|
||||
#endif
|
||||
} n;
|
||||
} _eco;
|
||||
|
||||
double fast_exp(double val) {
|
||||
const double a = 1048576/M_LN2;
|
||||
const double b_c = 1072632447; /* 1072693248 - 60801 */
|
||||
|
||||
_eco.n.i = (int)(a*val + b_c);
|
||||
|
||||
return _eco.d;
|
||||
}
|
||||
|
||||
/*
|
||||
* Linear approx. between 2 integer values of val. Uses 32-bit integers.
|
||||
* Not very efficient but faster than exp()
|
||||
*/
|
||||
double fast_exp2( const double val )
|
||||
{
|
||||
int e;
|
||||
double ret;
|
||||
|
||||
if (val >= 0) {
|
||||
e = int (val);
|
||||
ret = val - (e - 1);
|
||||
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
((*((int *) &ret)) &= ~(2047 << 20)) += (e + 1023) << 20;
|
||||
#else
|
||||
((*(1 + (int *) &ret)) &= ~(2047 << 20)) += (e + 1023) << 20;
|
||||
#endif
|
||||
} else {
|
||||
e = int (val + 1023);
|
||||
ret = val - (e - 1024);
|
||||
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
((*((int *) &ret)) &= ~(2047 << 20)) += e << 20;
|
||||
#else
|
||||
((*(1 + (int *) &ret)) &= ~(2047 << 20)) += e << 20;
|
||||
#endif
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
float _fast_log2(const float val)
|
||||
{
|
||||
float result, tmp;
|
||||
float mp = 0.346607f;
|
||||
|
||||
result = *(int*)&val;
|
||||
result *= 1.0/(1<<23);
|
||||
result = result - 127;
|
||||
|
||||
tmp = result - floor(result);
|
||||
tmp = (tmp - tmp*tmp) * mp;
|
||||
return tmp + result;
|
||||
}
|
||||
|
||||
float _fast_pow2(const float val)
|
||||
{
|
||||
float result;
|
||||
|
||||
float mp = 0.33971f;
|
||||
float tmp = val - floor(val);
|
||||
tmp = (tmp - tmp*tmp) * mp;
|
||||
|
||||
result = val + 127 - tmp;
|
||||
result *= (1<<23);
|
||||
*(int*)&result = (int)result;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* While we're on the subject, someone might have use for these as well?
|
||||
* Float Shift Left and Float Shift Right. Do what you want with this.
|
||||
*/
|
||||
void fast_BSL(float &x, register unsigned long shiftAmount) {
|
||||
|
||||
*(unsigned long*)&x+=shiftAmount<<23;
|
||||
|
||||
}
|
||||
|
||||
void fast_BSR(float &x, register unsigned long shiftAmount) {
|
||||
|
||||
*(unsigned long*)&x-=shiftAmount<<23;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fastpow(f,n) gives a rather *rough* estimate of a float number f to the
|
||||
* power of an integer number n (y=f^n). It is fast but result can be quite a
|
||||
* bit off, since we directly mess with the floating point exponent.
|
||||
*
|
||||
* Use it only for getting rough estimates of the values and where precision
|
||||
* is not that important.
|
||||
*/
|
||||
float fast_pow(const float f, const int n)
|
||||
{
|
||||
long *lp,l;
|
||||
lp=(long*)(&f);
|
||||
l=*lp;l-=0x3F800000l;l<<=(n-1);l+=0x3F800000l;
|
||||
*lp=l;
|
||||
return f;
|
||||
}
|
||||
|
||||
float fast_root(const float f, const int n)
|
||||
{
|
||||
long *lp,l;
|
||||
lp=(long*)(&f);
|
||||
l=*lp;l-=0x3F800000l;l>>=(n-1);l+=0x3F800000l;
|
||||
*lp=l;
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Code for approximation of cos, sin, tan and inv sin, etc.
|
||||
* Surprisingly accurate and very usable.
|
||||
*
|
||||
* Domain:
|
||||
* Sin/Cos [0, pi/2]
|
||||
* Tan [0,pi/4]
|
||||
* InvSin/Cos [0, 1]
|
||||
* InvTan [-1, 1]
|
||||
*/
|
||||
|
||||
float fast_sin(const float val)
|
||||
{
|
||||
float fASqr = val*val;
|
||||
float fResult = -2.39e-08f;
|
||||
fResult *= fASqr;
|
||||
fResult += 2.7526e-06f;
|
||||
fResult *= fASqr;
|
||||
fResult -= 1.98409e-04f;
|
||||
fResult *= fASqr;
|
||||
fResult += 8.3333315e-03f;
|
||||
fResult *= fASqr;
|
||||
fResult -= 1.666666664e-01f;
|
||||
fResult *= fASqr;
|
||||
fResult += 1.0f;
|
||||
fResult *= val;
|
||||
|
||||
return fResult;
|
||||
}
|
||||
|
||||
float fast_cos(const float val)
|
||||
{
|
||||
float fASqr = val*val;
|
||||
float fResult = -2.605e-07f;
|
||||
fResult *= fASqr;
|
||||
fResult += 2.47609e-05f;
|
||||
fResult *= fASqr;
|
||||
fResult -= 1.3888397e-03f;
|
||||
fResult *= fASqr;
|
||||
fResult += 4.16666418e-02f;
|
||||
fResult *= fASqr;
|
||||
fResult -= 4.999999963e-01f;
|
||||
fResult *= fASqr;
|
||||
fResult += 1.0f;
|
||||
|
||||
return fResult;
|
||||
}
|
||||
|
||||
float fast_tan(const float val)
|
||||
{
|
||||
float fASqr = val*val;
|
||||
float fResult = 9.5168091e-03f;
|
||||
fResult *= fASqr;
|
||||
fResult += 2.900525e-03f;
|
||||
fResult *= fASqr;
|
||||
fResult += 2.45650893e-02f;
|
||||
fResult *= fASqr;
|
||||
fResult += 5.33740603e-02f;
|
||||
fResult *= fASqr;
|
||||
fResult += 1.333923995e-01f;
|
||||
fResult *= fASqr;
|
||||
fResult += 3.333314036e-01f;
|
||||
fResult *= fASqr;
|
||||
fResult += 1.0f;
|
||||
fResult *= val;
|
||||
|
||||
return fResult;
|
||||
|
||||
}
|
||||
|
||||
float fast_asin(float val)
|
||||
{
|
||||
float fRoot = sqrt(1.0f-val);
|
||||
float fResult = -0.0187293f;
|
||||
fResult *= val;
|
||||
fResult += 0.0742610f;
|
||||
fResult *= val;
|
||||
fResult -= 0.2121144f;
|
||||
fResult *= val;
|
||||
fResult += 1.5707288f;
|
||||
fResult = SGD_PI_2 - fRoot*fResult;
|
||||
|
||||
return fResult;
|
||||
}
|
||||
|
||||
float fast_acos(float val)
|
||||
{
|
||||
float fRoot = sqrt(1.0f-val);
|
||||
float fResult = -0.0187293f;
|
||||
fResult *= val;
|
||||
fResult += 0.0742610f;
|
||||
fResult *= val;
|
||||
fResult -= 0.2121144f;
|
||||
fResult *= val;
|
||||
fResult += 1.5707288f;
|
||||
fResult *= fRoot;
|
||||
|
||||
return fResult;
|
||||
}
|
||||
|
||||
float fast_atan(float val)
|
||||
{
|
||||
float fVSqr = val*val;
|
||||
float fResult = 0.0028662257f;
|
||||
fResult *= fVSqr;
|
||||
fResult -= 0.0161657367f;
|
||||
fResult *= fVSqr;
|
||||
fResult += 0.0429096138f;
|
||||
fResult *= fVSqr;
|
||||
fResult -= 0.0752896400f;
|
||||
fResult *= fVSqr;
|
||||
fResult += 0.1065626393f;
|
||||
fResult *= fVSqr;
|
||||
fResult -= 0.1420889944f;
|
||||
fResult *= fVSqr;
|
||||
fResult += 0.1999355085f;
|
||||
fResult *= fVSqr;
|
||||
fResult -= 0.3333314528f;
|
||||
fResult *= fVSqr;
|
||||
fResult += 1.0f;
|
||||
fResult *= val;
|
||||
|
||||
return fResult;
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
/*
|
||||
* \file fastmath.hxx
|
||||
* fast mathematics routines.
|
||||
*
|
||||
* References:
|
||||
*
|
||||
* A Fast, Compact Approximation of the Exponential Function
|
||||
* Nicol N. Schraudolph
|
||||
* IDSIA, Lugano, Switzerland
|
||||
* http://www.inf.ethz.ch/~schraudo/pubs/exp.pdf
|
||||
*
|
||||
* Fast log() Function, by Laurent de Soras:
|
||||
* http://www.flipcode.com/cgi-bin/msg.cgi?showThread=Tip-Fastlogfunction&forum=totd&id=-1
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _SG_FMATH_HXX
|
||||
#define _SG_FMATH_HXX 1
|
||||
|
||||
#ifndef __cplusplus
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
|
||||
|
||||
double fast_exp(double val);
|
||||
double fast_exp2(const double val);
|
||||
|
||||
float fast_pow(const float val1, const float val2);
|
||||
float fast_log2(const float cal);
|
||||
float fast_root(const float f, const int n);
|
||||
|
||||
float _fast_pow2(const float cal);
|
||||
float _fast_log2(const float val);
|
||||
|
||||
float fast_sin(const float val);
|
||||
float fast_cos(const float val);
|
||||
float fast_tan(const float val);
|
||||
float fast_asin(const float val);
|
||||
float fast_acos(const float val);
|
||||
float fast_atan(const float val);
|
||||
|
||||
void fast_BSL(float &x, register unsigned long shiftAmount);
|
||||
void fast_BSR(float &x, register unsigned long shiftAmount);
|
||||
|
||||
|
||||
inline float fast_log2 (float val)
|
||||
{
|
||||
union {
|
||||
float f;
|
||||
int i;
|
||||
} v;
|
||||
v.f = val;
|
||||
const int log_2 = ((v.i >> 23) & 255) - 128;
|
||||
v.i &= ~(255 << 23);
|
||||
v.i += 127 << 23;
|
||||
|
||||
v.f = ((-1.0f/3) * v.f + 2) * v.f - 2.0f/3; // (1)
|
||||
|
||||
return (v.f + log_2);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function is about 3 times faster than the system log() function
|
||||
* and has an error of about 0.01%
|
||||
*/
|
||||
inline float fast_log (const float &val)
|
||||
{
|
||||
return (fast_log2 (val) * 0.69314718f);
|
||||
}
|
||||
|
||||
inline float fast_log10 (const float &val)
|
||||
{
|
||||
return (fast_log2(val) / 3.321928095f);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function is about twice as fast as the system pow(x,y) function
|
||||
*/
|
||||
inline float fast_pow(const float val1, const float val2)
|
||||
{
|
||||
return _fast_pow2(val2 * _fast_log2(val1));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Haven't seen this elsewhere, probably because it is too obvious?
|
||||
* Anyway, these functions are intended for 32-bit floating point numbers
|
||||
* only and should work a bit faster than the regular ones.
|
||||
*/
|
||||
inline float fast_abs(float f)
|
||||
{
|
||||
int i=((*(int*)&f)&0x7fffffff);
|
||||
return (*(float*)&i);
|
||||
}
|
||||
|
||||
inline float fast_neg(float f)
|
||||
{
|
||||
int i=((*(int*)&f)^0x80000000);
|
||||
return (*(float*)&i);
|
||||
}
|
||||
|
||||
inline int fast_sgn(float f)
|
||||
{
|
||||
return 1+(((*(int*)&f)>>31)<<1);
|
||||
}
|
||||
|
||||
#endif // !_SG_FMATH_HXX
|
||||
|
||||
@@ -25,35 +25,41 @@
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <stdlib.h> // for exit()
|
||||
|
||||
#include STL_STRING
|
||||
#include <string>
|
||||
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/misc/sgstream.hxx>
|
||||
#include <simgear/props/props.hxx>
|
||||
|
||||
#include "interpolater.hxx"
|
||||
|
||||
SG_USING_STD(string);
|
||||
using std::string;
|
||||
|
||||
// Constructor -- starts with an empty table.
|
||||
SGInterpTable::SGInterpTable()
|
||||
: size(0)
|
||||
{
|
||||
}
|
||||
|
||||
SGInterpTable::SGInterpTable(const SGPropertyNode* interpolation)
|
||||
{
|
||||
if (!interpolation)
|
||||
return;
|
||||
std::vector<SGPropertyNode_ptr> entries = interpolation->getChildren("entry");
|
||||
for (unsigned i = 0; i < entries.size(); ++i)
|
||||
addEntry(entries[i]->getDoubleValue("ind", 0.0),
|
||||
entries[i]->getDoubleValue("dep", 0.0));
|
||||
}
|
||||
|
||||
// Constructor -- loads the interpolation table from the specified
|
||||
// file
|
||||
SGInterpTable::SGInterpTable( const string& file )
|
||||
: size(0)
|
||||
{
|
||||
SG_LOG( SG_MATH, SG_INFO, "Initializing Interpolator for " << file );
|
||||
|
||||
sg_gzifstream in( file );
|
||||
if ( !in.is_open() ) {
|
||||
SG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << file );
|
||||
exit(-1);
|
||||
return;
|
||||
}
|
||||
|
||||
in >> skipcomment;
|
||||
@@ -61,8 +67,7 @@ SGInterpTable::SGInterpTable( const string& file )
|
||||
double ind, dep;
|
||||
in >> ind >> dep;
|
||||
in >> skipws;
|
||||
table.push_back(Entry(ind, dep));
|
||||
size++;
|
||||
_table[ind] = dep;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,51 +75,42 @@ SGInterpTable::SGInterpTable( const string& file )
|
||||
// Add an entry to the table.
|
||||
void SGInterpTable::addEntry (double ind, double dep)
|
||||
{
|
||||
table.push_back(Entry(ind,dep));
|
||||
size++;
|
||||
_table[ind] = dep;
|
||||
}
|
||||
|
||||
|
||||
// Given an x value, linearly interpolate the y value from the table
|
||||
double SGInterpTable::interpolate(double x) const
|
||||
{
|
||||
int i;
|
||||
double y;
|
||||
|
||||
if (size == 0.0) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
|
||||
while ( (i < size) && (x > table[i].ind) ) {
|
||||
// cout << " i = " << i << " table[i].ind = " << table[i].ind << endl;
|
||||
// cout << " size = " << size << endl;
|
||||
i++;
|
||||
}
|
||||
|
||||
// printf ("i = %d ", i);
|
||||
|
||||
if ( i <= 0 ) {
|
||||
SG_LOG( SG_MATH, SG_DEBUG,
|
||||
"interpolate(): lookup error, x to small = " << x );
|
||||
return table[0].dep;
|
||||
}
|
||||
|
||||
// cout << " table[size-1].ind = " << table[size-1].ind << endl;
|
||||
if ( i >= size ) {
|
||||
SG_LOG( SG_MATH, SG_DEBUG,
|
||||
"interpolate(): lookup error, x to big = " << x );
|
||||
return table[size-1].dep;
|
||||
}
|
||||
|
||||
// y = y1 + (y0 - y1)(x - x1) / (x0 - x1)
|
||||
y = table[i].dep +
|
||||
( (table[i-1].dep - table[i].dep) *
|
||||
(x - table[i].ind) ) /
|
||||
(table[i-1].ind - table[i].ind);
|
||||
|
||||
return(y);
|
||||
// Empty table??
|
||||
if (_table.empty())
|
||||
return 0;
|
||||
|
||||
// Find the table bounds for the requested input.
|
||||
Table::const_iterator upBoundIt = _table.upper_bound(x);
|
||||
// points to a value outside the map. That is we are out of range.
|
||||
// use the last entry
|
||||
if (upBoundIt == _table.end())
|
||||
return _table.rbegin()->second;
|
||||
|
||||
// points to the first key must be lower
|
||||
// use the first entry
|
||||
if (upBoundIt == _table.begin())
|
||||
return upBoundIt->second;
|
||||
|
||||
// we know that we do not stand at the beginning, so it is safe to do so
|
||||
Table::const_iterator loBoundIt = upBoundIt;
|
||||
--loBoundIt;
|
||||
|
||||
// Just do linear interpolation.
|
||||
double loBound = loBoundIt->first;
|
||||
double upBound = upBoundIt->first;
|
||||
double loVal = loBoundIt->second;
|
||||
double upVal = upBoundIt->second;
|
||||
|
||||
// division by zero should not happen since the std::map
|
||||
// has sorted out duplicate entries before. Also since we have a
|
||||
// map, we know that we get different first values for different iterators
|
||||
return loVal + (upVal - loVal)*(x - loBound)/(upBound - loBound);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -35,12 +35,14 @@
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include <vector>
|
||||
SG_USING_STD(vector);
|
||||
#include "simgear/structure/SGReferenced.hxx"
|
||||
|
||||
#include STL_STRING
|
||||
SG_USING_STD(string);
|
||||
#include <map>
|
||||
|
||||
#include <string>
|
||||
using std::string;
|
||||
|
||||
class SGPropertyNode;
|
||||
|
||||
/**
|
||||
* A class that provids a simple linear 2d interpolation lookup table.
|
||||
@@ -48,21 +50,7 @@ SG_USING_STD(string);
|
||||
* independant variable must be strictly ascending. The dependent
|
||||
* variable can be anything.
|
||||
*/
|
||||
class SGInterpTable {
|
||||
|
||||
struct Entry
|
||||
{
|
||||
Entry ()
|
||||
: ind(0.0L), dep(0.0L) {}
|
||||
Entry (double independent, double dependent)
|
||||
: ind(independent), dep(dependent) {}
|
||||
double ind;
|
||||
double dep;
|
||||
};
|
||||
|
||||
int size;
|
||||
vector<Entry> table;
|
||||
|
||||
class SGInterpTable : public SGReferenced {
|
||||
public:
|
||||
|
||||
/**
|
||||
@@ -70,6 +58,13 @@ public:
|
||||
*/
|
||||
SGInterpTable();
|
||||
|
||||
/**
|
||||
* Constructor. Loads the interpolation table from an interpolation
|
||||
* property node.
|
||||
* @param interpolation property node having entry children
|
||||
*/
|
||||
SGInterpTable(const SGPropertyNode* interpolation);
|
||||
|
||||
/**
|
||||
* Constructor. Loads the interpolation table from the specified file.
|
||||
* @param file name of interpolation file
|
||||
@@ -95,6 +90,10 @@ public:
|
||||
|
||||
/** Destructor */
|
||||
~SGInterpTable();
|
||||
|
||||
private:
|
||||
typedef std::map<double, double> Table;
|
||||
Table _table;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
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
|
||||
@@ -1,540 +0,0 @@
|
||||
/*
|
||||
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];
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -37,41 +37,21 @@
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#ifdef SG_MATH_EXCEPTION_CLASH
|
||||
# define exception c_exception
|
||||
#endif
|
||||
|
||||
#ifdef SG_HAVE_STD_INCLUDES
|
||||
# include <iostream>
|
||||
# include <cassert>
|
||||
# include <cmath>
|
||||
#else
|
||||
# include <iostream.h>
|
||||
# include <assert.h>
|
||||
# include <math.h>
|
||||
#endif
|
||||
#include <ostream>
|
||||
#include <istream>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
|
||||
#include "SGMath.hxx"
|
||||
|
||||
// I don't understand ... <math.h> or <cmath> should be included
|
||||
// already depending on how you defined SG_HAVE_STD_INCLUDES, but I
|
||||
// can go ahead and add this -- CLO
|
||||
#ifdef __MWERKS__
|
||||
SG_USING_NAMESPACE(std);
|
||||
#endif
|
||||
|
||||
SG_USING_STD(ostream);
|
||||
SG_USING_STD(istream);
|
||||
|
||||
|
||||
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& );
|
||||
std::istream& operator>> ( std::istream&, Point3D& );
|
||||
std::ostream& operator<< ( std::ostream&, const Point3D& );
|
||||
Point3D operator- (const Point3D& p); // -p1
|
||||
bool operator== (const Point3D& a, const Point3D& b); // p1 == p2?
|
||||
|
||||
@@ -97,6 +77,8 @@ public:
|
||||
static Point3D fromSGGeod(const SGGeod& geod);
|
||||
static Point3D fromSGGeoc(const SGGeoc& geoc);
|
||||
static Point3D fromSGVec3(const SGVec3<double>& cart);
|
||||
static Point3D fromSGVec3(const SGVec3<float>& cart);
|
||||
static Point3D fromSGVec2(const SGVec2<double>& cart);
|
||||
|
||||
// Assignment operators
|
||||
|
||||
@@ -132,11 +114,15 @@ public:
|
||||
SGGeod toSGGeod(void) const;
|
||||
SGGeoc toSGGeoc(void) const;
|
||||
|
||||
SGVec3d toSGVec3d(void) const;
|
||||
SGVec3f toSGVec3f(void) const;
|
||||
SGVec2f toSGVec2f(void) const;
|
||||
|
||||
// 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& );
|
||||
friend std::istream& operator>> ( std::istream&, Point3D& );
|
||||
friend std::ostream& operator<< ( std::ostream&, const Point3D& );
|
||||
|
||||
// Special functions
|
||||
double distance3D(const Point3D& a) const; // distance between
|
||||
@@ -145,8 +131,8 @@ public:
|
||||
|
||||
|
||||
// input from stream
|
||||
inline istream&
|
||||
operator >> ( istream& in, Point3D& p)
|
||||
inline std::istream&
|
||||
operator >> ( std::istream& in, Point3D& p)
|
||||
{
|
||||
char c;
|
||||
|
||||
@@ -177,8 +163,8 @@ operator >> ( istream& in, Point3D& p)
|
||||
return in;
|
||||
}
|
||||
|
||||
inline ostream&
|
||||
operator<< ( ostream& out, const Point3D& p )
|
||||
inline std::ostream&
|
||||
operator<< ( std::ostream& out, const Point3D& p )
|
||||
{
|
||||
return out << p.n[PX] << ", " << p.n[PY] << ", " << p.n[PZ];
|
||||
}
|
||||
@@ -239,6 +225,24 @@ inline Point3D Point3D::fromSGVec3(const SGVec3<double>& cart)
|
||||
return pt;
|
||||
}
|
||||
|
||||
inline Point3D Point3D::fromSGVec3(const SGVec3<float>& cart)
|
||||
{
|
||||
Point3D pt;
|
||||
pt.setx(cart.x());
|
||||
pt.sety(cart.y());
|
||||
pt.setz(cart.z());
|
||||
return pt;
|
||||
}
|
||||
|
||||
inline Point3D Point3D::fromSGVec2(const SGVec2<double>& cart)
|
||||
{
|
||||
Point3D pt;
|
||||
pt.setx(cart.x());
|
||||
pt.sety(cart.y());
|
||||
pt.setz(0);
|
||||
return pt;
|
||||
}
|
||||
|
||||
// ASSIGNMENT OPERATORS
|
||||
|
||||
inline Point3D& Point3D::operator = (const Point3D& p)
|
||||
@@ -341,6 +345,21 @@ inline SGGeoc Point3D::toSGGeoc(void) const
|
||||
return geoc;
|
||||
}
|
||||
|
||||
inline SGVec3d Point3D::toSGVec3d(void) const
|
||||
{
|
||||
return SGVec3d(x(), y(), z());
|
||||
}
|
||||
|
||||
inline SGVec3f Point3D::toSGVec3f(void) const
|
||||
{
|
||||
return SGVec3f(x(), y(), z());
|
||||
}
|
||||
|
||||
inline SGVec2f Point3D::toSGVec2f(void) const
|
||||
{
|
||||
return SGVec2f(x(), y());
|
||||
}
|
||||
|
||||
// FRIENDS
|
||||
|
||||
inline Point3D operator - (const Point3D& a)
|
||||
|
||||
@@ -1,225 +0,0 @@
|
||||
// polar.cxx -- routines to deal with polar math and transformations
|
||||
//
|
||||
// Written by Curtis Olson, started June 1997.
|
||||
//
|
||||
// Copyright (C) 1997 Curtis L. Olson - http://www.flightgear.org/~curt
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <simgear/constants.h>
|
||||
|
||||
#include "polar3d.hxx"
|
||||
|
||||
/**
|
||||
* Calculate new lon/lat given starting lon/lat, and offset radial, and
|
||||
* distance. NOTE: starting point is specifed in radians, distance is
|
||||
* specified in meters (and converted internally to radians)
|
||||
* ... assumes a spherical world.
|
||||
* @param orig specified in polar coordinates
|
||||
* @param course offset radial
|
||||
* @param dist offset distance
|
||||
* @return destination point in polar coordinates
|
||||
*/
|
||||
Point3D calc_gc_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 *= SG_METER_TO_NM * SG_NM_TO_RAD;
|
||||
|
||||
result.sety( asin( sin(orig.y()) * cos(dist) +
|
||||
cos(orig.y()) * sin(dist) * cos(course) ) );
|
||||
|
||||
if ( cos(result.y()) < SG_EPSILON ) {
|
||||
result.setx( orig.x() ); // endpoint a pole
|
||||
} else {
|
||||
result.setx(
|
||||
fmod(orig.x() - asin( sin(course) * sin(dist) /
|
||||
cos(result.y()) )
|
||||
+ SGD_PI, SGD_2PI) - SGD_PI );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate course/dist given two spherical points.
|
||||
* @param start starting point
|
||||
* @param dest ending point
|
||||
* @param course resulting course
|
||||
* @param dist resulting distance
|
||||
*/
|
||||
void calc_gc_course_dist( const Point3D& start, const Point3D& dest,
|
||||
double *course, double *dist )
|
||||
{
|
||||
if ( start == dest) {
|
||||
*dist=0;
|
||||
*course=0;
|
||||
return;
|
||||
}
|
||||
// d = 2*asin(sqrt((sin((lat1-lat2)/2))^2 +
|
||||
// cos(lat1)*cos(lat2)*(sin((lon1-lon2)/2))^2))
|
||||
double cos_start_y = cos( start.y() );
|
||||
double tmp1 = sin( (start.y() - dest.y()) * 0.5 );
|
||||
double tmp2 = sin( (start.x() - dest.x()) * 0.5 );
|
||||
double d = 2.0 * asin( sqrt( tmp1 * tmp1 +
|
||||
cos_start_y * cos(dest.y()) * tmp2 * tmp2));
|
||||
|
||||
*dist = d * SG_RAD_TO_NM * SG_NM_TO_METER;
|
||||
|
||||
#if 1
|
||||
double c1 = atan2(
|
||||
cos(dest.y())*sin(dest.x()-start.x()),
|
||||
cos(start.y())*sin(dest.y())-
|
||||
sin(start.y())*cos(dest.y())*cos(dest.x()-start.x()));
|
||||
if (c1 >= 0)
|
||||
*course = SGD_2PI-c1;
|
||||
else
|
||||
*course = -c1;
|
||||
#else
|
||||
// We obtain the initial course, tc1, (at point 1) from point 1 to
|
||||
// point 2 by the following. The formula fails if the initial
|
||||
// point is a pole. We can special case this with:
|
||||
//
|
||||
// IF (cos(lat1) < EPS) // EPS a small number ~ machine precision
|
||||
// IF (lat1 > 0)
|
||||
// tc1= pi // starting from N pole
|
||||
// ELSE
|
||||
// tc1= 0 // starting from S pole
|
||||
// ENDIF
|
||||
// ENDIF
|
||||
//
|
||||
// For starting points other than the poles:
|
||||
//
|
||||
// IF sin(lon2-lon1)<0
|
||||
// tc1=acos((sin(lat2)-sin(lat1)*cos(d))/(sin(d)*cos(lat1)))
|
||||
// ELSE
|
||||
// tc1=2*pi-acos((sin(lat2)-sin(lat1)*cos(d))/(sin(d)*cos(lat1)))
|
||||
// ENDIF
|
||||
|
||||
// if ( cos(start.y()) < SG_EPSILON ) {
|
||||
// doing it this way saves a transcendental call
|
||||
double sin_start_y = sin( start.y() );
|
||||
if ( fabs(1.0-sin_start_y) < SG_EPSILON ) {
|
||||
// EPS a small number ~ machine precision
|
||||
if ( start.y() > 0 ) {
|
||||
*course = SGD_PI; // starting from N pole
|
||||
} else {
|
||||
*course = 0; // starting from S pole
|
||||
}
|
||||
} else {
|
||||
// For starting points other than the poles:
|
||||
// double tmp3 = sin(d)*cos_start_y);
|
||||
// double tmp4 = sin(dest.y())-sin(start.y())*cos(d);
|
||||
// double tmp5 = acos(tmp4/tmp3);
|
||||
|
||||
// Doing this way gaurentees that the temps are
|
||||
// not stored into memory
|
||||
double tmp5 = acos( (sin(dest.y()) - sin_start_y * cos(d)) /
|
||||
(sin(d) * cos_start_y) );
|
||||
|
||||
// if ( sin( dest.x() - start.x() ) < 0 ) {
|
||||
// the sin of the negative angle is just the opposite sign
|
||||
// of the sin of the angle so tmp2 will have the opposite
|
||||
// sign of sin( dest.x() - start.x() )
|
||||
if ( tmp2 >= 0 ) {
|
||||
*course = tmp5;
|
||||
} else {
|
||||
*course = SGD_2PI - tmp5;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Calculate course/dist given two spherical points.
|
||||
* @param start starting point
|
||||
* @param dest ending point
|
||||
* @param course resulting course
|
||||
* @param dist resulting distance
|
||||
*/
|
||||
void calc_gc_course_dist( const Point3D& start, const Point3D& dest,
|
||||
double *course, double *dist ) {
|
||||
// d = 2*asin(sqrt((sin((lat1-lat2)/2))^2 +
|
||||
// cos(lat1)*cos(lat2)*(sin((lon1-lon2)/2))^2))
|
||||
double tmp1 = sin( (start.y() - dest.y()) / 2 );
|
||||
double tmp2 = sin( (start.x() - dest.x()) / 2 );
|
||||
double d = 2.0 * asin( sqrt( tmp1 * tmp1 +
|
||||
cos(start.y()) * cos(dest.y()) * tmp2 * tmp2));
|
||||
// We obtain the initial course, tc1, (at point 1) from point 1 to
|
||||
// point 2 by the following. The formula fails if the initial
|
||||
// point is a pole. We can special case this with:
|
||||
//
|
||||
// IF (cos(lat1) < EPS) // EPS a small number ~ machine precision
|
||||
// IF (lat1 > 0)
|
||||
// tc1= pi // starting from N pole
|
||||
// ELSE
|
||||
// tc1= 0 // starting from S pole
|
||||
// ENDIF
|
||||
// ENDIF
|
||||
//
|
||||
// For starting points other than the poles:
|
||||
//
|
||||
// IF sin(lon2-lon1)<0
|
||||
// tc1=acos((sin(lat2)-sin(lat1)*cos(d))/(sin(d)*cos(lat1)))
|
||||
// ELSE
|
||||
// tc1=2*pi-acos((sin(lat2)-sin(lat1)*cos(d))/(sin(d)*cos(lat1)))
|
||||
// ENDIF
|
||||
|
||||
double tc1;
|
||||
|
||||
if ( cos(start.y()) < SG_EPSILON ) {
|
||||
// EPS a small number ~ machine precision
|
||||
if ( start.y() > 0 ) {
|
||||
tc1 = SGD_PI; // starting from N pole
|
||||
} else {
|
||||
tc1 = 0; // starting from S pole
|
||||
}
|
||||
}
|
||||
|
||||
// For starting points other than the poles:
|
||||
|
||||
double tmp3 = sin(d)*cos(start.y());
|
||||
double tmp4 = sin(dest.y())-sin(start.y())*cos(d);
|
||||
double tmp5 = acos(tmp4/tmp3);
|
||||
if ( sin( dest.x() - start.x() ) < 0 ) {
|
||||
tc1 = tmp5;
|
||||
} else {
|
||||
tc1 = SGD_2PI - tmp5;
|
||||
}
|
||||
|
||||
*course = tc1;
|
||||
*dist = d * SG_RAD_TO_NM * SG_NM_TO_METER;
|
||||
}
|
||||
#endif // 0
|
||||
@@ -32,56 +32,9 @@
|
||||
# error This library requires C++
|
||||
#endif
|
||||
|
||||
|
||||
#include <simgear/constants.h>
|
||||
#include <simgear/math/point3d.hxx>
|
||||
|
||||
#include "SGMath.hxx"
|
||||
|
||||
/**
|
||||
* Find the Altitude above the Ellipsoid (WGS84) given the Earth
|
||||
* Centered Cartesian coordinate vector Distances are specified in
|
||||
* meters.
|
||||
* @param cp point specified in cartesian coordinates
|
||||
* @return altitude above the (wgs84) earth in meters
|
||||
*/
|
||||
inline double sgGeodAltFromCart(const Point3D& p)
|
||||
{
|
||||
SGGeod geod;
|
||||
SGGeodesy::SGCartToGeod(SGVec3<double>(p.x(), p.y(), p.z()), geod);
|
||||
return geod.getElevationM();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert a polar coordinate to a cartesian coordinate. Lon and Lat
|
||||
* must be specified in radians. The SG convention is for distances
|
||||
* to be specified in meters
|
||||
* @param p point specified in polar coordinates
|
||||
* @return the same point in cartesian coordinates
|
||||
*/
|
||||
inline Point3D sgPolarToCart3d(const Point3D& p)
|
||||
{
|
||||
SGVec3<double> cart;
|
||||
SGGeodesy::SGGeocToCart(SGGeoc::fromRadM(p.lon(), p.lat(), p.radius()), cart);
|
||||
return Point3D::fromSGVec3(cart);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert a cartesian coordinate to polar coordinates (lon/lat
|
||||
* specified in radians. Distances are specified in meters.
|
||||
* @param cp point specified in cartesian coordinates
|
||||
* @return the same point in polar coordinates
|
||||
*/
|
||||
inline Point3D sgCartToPolar3d(const Point3D& p)
|
||||
{
|
||||
SGGeoc geoc;
|
||||
SGGeodesy::SGCartToGeoc(SGVec3<double>(p.x(), p.y(), p.z()), geoc);
|
||||
return Point3D::fromSGGeoc(geoc);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calculate new lon/lat given starting lon/lat, and offset radial, and
|
||||
* distance. NOTE: starting point is specifed in radians, distance is
|
||||
@@ -92,7 +45,8 @@ inline Point3D sgCartToPolar3d(const Point3D& p)
|
||||
* @param dist offset distance
|
||||
* @return destination point in polar coordinates
|
||||
*/
|
||||
Point3D calc_gc_lon_lat( const Point3D& orig, double course, double dist );
|
||||
inline Point3D calc_gc_lon_lat(const Point3D& orig, double course, double dist)
|
||||
{ return Point3D::fromSGGeoc(orig.toSGGeoc().advanceRadM(course, dist)); }
|
||||
|
||||
|
||||
/**
|
||||
@@ -102,20 +56,14 @@ Point3D calc_gc_lon_lat( const Point3D& orig, double course, double dist );
|
||||
* @param course resulting course
|
||||
* @param dist resulting distance
|
||||
*/
|
||||
void calc_gc_course_dist( const Point3D& start, const Point3D& dest,
|
||||
double *course, double *dist );
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Calculate course/dist given two spherical points.
|
||||
* @param start starting point
|
||||
* @param dest ending point
|
||||
* @param course resulting course
|
||||
* @param dist resulting distance
|
||||
*/
|
||||
void calc_gc_course_dist( const Point3D& start, const Point3D& dest,
|
||||
double *course, double *dist );
|
||||
#endif // 0
|
||||
inline void calc_gc_course_dist( const Point3D& start, const Point3D& dest,
|
||||
double *course, double *dist )
|
||||
{
|
||||
SGGeoc gs = start.toSGGeoc();
|
||||
SGGeoc gd = dest.toSGGeoc();
|
||||
*course = SGGeoc::courseRad(gs, gd);
|
||||
*dist = SGGeoc::distanceM(gs, gd);
|
||||
}
|
||||
|
||||
#endif // _POLAR3D_HXX
|
||||
|
||||
|
||||
@@ -1,285 +0,0 @@
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/constants.h>
|
||||
#include "SGMath.hxx"
|
||||
#include "sg_geodesy.hxx"
|
||||
|
||||
// Notes:
|
||||
//
|
||||
// The XYZ/cartesian coordinate system in use puts the X axis through
|
||||
// zero lat/lon (off west Africa), the Z axis through the north pole,
|
||||
// and the Y axis through 90 degrees longitude (in the Indian Ocean).
|
||||
//
|
||||
// All latitude and longitude values are in radians. Altitude is in
|
||||
// meters, with zero on the WGS84 ellipsoid.
|
||||
//
|
||||
// The code below makes use of the notion of "squashed" space. This
|
||||
// is a 2D cylindrical coordinate system where the radius from the Z
|
||||
// axis is multiplied by SQUASH; the earth in this space is a perfect
|
||||
// circle with a radius of POLRAD.
|
||||
//
|
||||
// Performance: with full optimization, a transformation from
|
||||
// lat/lon/alt to XYZ and back takes 5263 CPU cycles on my 2.2GHz
|
||||
// Pentium 4. About 83% of this is spent in the iterative sgCartToGeod()
|
||||
// algorithm.
|
||||
|
||||
// These are hard numbers from the WGS84 standard. DON'T MODIFY
|
||||
// unless you want to change the datum.
|
||||
static const double EQURAD = 6378137;
|
||||
static const double iFLATTENING = 298.257223563;
|
||||
|
||||
// These are derived quantities more useful to the code:
|
||||
#if 0
|
||||
static const double SQUASH = 1 - 1/iFLATTENING;
|
||||
static const double STRETCH = 1/SQUASH;
|
||||
static const double POLRAD = EQURAD * SQUASH;
|
||||
#else
|
||||
// High-precision versions of the above produced with an arbitrary
|
||||
// precision calculator (the compiler might lose a few bits in the FPU
|
||||
// operations). These are specified to 81 bits of mantissa, which is
|
||||
// higher than any FPU known to me:
|
||||
static const double SQUASH = 0.9966471893352525192801545;
|
||||
static const double STRETCH = 1.0033640898209764189003079;
|
||||
static const double POLRAD = 6356752.3142451794975639668;
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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
|
||||
|
||||
static const double GEOD_INV_PI = SGD_PI;
|
||||
|
||||
// s == distance
|
||||
// az = azimuth
|
||||
|
||||
static inline 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 = EQURAD, rf = iFLATTENING;
|
||||
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 );
|
||||
double zero = 0.0f;
|
||||
return geo_direct_wgs_84( alt, zero, 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 = EQURAD, rf = iFLATTENING;
|
||||
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
|
||||
double _lon1 = lon1 + 180.0f;
|
||||
int k = geo_inverse_wgs_84( alt, lat1, lon1, lat1, _lon1,
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -4,38 +4,8 @@
|
||||
#include <simgear/math/point3d.hxx>
|
||||
#include "SGMath.hxx"
|
||||
|
||||
// Returns the insersection of the line joining the center of the
|
||||
// earth and the specified cylindrical point with the surface of the
|
||||
// WGS84 ellipsoid. Works by finding a normalization constant (in
|
||||
// squashed space) that places the squashed point on the surface of
|
||||
// the sphere.
|
||||
inline double seaLevelRadius(double r, double z)
|
||||
{
|
||||
double sr = r * SGGeodesy::SQUASH;
|
||||
double zz = z*z;
|
||||
return SGGeodesy::POLRAD*sqrt((r*r + zz)/(sr*sr + zz));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert from geocentric coordinates to geodetic coordinates
|
||||
* @param lat_geoc (in) Geocentric latitude, radians, + = North
|
||||
* @param radius (in) C.G. radius to earth center (meters)
|
||||
* @param lat_geod (out) Geodetic latitude, radians, + = North
|
||||
* @param alt (out) C.G. altitude above mean sea level (meters)
|
||||
* @param sea_level_r (out) radius from earth center to sea level at
|
||||
* local vertical (surface normal) of C.G. (meters)
|
||||
*/
|
||||
inline void sgGeocToGeod(double lat_geoc, double radius,
|
||||
double *lat_geod, double *alt, double *sea_level_r)
|
||||
{
|
||||
SGVec3<double> cart;
|
||||
SGGeodesy::SGGeocToCart(SGGeoc::fromRadM(0, lat_geoc, radius), cart);
|
||||
SGGeod geod;
|
||||
SGGeodesy::SGCartToGeod(cart, geod);
|
||||
*lat_geod = geod.getLatitudeRad();
|
||||
*alt = geod.getElevationM();
|
||||
*sea_level_r = SGGeodesy::SGGeodToSeaLevelRadius(geod);
|
||||
}
|
||||
// Compatibility header.
|
||||
// Please use the SGGeodesy and SGMath functions directly.
|
||||
|
||||
/**
|
||||
* Convert from geodetic coordinates to geocentric coordinates.
|
||||
@@ -56,11 +26,12 @@ inline void sgGeodToGeoc(double lat_geod, double alt,
|
||||
double *sl_radius, double *lat_geoc)
|
||||
{
|
||||
SGVec3<double> cart;
|
||||
SGGeodesy::SGGeodToCart(SGGeod::fromRadM(0, lat_geod, alt), cart);
|
||||
SGGeod geod = SGGeod::fromRadM(0, lat_geod, alt);
|
||||
SGGeodesy::SGGeodToCart(geod, cart);
|
||||
SGGeoc geoc;
|
||||
SGGeodesy::SGCartToGeoc(cart, geoc);
|
||||
*lat_geoc = geoc.getLatitudeRad();
|
||||
*sl_radius = seaLevelRadius(cart(0), cart(2));
|
||||
*sl_radius = SGGeodesy::SGGeodToSeaLevelRadius(geod);
|
||||
}
|
||||
|
||||
|
||||
@@ -130,7 +101,7 @@ inline Point3D sgGeodToCart(const Point3D& geod)
|
||||
/**
|
||||
* Given a starting position and an offset radial and distance,
|
||||
* calculate an ending positon on a wgs84 ellipsoid.
|
||||
* @param alt (in) meters
|
||||
* @param alt (in) meters (unused)
|
||||
* @param lat1 (in) degrees
|
||||
* @param lon1 (in) degrees
|
||||
* @param az1 (in) degrees
|
||||
@@ -139,16 +110,42 @@ inline Point3D sgGeodToCart(const Point3D& geod)
|
||||
* @param lon2 (out) degrees
|
||||
* @param az2 (out) return course in degrees
|
||||
*/
|
||||
int geo_direct_wgs_84 ( double alt, double lat1,
|
||||
inline int geo_direct_wgs_84 ( double lat1, double lon1, double az1,
|
||||
double s, double *lat2, double *lon2,
|
||||
double *az2 )
|
||||
{
|
||||
SGGeod p2;
|
||||
if (!SGGeodesy::direct(SGGeod::fromDeg(lon1, lat1), az1, s, p2, *az2))
|
||||
return 1;
|
||||
*lat2 = p2.getLatitudeDeg();
|
||||
*lon2 = p2.getLongitudeDeg();
|
||||
return 0;
|
||||
}
|
||||
inline int geo_direct_wgs_84 ( double alt, double lat1,
|
||||
double lon1, double az1,
|
||||
double s, double *lat2, double *lon2,
|
||||
double *az2 );
|
||||
double *az2 )
|
||||
{ return geo_direct_wgs_84(lat1, lon1, az1, s, lat2, lon2, az2); }
|
||||
|
||||
/**
|
||||
* Given a starting position and an offset radial and distance,
|
||||
* calculate an ending positon on a wgs84 ellipsoid.
|
||||
* @param p1 (in) geodetic position
|
||||
* @param az1 (in) degrees
|
||||
* @param s (in) distance in meters
|
||||
* @param p2 (out) geodetic position
|
||||
* @param az2 (out) return course in degrees
|
||||
*/
|
||||
inline int geo_direct_wgs_84(const SGGeod& p1, double az1,
|
||||
double s, SGGeod& p2, double *az2 )
|
||||
{
|
||||
return !SGGeodesy::direct(p1, az1, s, p2, *az2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an altitude and two sets of (lat, lon) calculate great circle
|
||||
* distance between them as well as the starting and ending azimuths.
|
||||
* @param alt (in) meters
|
||||
* @param alt (in) meters (unused)
|
||||
* @param lat1 (in) degrees
|
||||
* @param lon1 (in) degrees
|
||||
* @param lat2 (in) degrees
|
||||
@@ -157,9 +154,33 @@ int geo_direct_wgs_84 ( double alt, double lat1,
|
||||
* @param az2 (out) end heading degrees
|
||||
* @param s (out) distance meters
|
||||
*/
|
||||
int geo_inverse_wgs_84( double alt, double lat1,
|
||||
double lon1, double lat2,
|
||||
double lon2, double *az1, double *az2,
|
||||
double *s );
|
||||
inline int geo_inverse_wgs_84( double lat1, double lon1, double lat2,
|
||||
double lon2, double *az1, double *az2,
|
||||
double *s )
|
||||
{
|
||||
return !SGGeodesy::inverse(SGGeod::fromDeg(lon1, lat1),
|
||||
SGGeod::fromDeg(lon2, lat2), *az1, *az2, *s);
|
||||
}
|
||||
inline int geo_inverse_wgs_84( double alt, double lat1,
|
||||
double lon1, double lat2,
|
||||
double lon2, double *az1, double *az2,
|
||||
double *s )
|
||||
{ return geo_inverse_wgs_84(lat1, lon1, lat2, lon2, az1, az2, s); }
|
||||
|
||||
|
||||
/**
|
||||
* Given an altitude and two sets of (lat, lon) calculate great circle
|
||||
* distance between them as well as the starting and ending azimuths.
|
||||
* @param p1 (in) first position
|
||||
* @param p2 (in) fsecond position
|
||||
* @param az1 (out) start heading degrees
|
||||
* @param az2 (out) end heading degrees
|
||||
* @param s (out) distance meters
|
||||
*/
|
||||
inline int geo_inverse_wgs_84(const SGGeod& p1, const SGGeod& p2,
|
||||
double *az1, double *az2, double *s )
|
||||
{
|
||||
return !SGGeodesy::inverse(p1, p2, *az1, *az2, *s);
|
||||
}
|
||||
|
||||
#endif // _SG_GEODESY_HXX
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
/**
|
||||
* \file sg_memory.h
|
||||
* memcpy/bcopy portability declarations (not actually used by anything
|
||||
* as best as I can tell.
|
||||
*/
|
||||
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#ifndef _SG_MEMORY_H
|
||||
#define _SG_MEMORY_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MEMCPY
|
||||
|
||||
# ifdef HAVE_MEMORY_H
|
||||
# include <memory.h>
|
||||
# endif
|
||||
|
||||
# define sgmemcmp memcmp
|
||||
# define sgmemcpy memcpy
|
||||
# define sgmemzero(dest,len) memset(dest,0,len)
|
||||
|
||||
#elif defined(HAVE_BCOPY)
|
||||
|
||||
# define sgmemcmp bcmp
|
||||
# define sgmemcpy(dest,src,n) bcopy(src,dest,n)
|
||||
# define sgmemzero bzero
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* Neither memcpy() or bcopy() available.
|
||||
* Use substitutes provided be zlib.
|
||||
*/
|
||||
|
||||
# include <zutil.h>
|
||||
# define sgmemcmp zmemcmp
|
||||
# define sgmemcpy zmemcpy
|
||||
# define sgmemzero zmemzero
|
||||
|
||||
#endif
|
||||
|
||||
#endif // _SG_MEMORY_H
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user