Compare commits
908
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
506b9130a8 | ||
|
|
5d1b70a7f2 | ||
|
|
eff3df57d9 | ||
|
|
2931f3380f | ||
|
|
2d00653f6e | ||
|
|
4647ce2da5 | ||
|
|
51d43f809e | ||
|
|
370a115ab9 | ||
|
|
32b60f9b80 | ||
|
|
beeaef3868 | ||
|
|
ddd9691439 | ||
|
|
9da0031039 | ||
|
|
9537876bba | ||
|
|
958ae9bdf0 | ||
|
|
023b5a09f7 | ||
|
|
46fe57fb8d | ||
|
|
07e09bb88c | ||
|
|
1b7f310ea6 | ||
|
|
365ddb84a7 | ||
|
|
5fef44b11c | ||
|
|
1480aa9bb8 | ||
|
|
75271c44a8 | ||
|
|
543f1b7902 | ||
|
|
93a63a0678 | ||
|
|
2bf79a2fa1 | ||
|
|
ab956f15c3 | ||
|
|
deceee8997 | ||
|
|
b3c7d63809 | ||
|
|
2026c665b2 | ||
|
|
36fd005bb9 | ||
|
|
46bed67cce | ||
|
|
5b9af0c0aa | ||
|
|
85090180d0 | ||
|
|
f33ad357e9 | ||
|
|
c30ce67e16 | ||
|
|
3ca7369fb2 | ||
|
|
088ce31f7c | ||
|
|
4f94c22241 | ||
|
|
e1791b3006 | ||
|
|
e608ed5a01 | ||
|
|
35ebb16215 | ||
|
|
68d0891665 | ||
|
|
b11ff19a0f | ||
|
|
e7e616e07c | ||
|
|
14f2f9e917 | ||
|
|
791273c61d | ||
|
|
519326f751 | ||
|
|
d1f5d92a7b | ||
|
|
f448898531 | ||
|
|
d9b66fc0ef | ||
|
|
3bcd0bafd5 | ||
|
|
942181c8ae | ||
|
|
7df39b9fc8 | ||
|
|
f41b18f064 | ||
|
|
c5d649aa0b | ||
|
|
64ac22f50c | ||
|
|
719ee36f5c | ||
|
|
92851135d4 | ||
|
|
76fc47b24b | ||
|
|
f25abad9d7 | ||
|
|
23413b4781 | ||
|
|
e036dfc5bf | ||
|
|
9260bea850 | ||
|
|
c1f09034e0 | ||
|
|
557e4f75b5 | ||
|
|
e71d6b24d7 | ||
|
|
726a4c6d10 | ||
|
|
6af8d32078 | ||
|
|
f6b16e2ba8 | ||
|
|
e415b08da4 | ||
|
|
1d93e8d61e | ||
|
|
4bd34991e9 | ||
|
|
9709cfe20d | ||
|
|
a5e99ea996 | ||
|
|
d9df10fe10 | ||
|
|
f1677f5546 | ||
|
|
cb796e374a | ||
|
|
7c3491c679 | ||
|
|
6200b160ec | ||
|
|
9868fb03a2 | ||
|
|
a69130ff10 | ||
|
|
0b60643053 | ||
|
|
dc4644bf3a | ||
|
|
38b766f845 | ||
|
|
10d0be013e | ||
|
|
5126ae5891 | ||
|
|
49bcf49db1 | ||
|
|
3bbb272ad5 | ||
|
|
645cae184b | ||
|
|
bd9fa7017f | ||
|
|
fc9f3abfbb | ||
|
|
f2f1b36df9 | ||
|
|
03d2a166b7 | ||
|
|
f0a76aa918 | ||
|
|
c144c3562c | ||
|
|
e06f9462ab | ||
|
|
9aa5c3b2ae | ||
|
|
2c41c25fcd | ||
|
|
9ffc0ae8bc | ||
|
|
bb5e07d958 | ||
|
|
5024b62c0a | ||
|
|
82d5c605e5 | ||
|
|
737b1948bf | ||
|
|
1225e53162 | ||
|
|
b58bf443ff | ||
|
|
9bef80fbef | ||
|
|
36cb7a752b | ||
|
|
d3b211e787 | ||
|
|
e3f0fad272 | ||
|
|
e8f10dd2e8 | ||
|
|
edbfbd769e | ||
|
|
dc60cf0e67 | ||
|
|
083b364afd | ||
|
|
dd2bf418b9 | ||
|
|
97cc250047 | ||
|
|
49fc75926e | ||
|
|
9880ba39a7 | ||
|
|
a8c8148068 | ||
|
|
adebbe006b | ||
|
|
c3bc73ab2f | ||
|
|
c716cfbb07 | ||
|
|
ade4627f1a | ||
|
|
e508ff724c | ||
|
|
c54e3f8101 | ||
|
|
6925c2a2be | ||
|
|
398bf740d7 | ||
|
|
e302ad092e | ||
|
|
7a65d42a4c | ||
|
|
d3a14bfd61 | ||
|
|
03cafe4547 | ||
|
|
e5acc3f048 | ||
|
|
4931ce0364 | ||
|
|
e3d53e854a | ||
|
|
bdf6b25338 | ||
|
|
5dddba26ac | ||
|
|
746fa419ed | ||
|
|
7080f919e9 | ||
|
|
c4e0014d74 | ||
|
|
7d9797e091 | ||
|
|
67a8d8049f | ||
|
|
c3670b211f | ||
|
|
32274027ef | ||
|
|
d09943cbb8 | ||
|
|
150039f9ba | ||
|
|
820a315cbe | ||
|
|
8abe4622b9 | ||
|
|
da6ab1eabc | ||
|
|
e3ddcbe2dd | ||
|
|
b36cdebe8b | ||
|
|
3c0544c9a6 | ||
|
|
be358f8d24 | ||
|
|
e1abab393b | ||
|
|
0b21181f1a | ||
|
|
dfdd1c6d5e | ||
|
|
a8e96997cb | ||
|
|
6db07373ee | ||
|
|
36ae8cdce3 | ||
|
|
d77ba7d2db | ||
|
|
6e58fdac85 | ||
|
|
3f6933940e | ||
|
|
4bd8fe5855 | ||
|
|
9c421d55a9 | ||
|
|
1af6cbc1aa | ||
|
|
a9e7af6e6e | ||
|
|
c967fbc0a6 | ||
|
|
6929ba75c0 | ||
|
|
289777bd99 | ||
|
|
7535dfd2d0 | ||
|
|
23279b4d0a | ||
|
|
d34d3ecfb1 | ||
|
|
55f18574aa | ||
|
|
02ac1a43c1 | ||
|
|
b2c3a90adf | ||
|
|
9975c751a7 | ||
|
|
efbec8b367 | ||
|
|
9642f6d946 | ||
|
|
247aa49849 | ||
|
|
edaae885ee | ||
|
|
b101f64cd8 | ||
|
|
f75d1cbcb1 | ||
|
|
ac2e80dc07 | ||
|
|
85b17ae8d4 | ||
|
|
77955e5c3c | ||
|
|
19481983e5 | ||
|
|
5b2b420c48 | ||
|
|
15d3c12139 | ||
|
|
338a748823 | ||
|
|
8c45796dc8 | ||
|
|
a160e176da | ||
|
|
d332da0605 | ||
|
|
6ea55c6851 | ||
|
|
10ee7a901f | ||
|
|
db8b60ec49 | ||
|
|
09d47e7f55 | ||
|
|
13a3ea3503 | ||
|
|
ff53792e4f | ||
|
|
fd51518d92 | ||
|
|
01a43b49a5 | ||
|
|
3525fff8d0 | ||
|
|
6c75e2fe3c | ||
|
|
b322864ef4 | ||
|
|
f28e3fc9bb | ||
|
|
80e77b8372 | ||
|
|
c925b7b601 | ||
|
|
966789de90 | ||
|
|
d44a3117d9 | ||
|
|
c851c449da | ||
|
|
b2d9385f46 | ||
|
|
f40efe66fa | ||
|
|
5560479665 | ||
|
|
4ea8e4774e | ||
|
|
18ff03acdf | ||
|
|
aa27a09801 | ||
|
|
a8d7645004 | ||
|
|
081aafb914 | ||
|
|
5a5ba08c23 | ||
|
|
91b92c5613 | ||
|
|
bd5bc9cda0 | ||
|
|
db684eb33e | ||
|
|
a07cfdb683 | ||
|
|
b956a2c834 | ||
|
|
ba38688a83 | ||
|
|
3429e00721 | ||
|
|
32a6bd78d8 | ||
|
|
b2cedc5332 | ||
|
|
94bbed80d0 | ||
|
|
b4ecb6f2db | ||
|
|
3b5665fe92 | ||
|
|
b4f4ef9c5b | ||
|
|
3c4c05fb3e | ||
|
|
b0cad59508 | ||
|
|
d4030e72e4 | ||
|
|
481f7e3bfa | ||
|
|
c35243e215 | ||
|
|
00d8849a28 | ||
|
|
6b9ce935cd | ||
|
|
e440aba0d2 | ||
|
|
574d459f4e | ||
|
|
5fa0931a89 | ||
|
|
748b13850a | ||
|
|
9a09a6a447 | ||
|
|
79c56c924f | ||
|
|
eef73953cb | ||
|
|
781682f4ee | ||
|
|
4a10806352 | ||
|
|
13ae2f08ee | ||
|
|
3e8aeccc87 | ||
|
|
de39e0093a | ||
|
|
943f52aedf | ||
|
|
46eb2f439d | ||
|
|
4f5c519636 | ||
|
|
8f6677974e | ||
|
|
0f5cbc35a2 | ||
|
|
c54b1e037a | ||
|
|
0d19be2196 | ||
|
|
c1b579ec5d | ||
|
|
0a8246c676 | ||
|
|
ea02453f63 | ||
|
|
d1942da317 | ||
|
|
ed9764f923 | ||
|
|
3b5ed81216 | ||
|
|
12d0d4140e | ||
|
|
d6c8008978 | ||
|
|
488ca0fcc5 | ||
|
|
dfd15cadab | ||
|
|
1613257bdc | ||
|
|
1061580118 | ||
|
|
7184828a58 | ||
|
|
0428adff03 | ||
|
|
04246f0a63 | ||
|
|
61df58d651 | ||
|
|
1bd9a440e8 | ||
|
|
d82c8eb945 | ||
|
|
becbad7ea4 | ||
|
|
2335796a28 | ||
|
|
c6330b64f6 | ||
|
|
df57a23512 | ||
|
|
aea71cf0af | ||
|
|
fb54386f8d | ||
|
|
4d931b6109 | ||
|
|
407c7a10f5 | ||
|
|
16fa4d1d17 | ||
|
|
1ecccd43d4 | ||
|
|
2edbb1cf8b | ||
|
|
8dccbe8029 | ||
|
|
031c833e4d | ||
|
|
890cc46825 | ||
|
|
6b0f7e8512 | ||
|
|
7a220921f0 | ||
|
|
7ef9acda5d | ||
|
|
2a6d62e6f7 | ||
|
|
42b50bd7f7 | ||
|
|
2c3f44ae11 | ||
|
|
b7662f16e5 | ||
|
|
5bc535a8d2 | ||
|
|
3ec9c7ae6e | ||
|
|
e326d0c756 | ||
|
|
7c5434a99f | ||
|
|
26d9256ee9 | ||
|
|
053e761d8f | ||
|
|
5861b52cff | ||
|
|
66193d7283 | ||
|
|
dfb07f359e | ||
|
|
6fe1433497 | ||
|
|
01ace109ba | ||
|
|
8e01acaa12 | ||
|
|
7bbec8dbcb | ||
|
|
10375086ed | ||
|
|
dd367daac9 | ||
|
|
27063d0c32 | ||
|
|
80ff0282c3 | ||
|
|
e973e406a3 | ||
|
|
c64776029e | ||
|
|
5d7d0a922d | ||
|
|
c2c96c4219 | ||
|
|
3e9ed08c53 | ||
|
|
b7df9026c0 | ||
|
|
6527c6357b | ||
|
|
fad333256c | ||
|
|
8753811fe1 | ||
|
|
237752ff62 | ||
|
|
743244a69c | ||
|
|
9f89737986 | ||
|
|
508a5c5f66 | ||
|
|
d84394efa0 | ||
|
|
dd613d48bc | ||
|
|
2e8e500d4f | ||
|
|
48f866dcc6 | ||
|
|
ec4d3e4f9b | ||
|
|
38ddfab1e0 | ||
|
|
353b7e4438 | ||
|
|
7076c9a0ff | ||
|
|
2f42a8714c | ||
|
|
fdf6fc32ff | ||
|
|
f2188b33c6 | ||
|
|
f93fead8f2 | ||
|
|
050f3791cc | ||
|
|
94326fd964 | ||
|
|
f26f3b606d | ||
|
|
7cbfa76be4 | ||
|
|
d896e71ae9 | ||
|
|
ca79d99ec4 | ||
|
|
95f77ef81d | ||
|
|
c4e7d26b70 | ||
|
|
ea49a1a07b | ||
|
|
784223c67f | ||
|
|
77aa2c9a9d | ||
|
|
48145fb234 | ||
|
|
49730cadee | ||
|
|
0b197501e1 | ||
|
|
8b0c246a7b | ||
|
|
9c4face1ae | ||
|
|
952e2e6631 | ||
|
|
4766910413 | ||
|
|
3c2f97a8d2 | ||
|
|
f75730f165 | ||
|
|
b596e62a61 | ||
|
|
1349d48339 | ||
|
|
d69ea5fda6 | ||
|
|
9b68062ba7 | ||
|
|
b217019723 | ||
|
|
a37a254a68 | ||
|
|
5258699f20 | ||
|
|
483bebb003 | ||
|
|
8ca8052a8d | ||
|
|
d68b1144b8 | ||
|
|
42c39b6be3 | ||
|
|
bb82b9d168 | ||
|
|
b1f865d461 | ||
|
|
8e75c6be50 | ||
|
|
06a5f9188d | ||
|
|
370a991208 | ||
|
|
6deb77dd4d | ||
|
|
9e3172cb04 | ||
|
|
426c6b9a72 | ||
|
|
d148bdedcd | ||
|
|
23140e3bf7 | ||
|
|
2f023803e7 | ||
|
|
d658b5fc38 | ||
|
|
68cd84c330 | ||
|
|
0bd82a43d3 | ||
|
|
7fdf42b699 | ||
|
|
aeb0e9aac3 | ||
|
|
1099a3bdf0 | ||
|
|
aa3458f69c | ||
|
|
0186cbb7b7 | ||
|
|
fa36e94c4b | ||
|
|
ad83e70cf5 | ||
|
|
4a0377c0a1 | ||
|
|
83a3241830 | ||
|
|
f299b351e3 | ||
|
|
3880e4ef47 | ||
|
|
f205e918d9 | ||
|
|
42b0b9306b | ||
|
|
483659c319 | ||
|
|
add14dd27c | ||
|
|
61516a5e97 | ||
|
|
17418039e1 | ||
|
|
25cae61211 | ||
|
|
db98c7440e | ||
|
|
3783ae2234 | ||
|
|
3e8732b230 | ||
|
|
b39bca9458 | ||
|
|
d263334030 | ||
|
|
b2cea62189 | ||
|
|
d6b886c69b | ||
|
|
38fb9ea41e | ||
|
|
a922aaa68e | ||
|
|
4f2e36ca46 | ||
|
|
f367627cac | ||
|
|
7a7fcf10ad | ||
|
|
b9bd2734eb | ||
|
|
9c7bd4f5d5 | ||
|
|
362d47f91f | ||
|
|
a18792c397 | ||
|
|
0e2ddb2f16 | ||
|
|
bcfadd6657 | ||
|
|
021cf1a2b4 | ||
|
|
acf86be516 | ||
|
|
dd93eb88f2 | ||
|
|
e06f9e35b3 | ||
|
|
c0424aba7e | ||
|
|
b468254d73 | ||
|
|
15e3e92ec2 | ||
|
|
ee403fd83a | ||
|
|
05f266ac10 | ||
|
|
f52c0026dd | ||
|
|
a284107249 | ||
|
|
a2e25e7940 | ||
|
|
d45a0161cf | ||
|
|
c7a5d15e7a | ||
|
|
3cb2241b1d | ||
|
|
b236821661 | ||
|
|
fc75b0bd21 | ||
|
|
a9fc84d568 | ||
|
|
b15c6d887d | ||
|
|
c2f89978ff | ||
|
|
a004153223 | ||
|
|
dde2bbcbe7 | ||
|
|
7bd572f3ec | ||
|
|
486011dceb | ||
|
|
01c45633b7 | ||
|
|
5320d0ecaa | ||
|
|
757ba03918 | ||
|
|
948db69cc9 | ||
|
|
92f363926e | ||
|
|
d0ff144753 | ||
|
|
943efbb3ed | ||
|
|
6962de4b1f | ||
|
|
6f7c0c23d1 | ||
|
|
14eccc70da | ||
|
|
d4b48cec5d | ||
|
|
2d23c5351f | ||
|
|
b5dfaf170a | ||
|
|
c372591f36 | ||
|
|
36d1308aa6 | ||
|
|
b0d6ed3844 | ||
|
|
5818366d92 | ||
|
|
e5bca74b9d | ||
|
|
82dd1e4be9 | ||
|
|
d0b77639c2 | ||
|
|
6edb0f66d5 | ||
|
|
c458c13af7 | ||
|
|
bb7875edd4 | ||
|
|
6f54fb90eb | ||
|
|
4d1e7c536f | ||
|
|
59cc200f92 | ||
|
|
c6093430ae | ||
|
|
23172bcdd0 | ||
|
|
aea2dab0d7 | ||
|
|
4d26e144ab | ||
|
|
c391fcd345 | ||
|
|
ece743342a | ||
|
|
02babbe340 | ||
|
|
e27b6d050c | ||
|
|
86e2de8d10 | ||
|
|
b4526f926d | ||
|
|
14f04878d1 | ||
|
|
830fb3b752 | ||
|
|
9a336da359 | ||
|
|
6cec49ce7e | ||
|
|
6c28edea55 | ||
|
|
d7870d672e | ||
|
|
5bd9228b4a | ||
|
|
6392cf5a2f | ||
|
|
6a2e2b704e | ||
|
|
ecec803388 | ||
|
|
848965e7f0 | ||
|
|
478af5f01e | ||
|
|
14decb7387 | ||
|
|
323d0d5ba0 | ||
|
|
9bfa6ac1a1 | ||
|
|
c8af817eeb | ||
|
|
d24d3ce487 | ||
|
|
60a81dfbd8 | ||
|
|
8896a59dff | ||
|
|
7fe16d99be | ||
|
|
c3af88dfc1 | ||
|
|
5c8f0cc966 | ||
|
|
2a6c50c893 | ||
|
|
7a8d796ac1 | ||
|
|
8b3b71bce3 | ||
|
|
83da4e9248 | ||
|
|
2c879095d9 | ||
|
|
13344fbb62 | ||
|
|
2fe9ad595f | ||
|
|
0f798289f0 | ||
|
|
01104cc1d3 | ||
|
|
d61b5827fd | ||
|
|
d18cc81531 | ||
|
|
c96d7ae226 | ||
|
|
9535aef59b | ||
|
|
82f6fca06f | ||
|
|
627b36a53b | ||
|
|
2af78a3874 | ||
|
|
7c7109edf4 | ||
|
|
0fa23b83e6 | ||
|
|
e53c71543a | ||
|
|
fa64f7b6aa | ||
|
|
eaac3a64f8 | ||
|
|
4eabc45dfc | ||
|
|
5c5e2a0f2f | ||
|
|
559a5d146a | ||
|
|
df46c58cb8 | ||
|
|
1f43132363 | ||
|
|
17369a20de | ||
|
|
c83dae4c70 | ||
|
|
c2f44a51c4 | ||
|
|
3da44d1215 | ||
|
|
f6709e357f | ||
|
|
45d5511fd7 | ||
|
|
198c5d23fd | ||
|
|
c41caeaf64 | ||
|
|
b6c542b0e7 | ||
|
|
2d62275a08 | ||
|
|
971ea81861 | ||
|
|
9e9cc7859c | ||
|
|
8898f5fe52 | ||
|
|
40be69ae8e | ||
|
|
17eec81071 | ||
|
|
c9bbbd18ec | ||
|
|
e08eda18d5 | ||
|
|
d2c03a6651 | ||
|
|
0a1e920659 | ||
|
|
cd58df820e | ||
|
|
1a5467aec8 | ||
|
|
0dcb64dca3 | ||
|
|
b703102d9b | ||
|
|
3c2ef75b50 | ||
|
|
4fa530354d | ||
|
|
eeeb30dc3f | ||
|
|
870fc2e53e | ||
|
|
79ae0da927 | ||
|
|
e179bda57a | ||
|
|
8e0c15e32e | ||
|
|
ff844f6760 | ||
|
|
bc96ac85f4 | ||
|
|
33b328e3d5 | ||
|
|
dcda8d1c7a | ||
|
|
5fd2bd225f | ||
|
|
2db8859076 | ||
|
|
6eff167a28 | ||
|
|
9fecb69b84 | ||
|
|
0539aa38e5 | ||
|
|
fe9caad391 | ||
|
|
ceae2928aa | ||
|
|
0e6934abe5 | ||
|
|
a2e7c92f99 | ||
|
|
643a8717b4 | ||
|
|
f21127fd4a | ||
|
|
0bc8005100 | ||
|
|
67efc1f68f | ||
|
|
dfebf60e68 | ||
|
|
26e7d134ce | ||
|
|
c414242f13 | ||
|
|
33e60725b1 | ||
|
|
f21b0985cc | ||
|
|
71e9548c20 | ||
|
|
fc64abea5c | ||
|
|
413e89c955 | ||
|
|
439041c2f4 | ||
|
|
530de4d809 | ||
|
|
5e45bdeeda | ||
|
|
081eba903f | ||
|
|
0def045611 | ||
|
|
e20cc6a90f | ||
|
|
7dd83dd2d1 | ||
|
|
1240807b9f | ||
|
|
ad7d6624de | ||
|
|
06b089ba13 | ||
|
|
e1302bcf17 | ||
|
|
cfdc7db79a | ||
|
|
50de873453 | ||
|
|
a4ae7b2059 | ||
|
|
d90abdcb44 | ||
|
|
4a31045fd9 | ||
|
|
249155987d | ||
|
|
2ae7fc244b | ||
|
|
fafa70c6bc | ||
|
|
49162a7a64 | ||
|
|
328e6b3e28 | ||
|
|
5441db9b18 | ||
|
|
06bfa4f1a1 | ||
|
|
a530712491 | ||
|
|
3c8cfe9b76 | ||
|
|
57b4ce96e4 | ||
|
|
63c7d64143 | ||
|
|
1784327c47 | ||
|
|
a63ec83d5f | ||
|
|
d661516b02 | ||
|
|
ba020245f9 | ||
|
|
79fefc1ff9 | ||
|
|
eac169b6da | ||
|
|
a60d293759 | ||
|
|
b0063f8db6 | ||
|
|
632abdd87b | ||
|
|
d9b01ca5de | ||
|
|
adb7db9229 | ||
|
|
e4f7aec965 | ||
|
|
768a8c1062 | ||
|
|
318c5000ce | ||
|
|
70f334e1a3 | ||
|
|
279b53a705 | ||
|
|
a72a3ce5f3 | ||
|
|
979aea5212 | ||
|
|
34d3c63384 | ||
|
|
cf4af2692b | ||
|
|
d335ca5a8d | ||
|
|
9cac2c1457 | ||
|
|
523b992b4c | ||
|
|
02be490466 | ||
|
|
45ae3978f6 | ||
|
|
f983194d7e | ||
|
|
ab8373b989 | ||
|
|
4bef2c48eb | ||
|
|
21e2a769eb | ||
|
|
fd8369142a | ||
|
|
5dea221ad5 | ||
|
|
235c29913a | ||
|
|
0870407f65 | ||
|
|
e8156c6bd9 | ||
|
|
e7f9486aa1 | ||
|
|
53b9fd2110 | ||
|
|
4d4e474464 | ||
|
|
a58b41e7d2 | ||
|
|
4db05e97c5 | ||
|
|
3a668232c8 | ||
|
|
d2622a5d86 | ||
|
|
d11db8a67a | ||
|
|
98b6102e56 | ||
|
|
0db8613a21 | ||
|
|
94a6cb2cff | ||
|
|
5b92575ed3 | ||
|
|
47b02c0480 | ||
|
|
691be54ca2 | ||
|
|
22ea8ebe25 | ||
|
|
bd71635c49 | ||
|
|
830bc3eac3 | ||
|
|
2d72bf4308 | ||
|
|
f4e694afa7 | ||
|
|
55610bae70 | ||
|
|
08351e0df2 | ||
|
|
7489771ad2 | ||
|
|
ea8023e51f | ||
|
|
8a9693a28e | ||
|
|
724fba4af9 | ||
|
|
beca1cbf96 | ||
|
|
b74d2ae9fa | ||
|
|
ec82a0154b | ||
|
|
0ea8dbea10 | ||
|
|
a131f44247 | ||
|
|
0423aedffc | ||
|
|
afc89cdd95 | ||
|
|
541606e00d | ||
|
|
c53fd5fc9a | ||
|
|
bc3dd06b26 | ||
|
|
fd39808ed8 | ||
|
|
a1b7cb5330 | ||
|
|
ac27fae712 | ||
|
|
f6270ec395 | ||
|
|
e9c70f8b1c | ||
|
|
50688e1159 | ||
|
|
8417fea3bf | ||
|
|
f5150d32af | ||
|
|
2263823f75 | ||
|
|
a882263033 | ||
|
|
24d2431522 | ||
|
|
fd27e7bd43 | ||
|
|
4dfe36cdc1 | ||
|
|
fc49be1e05 | ||
|
|
d06d94c767 | ||
|
|
66786651b0 | ||
|
|
e9b499b82d | ||
|
|
e6e3e686c6 | ||
|
|
1e6ba0cdc4 | ||
|
|
75db4c29b8 | ||
|
|
914d3e6a2b | ||
|
|
ff678a5ad7 | ||
|
|
46442ef50c | ||
|
|
7d8fde82e6 | ||
|
|
99cf057906 | ||
|
|
59d3d66f91 | ||
|
|
be73c0fe43 | ||
|
|
e5afc6f029 | ||
|
|
8816d0a9ac | ||
|
|
229837b14c | ||
|
|
94b068a40f | ||
|
|
2f0dfc4d74 | ||
|
|
3391c44107 | ||
|
|
35aae588b8 | ||
|
|
c19585e22a | ||
|
|
77946585b1 | ||
|
|
88a35fd162 | ||
|
|
7d8d4a03fb | ||
|
|
1a68d34663 | ||
|
|
72a0ff706d | ||
|
|
420e43d47d | ||
|
|
3c749d4774 | ||
|
|
d4310a7f3b | ||
|
|
f892d88c10 | ||
|
|
d226709836 | ||
|
|
fbfd03fe5c | ||
|
|
f513001798 | ||
|
|
31aa0ddabe | ||
|
|
767184cf3c | ||
|
|
fe86a9ed02 | ||
|
|
9be53e746f | ||
|
|
8b6f50d0cc | ||
|
|
80dc28bfb5 | ||
|
|
983e1abf48 | ||
|
|
ff65b82671 | ||
|
|
0b26c69222 | ||
|
|
904d714d6d | ||
|
|
2aed93a576 | ||
|
|
d1af42e9ad | ||
|
|
9f31addfa5 | ||
|
|
d56ea7e6c4 | ||
|
|
1cbe271ad5 | ||
|
|
33db3c377f | ||
|
|
a0535ef64d | ||
|
|
392ba18ff7 | ||
|
|
e872f9e928 | ||
|
|
04685a8179 | ||
|
|
55fbe68e62 | ||
|
|
f51e1f0cc8 | ||
|
|
d31b62d44d | ||
|
|
9fd90e26f7 | ||
|
|
dbea0c9361 | ||
|
|
201cb61f84 | ||
|
|
71141e830a | ||
|
|
7dc8bf3aa4 | ||
|
|
0fef94cfdb | ||
|
|
a9b45967ce | ||
|
|
0928bca531 | ||
|
|
77f73a79df | ||
|
|
279445d6bc | ||
|
|
54778ee1e1 | ||
|
|
4efcda534d | ||
|
|
45ac5cb2fa | ||
|
|
6d045a9403 | ||
|
|
8c57a77d7e | ||
|
|
1f585d6719 | ||
|
|
6c111f55aa | ||
|
|
b01693f426 | ||
|
|
e37232aeb4 | ||
|
|
1c1c7dad7b | ||
|
|
b70b81f4cc | ||
|
|
e3cf41a666 | ||
|
|
851a307c23 | ||
|
|
183d3749f0 | ||
|
|
3fe513f9e0 | ||
|
|
81bee2bbc6 | ||
|
|
34719da000 | ||
|
|
df8a3d9c60 | ||
|
|
53dea9b069 | ||
|
|
186bae2bd4 | ||
|
|
f83c8828f0 | ||
|
|
509d064286 | ||
|
|
2d039e393a | ||
|
|
9ab88d9387 | ||
|
|
882a2a0e52 | ||
|
|
c6ce1d8c67 | ||
|
|
77e1a2e4be | ||
|
|
b99f53fda3 | ||
|
|
a7f64cf7aa | ||
|
|
8ebc0f2b24 | ||
|
|
5330dc34bc | ||
|
|
4854a9e320 | ||
|
|
71be1a9e28 | ||
|
|
d0ae09c7e2 | ||
|
|
a25bd06138 | ||
|
|
1b55076897 | ||
|
|
5eac7974c9 | ||
|
|
3afd6e9f51 | ||
|
|
05c107ba9c | ||
|
|
99b00daf87 | ||
|
|
8ddb99f62f | ||
|
|
47dec485e5 | ||
|
|
f191b4f35c | ||
|
|
e24e3c0612 | ||
|
|
1dfac0a8b9 | ||
|
|
f5cc151618 | ||
|
|
1ff3a61de6 | ||
|
|
81d5b651d2 | ||
|
|
ea4ed7cdd1 | ||
|
|
e30ea5206f | ||
|
|
c188f6e3cb | ||
|
|
2fb8999ac2 | ||
|
|
9c9bfc1a98 | ||
|
|
f7a87789ab | ||
|
|
7bcf02a0b4 | ||
|
|
fcd1733787 | ||
|
|
c04ec5953f | ||
|
|
63aa16b97c | ||
|
|
cafbf860be | ||
|
|
700b0bc776 | ||
|
|
98ca36e8f5 | ||
|
|
25130e3c82 | ||
|
|
dc463d1c2c | ||
|
|
89d30acbc5 | ||
|
|
be405d2311 | ||
|
|
acbe42775c | ||
|
|
42d8772dd6 | ||
|
|
81ef922f02 | ||
|
|
d6e18c8a35 | ||
|
|
4993a5c6c0 | ||
|
|
052382af89 | ||
|
|
18f7102461 | ||
|
|
ddbb2bea8a | ||
|
|
27131b43cb | ||
|
|
e8c2483432 | ||
|
|
fd495574a4 | ||
|
|
12f85b3d1f | ||
|
|
47d88bcfa7 | ||
|
|
e4dacaf0d2 | ||
|
|
2906a2d007 | ||
|
|
3000fdc33c | ||
|
|
076bde34a2 | ||
|
|
836c563c89 | ||
|
|
78c0419007 | ||
|
|
9dd5b91cea | ||
|
|
b4c8b00c0e | ||
|
|
430e72b424 | ||
|
|
135a8102f0 | ||
|
|
c9cf4ad02a | ||
|
|
3001809bc3 | ||
|
|
9e77ff328e | ||
|
|
efddcb18a3 | ||
|
|
54ff2bec90 | ||
|
|
287ed83de7 | ||
|
|
dd13924a67 | ||
|
|
a050a3b80f | ||
|
|
f1201eaebc | ||
|
|
68dd50ecbc | ||
|
|
2129cf5aa6 | ||
|
|
cf1bdcef46 | ||
|
|
7a879e2abf | ||
|
|
22878b6f89 | ||
|
|
e99064ca18 | ||
|
|
b93661508e | ||
|
|
27ade6c420 | ||
|
|
473249d605 | ||
|
|
62cf65ce0f | ||
|
|
c4f6aa2f90 | ||
|
|
9ca112c362 | ||
|
|
cdcc17ee37 | ||
|
|
4f3e1587b1 | ||
|
|
b18c92f515 | ||
|
|
3270edcf87 | ||
|
|
c0e8dd97ae | ||
|
|
3a0ae3df58 | ||
|
|
d6361dfee4 | ||
|
|
b61692b667 | ||
|
|
2815688c7e | ||
|
|
78a78a17cc | ||
|
|
e202d4e4a5 | ||
|
|
8b585db238 | ||
|
|
e288549c9e | ||
|
|
f71f129e3b | ||
|
|
ee688166ab | ||
|
|
ed66c37de2 | ||
|
|
a5c6f8023b | ||
|
|
c82da8c9c8 | ||
|
|
07d1358e08 | ||
|
|
1212109c03 | ||
|
|
d4db4fcac3 | ||
|
|
1f46c79396 | ||
|
|
199419ae62 | ||
|
|
39a4d55866 | ||
|
|
c84e1d0f0e | ||
|
|
302deeb122 | ||
|
|
b2a6cdec4e | ||
|
|
87676fad4d | ||
|
|
75087095b1 | ||
|
|
d0a5032723 | ||
|
|
2d6a7c2cf7 | ||
|
|
56e9158dee | ||
|
|
3ba312116b | ||
|
|
e6ab3ddb7d | ||
|
|
8ed0fec364 | ||
|
|
ddfdbd75b8 | ||
|
|
00e21af5bb | ||
|
|
51a17a7a0f | ||
|
|
fa58672f09 | ||
|
|
4f7f5023df | ||
|
|
4838a9690e | ||
|
|
edcbfb52eb | ||
|
|
5af8bb7c8e |
+2
-1
@@ -1,5 +1,6 @@
|
|||||||
|
.*
|
||||||
|
*~
|
||||||
Makefile
|
Makefile
|
||||||
SimGear.spec
|
|
||||||
*.o
|
*.o
|
||||||
lib*.a
|
lib*.a
|
||||||
.*.swp
|
.*.swp
|
||||||
|
|||||||
Vendored
+5
@@ -0,0 +1,5 @@
|
|||||||
|
if (NOT SYSTEM_EXPAT)
|
||||||
|
add_subdirectory(expat)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_subdirectory(utf8)
|
||||||
Vendored
+33
@@ -0,0 +1,33 @@
|
|||||||
|
|
||||||
|
configure_file (
|
||||||
|
"${PROJECT_SOURCE_DIR}/3rdparty/expat/expat_config_cmake.in"
|
||||||
|
"${PROJECT_BINARY_DIR}/3rdparty/expat/expat_config.h"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(expat_sources
|
||||||
|
asciitab.h
|
||||||
|
hashtable.h
|
||||||
|
iasciitab.h
|
||||||
|
latin1tab.h
|
||||||
|
nametab.h
|
||||||
|
utf8tab.h
|
||||||
|
xmldef.h
|
||||||
|
xmlparse.h
|
||||||
|
xmlrole.h
|
||||||
|
xmltok.h
|
||||||
|
xmltok_impl.h
|
||||||
|
hashtable.c
|
||||||
|
xmlparse.c
|
||||||
|
xmlrole.c
|
||||||
|
xmltok.c
|
||||||
|
internal.h
|
||||||
|
ascii.h
|
||||||
|
sg_expat.h
|
||||||
|
sg_expat_external.h
|
||||||
|
)
|
||||||
|
|
||||||
|
foreach(s ${expat_sources})
|
||||||
|
set_property(GLOBAL
|
||||||
|
APPEND PROPERTY LOCAL_EXPAT_SOURCES
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/${s}")
|
||||||
|
endforeach()
|
||||||
+1
-1
@@ -15,7 +15,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "expat_external.h"
|
#include "sg_expat_external.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
+1
-1
@@ -23,7 +23,7 @@
|
|||||||
#endif /* ndef COMPILED_FROM_DSP */
|
#endif /* ndef COMPILED_FROM_DSP */
|
||||||
|
|
||||||
#include "ascii.h"
|
#include "ascii.h"
|
||||||
#include "expat.h"
|
#include "sg_expat.h"
|
||||||
|
|
||||||
#ifdef XML_UNICODE
|
#ifdef XML_UNICODE
|
||||||
#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
|
#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
|
||||||
+1
-1
@@ -18,7 +18,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif /* ndef COMPILED_FROM_DSP */
|
#endif /* ndef COMPILED_FROM_DSP */
|
||||||
|
|
||||||
#include "expat_external.h"
|
#include "sg_expat_external.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "xmlrole.h"
|
#include "xmlrole.h"
|
||||||
#include "ascii.h"
|
#include "ascii.h"
|
||||||
+1
-1
@@ -18,7 +18,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif /* ndef COMPILED_FROM_DSP */
|
#endif /* ndef COMPILED_FROM_DSP */
|
||||||
|
|
||||||
#include "expat_external.h"
|
#include "sg_expat_external.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "xmltok.h"
|
#include "xmltok.h"
|
||||||
#include "nametab.h"
|
#include "nametab.h"
|
||||||
Vendored
+17
@@ -0,0 +1,17 @@
|
|||||||
|
include (SimGearComponent)
|
||||||
|
|
||||||
|
set(HEADERS
|
||||||
|
source/utf8.h
|
||||||
|
)
|
||||||
|
|
||||||
|
set(HEADERS_utf8
|
||||||
|
source/utf8/checked.h
|
||||||
|
source/utf8/core.h
|
||||||
|
source/utf8/unchecked.h
|
||||||
|
)
|
||||||
|
|
||||||
|
set(SOURCES
|
||||||
|
)
|
||||||
|
|
||||||
|
simgear_component(utf8 3rdparty/utf8 "${SOURCES}" "${HEADERS}")
|
||||||
|
simgear_component(utf8-internal 3rdparty/utf8/utf8 "" "${HEADERS_utf8}")
|
||||||
Vendored
+12
@@ -0,0 +1,12 @@
|
|||||||
|
utf8 cpp library
|
||||||
|
Release 2.3.4
|
||||||
|
|
||||||
|
A minor bug fix release. Thanks to all who reported bugs.
|
||||||
|
|
||||||
|
Note: Version 2.3.3 contained a regression, and therefore was removed.
|
||||||
|
|
||||||
|
Changes from version 2.3.2
|
||||||
|
- Bug fix [39]: checked.h Line 273 and unchecked.h Line 182 have an extra ';'
|
||||||
|
- Bug fix [36]: replace_invalid() only works with back_inserter
|
||||||
|
|
||||||
|
Files included in the release: utf8.h, core.h, checked.h, unchecked.h, utf8cpp.html, ReleaseNotes
|
||||||
Vendored
+1789
File diff suppressed because it is too large
Load Diff
Vendored
+34
@@ -0,0 +1,34 @@
|
|||||||
|
// Copyright 2006 Nemanja Trifunovic
|
||||||
|
|
||||||
|
/*
|
||||||
|
Permission is hereby granted, free of charge, to any person or organization
|
||||||
|
obtaining a copy of the software and accompanying documentation covered by
|
||||||
|
this license (the "Software") to use, reproduce, display, distribute,
|
||||||
|
execute, and transmit the Software, and to prepare derivative works of the
|
||||||
|
Software, and to permit third-parties to whom the Software is furnished to
|
||||||
|
do so, all subject to the following:
|
||||||
|
|
||||||
|
The copyright notices in the Software and this entire statement, including
|
||||||
|
the above license grant, this restriction and the following disclaimer,
|
||||||
|
must be included in all copies of the Software, in whole or in part, and
|
||||||
|
all derivative works of the Software, unless such copies or derivative
|
||||||
|
works are solely in the form of machine-executable object code generated by
|
||||||
|
a source language processor.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||||
|
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||||
|
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||||
|
#define UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||||
|
|
||||||
|
#include "utf8/checked.h"
|
||||||
|
#include "utf8/unchecked.h"
|
||||||
|
|
||||||
|
#endif // header guard
|
||||||
Vendored
+327
@@ -0,0 +1,327 @@
|
|||||||
|
// Copyright 2006 Nemanja Trifunovic
|
||||||
|
|
||||||
|
/*
|
||||||
|
Permission is hereby granted, free of charge, to any person or organization
|
||||||
|
obtaining a copy of the software and accompanying documentation covered by
|
||||||
|
this license (the "Software") to use, reproduce, display, distribute,
|
||||||
|
execute, and transmit the Software, and to prepare derivative works of the
|
||||||
|
Software, and to permit third-parties to whom the Software is furnished to
|
||||||
|
do so, all subject to the following:
|
||||||
|
|
||||||
|
The copyright notices in the Software and this entire statement, including
|
||||||
|
the above license grant, this restriction and the following disclaimer,
|
||||||
|
must be included in all copies of the Software, in whole or in part, and
|
||||||
|
all derivative works of the Software, unless such copies or derivative
|
||||||
|
works are solely in the form of machine-executable object code generated by
|
||||||
|
a source language processor.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||||
|
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||||
|
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||||
|
#define UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||||
|
|
||||||
|
#include "core.h"
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
namespace utf8
|
||||||
|
{
|
||||||
|
// Base for the exceptions that may be thrown from the library
|
||||||
|
class exception : public ::std::exception {
|
||||||
|
};
|
||||||
|
|
||||||
|
// Exceptions that may be thrown from the library functions.
|
||||||
|
class invalid_code_point : public exception {
|
||||||
|
uint32_t cp;
|
||||||
|
public:
|
||||||
|
invalid_code_point(uint32_t cp) : cp(cp) {}
|
||||||
|
virtual const char* what() const throw() { return "Invalid code point"; }
|
||||||
|
uint32_t code_point() const {return cp;}
|
||||||
|
};
|
||||||
|
|
||||||
|
class invalid_utf8 : public exception {
|
||||||
|
uint8_t u8;
|
||||||
|
public:
|
||||||
|
invalid_utf8 (uint8_t u) : u8(u) {}
|
||||||
|
virtual const char* what() const throw() { return "Invalid UTF-8"; }
|
||||||
|
uint8_t utf8_octet() const {return u8;}
|
||||||
|
};
|
||||||
|
|
||||||
|
class invalid_utf16 : public exception {
|
||||||
|
uint16_t u16;
|
||||||
|
public:
|
||||||
|
invalid_utf16 (uint16_t u) : u16(u) {}
|
||||||
|
virtual const char* what() const throw() { return "Invalid UTF-16"; }
|
||||||
|
uint16_t utf16_word() const {return u16;}
|
||||||
|
};
|
||||||
|
|
||||||
|
class not_enough_room : public exception {
|
||||||
|
public:
|
||||||
|
virtual const char* what() const throw() { return "Not enough space"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/// The library API - functions intended to be called by the users
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
octet_iterator append(uint32_t cp, octet_iterator result)
|
||||||
|
{
|
||||||
|
if (!utf8::internal::is_code_point_valid(cp))
|
||||||
|
throw invalid_code_point(cp);
|
||||||
|
|
||||||
|
if (cp < 0x80) // one octet
|
||||||
|
*(result++) = static_cast<uint8_t>(cp);
|
||||||
|
else if (cp < 0x800) { // two octets
|
||||||
|
*(result++) = static_cast<uint8_t>((cp >> 6) | 0xc0);
|
||||||
|
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||||
|
}
|
||||||
|
else if (cp < 0x10000) { // three octets
|
||||||
|
*(result++) = static_cast<uint8_t>((cp >> 12) | 0xe0);
|
||||||
|
*(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
|
||||||
|
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||||
|
}
|
||||||
|
else { // four octets
|
||||||
|
*(result++) = static_cast<uint8_t>((cp >> 18) | 0xf0);
|
||||||
|
*(result++) = static_cast<uint8_t>(((cp >> 12) & 0x3f) | 0x80);
|
||||||
|
*(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
|
||||||
|
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator, typename output_iterator>
|
||||||
|
output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement)
|
||||||
|
{
|
||||||
|
while (start != end) {
|
||||||
|
octet_iterator sequence_start = start;
|
||||||
|
internal::utf_error err_code = utf8::internal::validate_next(start, end);
|
||||||
|
switch (err_code) {
|
||||||
|
case internal::UTF8_OK :
|
||||||
|
for (octet_iterator it = sequence_start; it != start; ++it)
|
||||||
|
*out++ = *it;
|
||||||
|
break;
|
||||||
|
case internal::NOT_ENOUGH_ROOM:
|
||||||
|
throw not_enough_room();
|
||||||
|
case internal::INVALID_LEAD:
|
||||||
|
out = utf8::append (replacement, out);
|
||||||
|
++start;
|
||||||
|
break;
|
||||||
|
case internal::INCOMPLETE_SEQUENCE:
|
||||||
|
case internal::OVERLONG_SEQUENCE:
|
||||||
|
case internal::INVALID_CODE_POINT:
|
||||||
|
out = utf8::append (replacement, out);
|
||||||
|
++start;
|
||||||
|
// just one replacement mark for the sequence
|
||||||
|
while (start != end && utf8::internal::is_trail(*start))
|
||||||
|
++start;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator, typename output_iterator>
|
||||||
|
inline output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out)
|
||||||
|
{
|
||||||
|
static const uint32_t replacement_marker = utf8::internal::mask16(0xfffd);
|
||||||
|
return utf8::replace_invalid(start, end, out, replacement_marker);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
uint32_t next(octet_iterator& it, octet_iterator end)
|
||||||
|
{
|
||||||
|
uint32_t cp = 0;
|
||||||
|
internal::utf_error err_code = utf8::internal::validate_next(it, end, cp);
|
||||||
|
switch (err_code) {
|
||||||
|
case internal::UTF8_OK :
|
||||||
|
break;
|
||||||
|
case internal::NOT_ENOUGH_ROOM :
|
||||||
|
throw not_enough_room();
|
||||||
|
case internal::INVALID_LEAD :
|
||||||
|
case internal::INCOMPLETE_SEQUENCE :
|
||||||
|
case internal::OVERLONG_SEQUENCE :
|
||||||
|
throw invalid_utf8(*it);
|
||||||
|
case internal::INVALID_CODE_POINT :
|
||||||
|
throw invalid_code_point(cp);
|
||||||
|
}
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
uint32_t peek_next(octet_iterator it, octet_iterator end)
|
||||||
|
{
|
||||||
|
return utf8::next(it, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
uint32_t prior(octet_iterator& it, octet_iterator start)
|
||||||
|
{
|
||||||
|
// can't do much if it == start
|
||||||
|
if (it == start)
|
||||||
|
throw not_enough_room();
|
||||||
|
|
||||||
|
octet_iterator end = it;
|
||||||
|
// Go back until we hit either a lead octet or start
|
||||||
|
while (utf8::internal::is_trail(*(--it)))
|
||||||
|
if (it == start)
|
||||||
|
throw invalid_utf8(*it); // error - no lead byte in the sequence
|
||||||
|
return utf8::peek_next(it, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deprecated in versions that include "prior"
|
||||||
|
template <typename octet_iterator>
|
||||||
|
uint32_t previous(octet_iterator& it, octet_iterator pass_start)
|
||||||
|
{
|
||||||
|
octet_iterator end = it;
|
||||||
|
while (utf8::internal::is_trail(*(--it)))
|
||||||
|
if (it == pass_start)
|
||||||
|
throw invalid_utf8(*it); // error - no lead byte in the sequence
|
||||||
|
octet_iterator temp = it;
|
||||||
|
return utf8::next(temp, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator, typename distance_type>
|
||||||
|
void advance (octet_iterator& it, distance_type n, octet_iterator end)
|
||||||
|
{
|
||||||
|
for (distance_type i = 0; i < n; ++i)
|
||||||
|
utf8::next(it, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
typename std::iterator_traits<octet_iterator>::difference_type
|
||||||
|
distance (octet_iterator first, octet_iterator last)
|
||||||
|
{
|
||||||
|
typename std::iterator_traits<octet_iterator>::difference_type dist;
|
||||||
|
for (dist = 0; first < last; ++dist)
|
||||||
|
utf8::next(first, last);
|
||||||
|
return dist;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename u16bit_iterator, typename octet_iterator>
|
||||||
|
octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result)
|
||||||
|
{
|
||||||
|
while (start != end) {
|
||||||
|
uint32_t cp = utf8::internal::mask16(*start++);
|
||||||
|
// Take care of surrogate pairs first
|
||||||
|
if (utf8::internal::is_lead_surrogate(cp)) {
|
||||||
|
if (start != end) {
|
||||||
|
uint32_t trail_surrogate = utf8::internal::mask16(*start++);
|
||||||
|
if (utf8::internal::is_trail_surrogate(trail_surrogate))
|
||||||
|
cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET;
|
||||||
|
else
|
||||||
|
throw invalid_utf16(static_cast<uint16_t>(trail_surrogate));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw invalid_utf16(static_cast<uint16_t>(cp));
|
||||||
|
|
||||||
|
}
|
||||||
|
// Lone trail surrogate
|
||||||
|
else if (utf8::internal::is_trail_surrogate(cp))
|
||||||
|
throw invalid_utf16(static_cast<uint16_t>(cp));
|
||||||
|
|
||||||
|
result = utf8::append(cp, result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename u16bit_iterator, typename octet_iterator>
|
||||||
|
u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result)
|
||||||
|
{
|
||||||
|
while (start != end) {
|
||||||
|
uint32_t cp = utf8::next(start, end);
|
||||||
|
if (cp > 0xffff) { //make a surrogate pair
|
||||||
|
*result++ = static_cast<uint16_t>((cp >> 10) + internal::LEAD_OFFSET);
|
||||||
|
*result++ = static_cast<uint16_t>((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*result++ = static_cast<uint16_t>(cp);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator, typename u32bit_iterator>
|
||||||
|
octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result)
|
||||||
|
{
|
||||||
|
while (start != end)
|
||||||
|
result = utf8::append(*(start++), result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator, typename u32bit_iterator>
|
||||||
|
u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result)
|
||||||
|
{
|
||||||
|
while (start != end)
|
||||||
|
(*result++) = utf8::next(start, end);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The iterator class
|
||||||
|
template <typename octet_iterator>
|
||||||
|
class iterator : public std::iterator <std::bidirectional_iterator_tag, uint32_t> {
|
||||||
|
octet_iterator it;
|
||||||
|
octet_iterator range_start;
|
||||||
|
octet_iterator range_end;
|
||||||
|
public:
|
||||||
|
iterator () {}
|
||||||
|
explicit iterator (const octet_iterator& octet_it,
|
||||||
|
const octet_iterator& range_start,
|
||||||
|
const octet_iterator& range_end) :
|
||||||
|
it(octet_it), range_start(range_start), range_end(range_end)
|
||||||
|
{
|
||||||
|
if (it < range_start || it > range_end)
|
||||||
|
throw std::out_of_range("Invalid utf-8 iterator position");
|
||||||
|
}
|
||||||
|
// the default "big three" are OK
|
||||||
|
octet_iterator base () const { return it; }
|
||||||
|
uint32_t operator * () const
|
||||||
|
{
|
||||||
|
octet_iterator temp = it;
|
||||||
|
return utf8::next(temp, range_end);
|
||||||
|
}
|
||||||
|
bool operator == (const iterator& rhs) const
|
||||||
|
{
|
||||||
|
if (range_start != rhs.range_start || range_end != rhs.range_end)
|
||||||
|
throw std::logic_error("Comparing utf-8 iterators defined with different ranges");
|
||||||
|
return (it == rhs.it);
|
||||||
|
}
|
||||||
|
bool operator != (const iterator& rhs) const
|
||||||
|
{
|
||||||
|
return !(operator == (rhs));
|
||||||
|
}
|
||||||
|
iterator& operator ++ ()
|
||||||
|
{
|
||||||
|
utf8::next(it, range_end);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
iterator operator ++ (int)
|
||||||
|
{
|
||||||
|
iterator temp = *this;
|
||||||
|
utf8::next(it, range_end);
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
iterator& operator -- ()
|
||||||
|
{
|
||||||
|
utf8::prior(it, range_start);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
iterator operator -- (int)
|
||||||
|
{
|
||||||
|
iterator temp = *this;
|
||||||
|
utf8::prior(it, range_start);
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
}; // class iterator
|
||||||
|
|
||||||
|
} // namespace utf8
|
||||||
|
|
||||||
|
#endif //header guard
|
||||||
|
|
||||||
|
|
||||||
Vendored
+329
@@ -0,0 +1,329 @@
|
|||||||
|
// Copyright 2006 Nemanja Trifunovic
|
||||||
|
|
||||||
|
/*
|
||||||
|
Permission is hereby granted, free of charge, to any person or organization
|
||||||
|
obtaining a copy of the software and accompanying documentation covered by
|
||||||
|
this license (the "Software") to use, reproduce, display, distribute,
|
||||||
|
execute, and transmit the Software, and to prepare derivative works of the
|
||||||
|
Software, and to permit third-parties to whom the Software is furnished to
|
||||||
|
do so, all subject to the following:
|
||||||
|
|
||||||
|
The copyright notices in the Software and this entire statement, including
|
||||||
|
the above license grant, this restriction and the following disclaimer,
|
||||||
|
must be included in all copies of the Software, in whole or in part, and
|
||||||
|
all derivative works of the Software, unless such copies or derivative
|
||||||
|
works are solely in the form of machine-executable object code generated by
|
||||||
|
a source language processor.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||||
|
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||||
|
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||||
|
#define UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
namespace utf8
|
||||||
|
{
|
||||||
|
// The typedefs for 8-bit, 16-bit and 32-bit unsigned integers
|
||||||
|
// You may need to change them to match your system.
|
||||||
|
// These typedefs have the same names as ones from cstdint, or boost/cstdint
|
||||||
|
typedef unsigned char uint8_t;
|
||||||
|
typedef unsigned short uint16_t;
|
||||||
|
typedef unsigned int uint32_t;
|
||||||
|
|
||||||
|
// Helper code - not intended to be directly called by the library users. May be changed at any time
|
||||||
|
namespace internal
|
||||||
|
{
|
||||||
|
// Unicode constants
|
||||||
|
// Leading (high) surrogates: 0xd800 - 0xdbff
|
||||||
|
// Trailing (low) surrogates: 0xdc00 - 0xdfff
|
||||||
|
const uint16_t LEAD_SURROGATE_MIN = 0xd800u;
|
||||||
|
const uint16_t LEAD_SURROGATE_MAX = 0xdbffu;
|
||||||
|
const uint16_t TRAIL_SURROGATE_MIN = 0xdc00u;
|
||||||
|
const uint16_t TRAIL_SURROGATE_MAX = 0xdfffu;
|
||||||
|
const uint16_t LEAD_OFFSET = LEAD_SURROGATE_MIN - (0x10000 >> 10);
|
||||||
|
const uint32_t SURROGATE_OFFSET = 0x10000u - (LEAD_SURROGATE_MIN << 10) - TRAIL_SURROGATE_MIN;
|
||||||
|
|
||||||
|
// Maximum valid value for a Unicode code point
|
||||||
|
const uint32_t CODE_POINT_MAX = 0x0010ffffu;
|
||||||
|
|
||||||
|
template<typename octet_type>
|
||||||
|
inline uint8_t mask8(octet_type oc)
|
||||||
|
{
|
||||||
|
return static_cast<uint8_t>(0xff & oc);
|
||||||
|
}
|
||||||
|
template<typename u16_type>
|
||||||
|
inline uint16_t mask16(u16_type oc)
|
||||||
|
{
|
||||||
|
return static_cast<uint16_t>(0xffff & oc);
|
||||||
|
}
|
||||||
|
template<typename octet_type>
|
||||||
|
inline bool is_trail(octet_type oc)
|
||||||
|
{
|
||||||
|
return ((utf8::internal::mask8(oc) >> 6) == 0x2);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename u16>
|
||||||
|
inline bool is_lead_surrogate(u16 cp)
|
||||||
|
{
|
||||||
|
return (cp >= LEAD_SURROGATE_MIN && cp <= LEAD_SURROGATE_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename u16>
|
||||||
|
inline bool is_trail_surrogate(u16 cp)
|
||||||
|
{
|
||||||
|
return (cp >= TRAIL_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename u16>
|
||||||
|
inline bool is_surrogate(u16 cp)
|
||||||
|
{
|
||||||
|
return (cp >= LEAD_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename u32>
|
||||||
|
inline bool is_code_point_valid(u32 cp)
|
||||||
|
{
|
||||||
|
return (cp <= CODE_POINT_MAX && !utf8::internal::is_surrogate(cp));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
inline typename std::iterator_traits<octet_iterator>::difference_type
|
||||||
|
sequence_length(octet_iterator lead_it)
|
||||||
|
{
|
||||||
|
uint8_t lead = utf8::internal::mask8(*lead_it);
|
||||||
|
if (lead < 0x80)
|
||||||
|
return 1;
|
||||||
|
else if ((lead >> 5) == 0x6)
|
||||||
|
return 2;
|
||||||
|
else if ((lead >> 4) == 0xe)
|
||||||
|
return 3;
|
||||||
|
else if ((lead >> 3) == 0x1e)
|
||||||
|
return 4;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_difference_type>
|
||||||
|
inline bool is_overlong_sequence(uint32_t cp, octet_difference_type length)
|
||||||
|
{
|
||||||
|
if (cp < 0x80) {
|
||||||
|
if (length != 1)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (cp < 0x800) {
|
||||||
|
if (length != 2)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (cp < 0x10000) {
|
||||||
|
if (length != 3)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum utf_error {UTF8_OK, NOT_ENOUGH_ROOM, INVALID_LEAD, INCOMPLETE_SEQUENCE, OVERLONG_SEQUENCE, INVALID_CODE_POINT};
|
||||||
|
|
||||||
|
/// Helper for get_sequence_x
|
||||||
|
template <typename octet_iterator>
|
||||||
|
utf_error increase_safely(octet_iterator& it, octet_iterator end)
|
||||||
|
{
|
||||||
|
if (++it == end)
|
||||||
|
return NOT_ENOUGH_ROOM;
|
||||||
|
|
||||||
|
if (!utf8::internal::is_trail(*it))
|
||||||
|
return INCOMPLETE_SEQUENCE;
|
||||||
|
|
||||||
|
return UTF8_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(IT, END) {utf_error ret = increase_safely(IT, END); if (ret != UTF8_OK) return ret;}
|
||||||
|
|
||||||
|
/// get_sequence_x functions decode utf-8 sequences of the length x
|
||||||
|
template <typename octet_iterator>
|
||||||
|
utf_error get_sequence_1(octet_iterator& it, octet_iterator end, uint32_t& code_point)
|
||||||
|
{
|
||||||
|
if (it == end)
|
||||||
|
return NOT_ENOUGH_ROOM;
|
||||||
|
|
||||||
|
code_point = utf8::internal::mask8(*it);
|
||||||
|
|
||||||
|
return UTF8_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
utf_error get_sequence_2(octet_iterator& it, octet_iterator end, uint32_t& code_point)
|
||||||
|
{
|
||||||
|
if (it == end)
|
||||||
|
return NOT_ENOUGH_ROOM;
|
||||||
|
|
||||||
|
code_point = utf8::internal::mask8(*it);
|
||||||
|
|
||||||
|
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
|
||||||
|
|
||||||
|
code_point = ((code_point << 6) & 0x7ff) + ((*it) & 0x3f);
|
||||||
|
|
||||||
|
return UTF8_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
utf_error get_sequence_3(octet_iterator& it, octet_iterator end, uint32_t& code_point)
|
||||||
|
{
|
||||||
|
if (it == end)
|
||||||
|
return NOT_ENOUGH_ROOM;
|
||||||
|
|
||||||
|
code_point = utf8::internal::mask8(*it);
|
||||||
|
|
||||||
|
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
|
||||||
|
|
||||||
|
code_point = ((code_point << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff);
|
||||||
|
|
||||||
|
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
|
||||||
|
|
||||||
|
code_point += (*it) & 0x3f;
|
||||||
|
|
||||||
|
return UTF8_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
utf_error get_sequence_4(octet_iterator& it, octet_iterator end, uint32_t& code_point)
|
||||||
|
{
|
||||||
|
if (it == end)
|
||||||
|
return NOT_ENOUGH_ROOM;
|
||||||
|
|
||||||
|
code_point = utf8::internal::mask8(*it);
|
||||||
|
|
||||||
|
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
|
||||||
|
|
||||||
|
code_point = ((code_point << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff);
|
||||||
|
|
||||||
|
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
|
||||||
|
|
||||||
|
code_point += (utf8::internal::mask8(*it) << 6) & 0xfff;
|
||||||
|
|
||||||
|
UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
|
||||||
|
|
||||||
|
code_point += (*it) & 0x3f;
|
||||||
|
|
||||||
|
return UTF8_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
utf_error validate_next(octet_iterator& it, octet_iterator end, uint32_t& code_point)
|
||||||
|
{
|
||||||
|
// Save the original value of it so we can go back in case of failure
|
||||||
|
// Of course, it does not make much sense with i.e. stream iterators
|
||||||
|
octet_iterator original_it = it;
|
||||||
|
|
||||||
|
uint32_t cp = 0;
|
||||||
|
// Determine the sequence length based on the lead octet
|
||||||
|
typedef typename std::iterator_traits<octet_iterator>::difference_type octet_difference_type;
|
||||||
|
const octet_difference_type length = utf8::internal::sequence_length(it);
|
||||||
|
|
||||||
|
// Get trail octets and calculate the code point
|
||||||
|
utf_error err = UTF8_OK;
|
||||||
|
switch (length) {
|
||||||
|
case 0:
|
||||||
|
return INVALID_LEAD;
|
||||||
|
case 1:
|
||||||
|
err = utf8::internal::get_sequence_1(it, end, cp);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
err = utf8::internal::get_sequence_2(it, end, cp);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
err = utf8::internal::get_sequence_3(it, end, cp);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
err = utf8::internal::get_sequence_4(it, end, cp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err == UTF8_OK) {
|
||||||
|
// Decoding succeeded. Now, security checks...
|
||||||
|
if (utf8::internal::is_code_point_valid(cp)) {
|
||||||
|
if (!utf8::internal::is_overlong_sequence(cp, length)){
|
||||||
|
// Passed! Return here.
|
||||||
|
code_point = cp;
|
||||||
|
++it;
|
||||||
|
return UTF8_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
err = OVERLONG_SEQUENCE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
err = INVALID_CODE_POINT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Failure branch - restore the original value of the iterator
|
||||||
|
it = original_it;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
inline utf_error validate_next(octet_iterator& it, octet_iterator end) {
|
||||||
|
uint32_t ignored;
|
||||||
|
return utf8::internal::validate_next(it, end, ignored);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
/// The library API - functions intended to be called by the users
|
||||||
|
|
||||||
|
// Byte order mark
|
||||||
|
const uint8_t bom[] = {0xef, 0xbb, 0xbf};
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
octet_iterator find_invalid(octet_iterator start, octet_iterator end)
|
||||||
|
{
|
||||||
|
octet_iterator result = start;
|
||||||
|
while (result != end) {
|
||||||
|
utf8::internal::utf_error err_code = utf8::internal::validate_next(result, end);
|
||||||
|
if (err_code != internal::UTF8_OK)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
inline bool is_valid(octet_iterator start, octet_iterator end)
|
||||||
|
{
|
||||||
|
return (utf8::find_invalid(start, end) == end);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
inline bool starts_with_bom (octet_iterator it, octet_iterator end)
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
((it != end) && (utf8::internal::mask8(*it++)) == bom[0]) &&
|
||||||
|
((it != end) && (utf8::internal::mask8(*it++)) == bom[1]) &&
|
||||||
|
((it != end) && (utf8::internal::mask8(*it)) == bom[2])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Deprecated in release 2.3
|
||||||
|
template <typename octet_iterator>
|
||||||
|
inline bool is_bom (octet_iterator it)
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
(utf8::internal::mask8(*it++)) == bom[0] &&
|
||||||
|
(utf8::internal::mask8(*it++)) == bom[1] &&
|
||||||
|
(utf8::internal::mask8(*it)) == bom[2]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} // namespace utf8
|
||||||
|
|
||||||
|
#endif // header guard
|
||||||
|
|
||||||
|
|
||||||
+228
@@ -0,0 +1,228 @@
|
|||||||
|
// Copyright 2006 Nemanja Trifunovic
|
||||||
|
|
||||||
|
/*
|
||||||
|
Permission is hereby granted, free of charge, to any person or organization
|
||||||
|
obtaining a copy of the software and accompanying documentation covered by
|
||||||
|
this license (the "Software") to use, reproduce, display, distribute,
|
||||||
|
execute, and transmit the Software, and to prepare derivative works of the
|
||||||
|
Software, and to permit third-parties to whom the Software is furnished to
|
||||||
|
do so, all subject to the following:
|
||||||
|
|
||||||
|
The copyright notices in the Software and this entire statement, including
|
||||||
|
the above license grant, this restriction and the following disclaimer,
|
||||||
|
must be included in all copies of the Software, in whole or in part, and
|
||||||
|
all derivative works of the Software, unless such copies or derivative
|
||||||
|
works are solely in the form of machine-executable object code generated by
|
||||||
|
a source language processor.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||||
|
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||||
|
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||||
|
#define UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
|
||||||
|
|
||||||
|
#include "core.h"
|
||||||
|
|
||||||
|
namespace utf8
|
||||||
|
{
|
||||||
|
namespace unchecked
|
||||||
|
{
|
||||||
|
template <typename octet_iterator>
|
||||||
|
octet_iterator append(uint32_t cp, octet_iterator result)
|
||||||
|
{
|
||||||
|
if (cp < 0x80) // one octet
|
||||||
|
*(result++) = static_cast<uint8_t>(cp);
|
||||||
|
else if (cp < 0x800) { // two octets
|
||||||
|
*(result++) = static_cast<uint8_t>((cp >> 6) | 0xc0);
|
||||||
|
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||||
|
}
|
||||||
|
else if (cp < 0x10000) { // three octets
|
||||||
|
*(result++) = static_cast<uint8_t>((cp >> 12) | 0xe0);
|
||||||
|
*(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
|
||||||
|
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||||
|
}
|
||||||
|
else { // four octets
|
||||||
|
*(result++) = static_cast<uint8_t>((cp >> 18) | 0xf0);
|
||||||
|
*(result++) = static_cast<uint8_t>(((cp >> 12) & 0x3f)| 0x80);
|
||||||
|
*(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
|
||||||
|
*(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
uint32_t next(octet_iterator& it)
|
||||||
|
{
|
||||||
|
uint32_t cp = utf8::internal::mask8(*it);
|
||||||
|
typename std::iterator_traits<octet_iterator>::difference_type length = utf8::internal::sequence_length(it);
|
||||||
|
switch (length) {
|
||||||
|
case 1:
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
it++;
|
||||||
|
cp = ((cp << 6) & 0x7ff) + ((*it) & 0x3f);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
++it;
|
||||||
|
cp = ((cp << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff);
|
||||||
|
++it;
|
||||||
|
cp += (*it) & 0x3f;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
++it;
|
||||||
|
cp = ((cp << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff);
|
||||||
|
++it;
|
||||||
|
cp += (utf8::internal::mask8(*it) << 6) & 0xfff;
|
||||||
|
++it;
|
||||||
|
cp += (*it) & 0x3f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
uint32_t peek_next(octet_iterator it)
|
||||||
|
{
|
||||||
|
return utf8::unchecked::next(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
uint32_t prior(octet_iterator& it)
|
||||||
|
{
|
||||||
|
while (utf8::internal::is_trail(*(--it))) ;
|
||||||
|
octet_iterator temp = it;
|
||||||
|
return utf8::unchecked::next(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated in versions that include prior, but only for the sake of consistency (see utf8::previous)
|
||||||
|
template <typename octet_iterator>
|
||||||
|
inline uint32_t previous(octet_iterator& it)
|
||||||
|
{
|
||||||
|
return utf8::unchecked::prior(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator, typename distance_type>
|
||||||
|
void advance (octet_iterator& it, distance_type n)
|
||||||
|
{
|
||||||
|
for (distance_type i = 0; i < n; ++i)
|
||||||
|
utf8::unchecked::next(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator>
|
||||||
|
typename std::iterator_traits<octet_iterator>::difference_type
|
||||||
|
distance (octet_iterator first, octet_iterator last)
|
||||||
|
{
|
||||||
|
typename std::iterator_traits<octet_iterator>::difference_type dist;
|
||||||
|
for (dist = 0; first < last; ++dist)
|
||||||
|
utf8::unchecked::next(first);
|
||||||
|
return dist;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename u16bit_iterator, typename octet_iterator>
|
||||||
|
octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result)
|
||||||
|
{
|
||||||
|
while (start != end) {
|
||||||
|
uint32_t cp = utf8::internal::mask16(*start++);
|
||||||
|
// Take care of surrogate pairs first
|
||||||
|
if (utf8::internal::is_lead_surrogate(cp)) {
|
||||||
|
uint32_t trail_surrogate = utf8::internal::mask16(*start++);
|
||||||
|
cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET;
|
||||||
|
}
|
||||||
|
result = utf8::unchecked::append(cp, result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename u16bit_iterator, typename octet_iterator>
|
||||||
|
u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result)
|
||||||
|
{
|
||||||
|
while (start < end) {
|
||||||
|
uint32_t cp = utf8::unchecked::next(start);
|
||||||
|
if (cp > 0xffff) { //make a surrogate pair
|
||||||
|
*result++ = static_cast<uint16_t>((cp >> 10) + internal::LEAD_OFFSET);
|
||||||
|
*result++ = static_cast<uint16_t>((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*result++ = static_cast<uint16_t>(cp);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator, typename u32bit_iterator>
|
||||||
|
octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result)
|
||||||
|
{
|
||||||
|
while (start != end)
|
||||||
|
result = utf8::unchecked::append(*(start++), result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename octet_iterator, typename u32bit_iterator>
|
||||||
|
u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result)
|
||||||
|
{
|
||||||
|
while (start < end)
|
||||||
|
(*result++) = utf8::unchecked::next(start);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The iterator class
|
||||||
|
template <typename octet_iterator>
|
||||||
|
class iterator : public std::iterator <std::bidirectional_iterator_tag, uint32_t> {
|
||||||
|
octet_iterator it;
|
||||||
|
public:
|
||||||
|
iterator () {}
|
||||||
|
explicit iterator (const octet_iterator& octet_it): it(octet_it) {}
|
||||||
|
// the default "big three" are OK
|
||||||
|
octet_iterator base () const { return it; }
|
||||||
|
uint32_t operator * () const
|
||||||
|
{
|
||||||
|
octet_iterator temp = it;
|
||||||
|
return utf8::unchecked::next(temp);
|
||||||
|
}
|
||||||
|
bool operator == (const iterator& rhs) const
|
||||||
|
{
|
||||||
|
return (it == rhs.it);
|
||||||
|
}
|
||||||
|
bool operator != (const iterator& rhs) const
|
||||||
|
{
|
||||||
|
return !(operator == (rhs));
|
||||||
|
}
|
||||||
|
iterator& operator ++ ()
|
||||||
|
{
|
||||||
|
::std::advance(it, utf8::internal::sequence_length(it));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
iterator operator ++ (int)
|
||||||
|
{
|
||||||
|
iterator temp = *this;
|
||||||
|
::std::advance(it, utf8::internal::sequence_length(it));
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
iterator& operator -- ()
|
||||||
|
{
|
||||||
|
utf8::unchecked::prior(it);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
iterator operator -- (int)
|
||||||
|
{
|
||||||
|
iterator temp = *this;
|
||||||
|
utf8::unchecked::prior(it);
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
}; // class iterator
|
||||||
|
|
||||||
|
} // namespace utf8::unchecked
|
||||||
|
} // namespace utf8
|
||||||
|
|
||||||
|
|
||||||
|
#endif // header guard
|
||||||
|
|
||||||
+172
-53
@@ -2,17 +2,30 @@ cmake_minimum_required (VERSION 2.6.4)
|
|||||||
include (CheckFunctionExists)
|
include (CheckFunctionExists)
|
||||||
include (CheckIncludeFile)
|
include (CheckIncludeFile)
|
||||||
include (CheckCXXSourceCompiles)
|
include (CheckCXXSourceCompiles)
|
||||||
|
include (CheckCXXCompilerFlag)
|
||||||
|
|
||||||
project(SimGear)
|
project(SimGear)
|
||||||
|
|
||||||
|
# using 10.7 because boost requires libc++ and 10.6 doesn't include it
|
||||||
|
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.7)
|
||||||
|
|
||||||
# read 'version' file into a variable (stripping any newlines or spaces)
|
# read 'version' file into a variable (stripping any newlines or spaces)
|
||||||
file(READ version versionFile)
|
file(READ version versionFile)
|
||||||
string(STRIP ${versionFile} SIMGEAR_VERSION)
|
string(STRIP ${versionFile} SIMGEAR_VERSION)
|
||||||
|
|
||||||
|
set(FIND_LIBRARY_USE_LIB64_PATHS ON)
|
||||||
|
|
||||||
# use simgear version also as the SO version (if building SOs)
|
# use simgear version also as the SO version (if building SOs)
|
||||||
SET(SIMGEAR_SOVERSION ${SIMGEAR_VERSION})
|
SET(SIMGEAR_SOVERSION ${SIMGEAR_VERSION})
|
||||||
|
|
||||||
|
# Warning when build is not an out-of-source build.
|
||||||
|
string(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" InSourceBuild)
|
||||||
|
if(InSourceBuild)
|
||||||
|
message(WARNING "Avoid building inside the source tree!")
|
||||||
|
message(WARNING "Create a separate build directory instead (i.e. 'sgbuild') and call CMake from there: ")
|
||||||
|
message(WARNING " mkdir ../sgbuild && cd ../sgbuild && cmake ${CMAKE_SOURCE_DIR}")
|
||||||
|
endif(InSourceBuild)
|
||||||
|
|
||||||
#packaging
|
#packaging
|
||||||
SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/COPYING")
|
SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/COPYING")
|
||||||
SET(CPACK_RESOURCE_FILE_README "${PROJECT_SOURCE_DIR}/README")
|
SET(CPACK_RESOURCE_FILE_README "${PROJECT_SOURCE_DIR}/README")
|
||||||
@@ -60,15 +73,43 @@ else(${CMAKE_VERSION} VERSION_GREATER 2.8.4)
|
|||||||
endif(${CMAKE_VERSION} VERSION_GREATER 2.8.4)
|
endif(${CMAKE_VERSION} VERSION_GREATER 2.8.4)
|
||||||
message(STATUS "Library installation directory: ${CMAKE_INSTALL_LIBDIR}")
|
message(STATUS "Library installation directory: ${CMAKE_INSTALL_LIBDIR}")
|
||||||
|
|
||||||
|
#####################################################################################
|
||||||
|
# Configure library search paths
|
||||||
|
#####################################################################################
|
||||||
|
|
||||||
|
if(NOT "${CMAKE_LIBRARY_ARCHITECTURE}" STREQUAL "")
|
||||||
|
# Workaround for Ubuntu/Debian which introduced the "multiarch" library
|
||||||
|
# directory structure, which is unsupported by CMake < 2.8.10, so we need to
|
||||||
|
# add paths manually
|
||||||
|
# see http://www.cmake.org/Bug/view.php?id=12049 and
|
||||||
|
# http://www.cmake.org/Bug/view.php?id=12037
|
||||||
|
list(APPEND ADDITIONAL_LIBRARY_PATHS
|
||||||
|
/usr/local/lib/${CMAKE_LIBRARY_ARCHITECTURE}
|
||||||
|
/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}
|
||||||
|
/lib/${CMAKE_LIBRARY_ARCHITECTURE})
|
||||||
|
message(STATUS "additional library directories: ${ADDITIONAL_LIBRARY_PATHS}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
#####################################################################################
|
||||||
|
|
||||||
|
if (NOT MSVC)
|
||||||
option(SIMGEAR_SHARED "Set to ON to build SimGear as a shared library/framework" OFF)
|
option(SIMGEAR_SHARED "Set to ON to build SimGear as a shared library/framework" OFF)
|
||||||
|
option(SYSTEM_EXPAT "Set to ON to build SimGear using the system libExpat" OFF)
|
||||||
|
else()
|
||||||
|
# Building SimGear DLLs is currently not supported for MSVC.
|
||||||
|
set(SIMGEAR_SHARED OFF)
|
||||||
|
# Using a system expat is currently not supported for MSVC - it would require shared simgear (DLL).
|
||||||
|
set(SYSTEM_EXPAT OFF)
|
||||||
|
endif()
|
||||||
|
|
||||||
option(SIMGEAR_HEADLESS "Set to ON to build SimGear without GUI/graphics support" OFF)
|
option(SIMGEAR_HEADLESS "Set to ON to build SimGear without GUI/graphics support" OFF)
|
||||||
option(JPEG_FACTORY "Enable JPEG-factory support" OFF)
|
|
||||||
option(ENABLE_LIBSVN "Set to ON to build SimGear with libsvnclient support" ON)
|
|
||||||
option(ENABLE_RTI "Set to ON to build SimGear with RTI support" OFF)
|
option(ENABLE_RTI "Set to ON to build SimGear with RTI support" OFF)
|
||||||
option(ENABLE_TESTS "Set to OFF to disable building SimGear's test applications" ON)
|
option(ENABLE_TESTS "Set to OFF to disable building SimGear's test applications" ON)
|
||||||
|
option(ENABLE_SOUND "Set to OFF to disable building SimGear's sound support" ON)
|
||||||
|
option(ENABLE_PKGUTIL "Set to ON to build the sg_pkgutil application (default)" ON)
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
GET_FILENAME_COMPONENT(PARENT_DIR ${PROJECT_SOURCE_DIR} PATH)
|
GET_FILENAME_COMPONENT(PARENT_DIR ${PROJECT_BINARY_DIR} PATH)
|
||||||
if (CMAKE_CL_64)
|
if (CMAKE_CL_64)
|
||||||
SET(TEST_3RDPARTY_DIR "${PARENT_DIR}/3rdparty.x64")
|
SET(TEST_3RDPARTY_DIR "${PARENT_DIR}/3rdparty.x64")
|
||||||
else (CMAKE_CL_64)
|
else (CMAKE_CL_64)
|
||||||
@@ -86,11 +127,13 @@ endif (MSVC)
|
|||||||
if (MSVC AND MSVC_3RDPARTY_ROOT)
|
if (MSVC AND MSVC_3RDPARTY_ROOT)
|
||||||
message(STATUS "3rdparty files located in ${MSVC_3RDPARTY_ROOT}")
|
message(STATUS "3rdparty files located in ${MSVC_3RDPARTY_ROOT}")
|
||||||
set( OSG_MSVC "msvc" )
|
set( OSG_MSVC "msvc" )
|
||||||
if (${MSVC_VERSION} EQUAL 1600)
|
if (${MSVC_VERSION} EQUAL 1700)
|
||||||
|
set( OSG_MSVC ${OSG_MSVC}110 )
|
||||||
|
elseif (${MSVC_VERSION} EQUAL 1600)
|
||||||
set( OSG_MSVC ${OSG_MSVC}100 )
|
set( OSG_MSVC ${OSG_MSVC}100 )
|
||||||
else (${MSVC_VERSION} EQUAL 1600)
|
else (${MSVC_VERSION} EQUAL 1700)
|
||||||
set( OSG_MSVC ${OSG_MSVC}90 )
|
set( OSG_MSVC ${OSG_MSVC}90 )
|
||||||
endif (${MSVC_VERSION} EQUAL 1600)
|
endif (${MSVC_VERSION} EQUAL 1700)
|
||||||
if (CMAKE_CL_64)
|
if (CMAKE_CL_64)
|
||||||
set( OSG_MSVC ${OSG_MSVC}-64 )
|
set( OSG_MSVC ${OSG_MSVC}-64 )
|
||||||
set( MSVC_3RDPARTY_DIR 3rdParty.x64 )
|
set( MSVC_3RDPARTY_DIR 3rdParty.x64 )
|
||||||
@@ -98,61 +141,83 @@ if (MSVC AND MSVC_3RDPARTY_ROOT)
|
|||||||
set( MSVC_3RDPARTY_DIR 3rdParty )
|
set( MSVC_3RDPARTY_DIR 3rdParty )
|
||||||
endif (CMAKE_CL_64)
|
endif (CMAKE_CL_64)
|
||||||
|
|
||||||
set (CMAKE_LIBRARY_PATH ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/lib ${MSVC_3RDPARTY_ROOT}/install/${OSG_MSVC}/OpenScenegraph/lib )
|
set (CMAKE_LIBRARY_PATH ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/lib ${MSVC_3RDPARTY_ROOT}/install/${OSG_MSVC}/OpenScenegraph/lib ${MSVC_3RDPARTY_ROOT}/install/${OSG_MSVC}/OpenRTI/lib )
|
||||||
set (CMAKE_INCLUDE_PATH ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/include ${MSVC_3RDPARTY_ROOT}/install/${OSG_MSVC}/OpenScenegraph/include)
|
set (CMAKE_INCLUDE_PATH ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/include ${MSVC_3RDPARTY_ROOT}/install/${OSG_MSVC}/OpenScenegraph/include ${MSVC_3RDPARTY_ROOT}/install/${OSG_MSVC}/OpenRTI/include)
|
||||||
set (BOOST_ROOT ${MSVC_3RDPARTY_ROOT}/boost_1_44_0)
|
find_path(BOOST_ROOT boost/version.hpp
|
||||||
|
${MSVC_3RDPARTY_ROOT}/boost
|
||||||
|
${MSVC_3RDPARTY_ROOT}/boost_1_52_0
|
||||||
|
${MSVC_3RDPARTY_ROOT}/boost_1_51_0
|
||||||
|
${MSVC_3RDPARTY_ROOT}/boost_1_50_0
|
||||||
|
${MSVC_3RDPARTY_ROOT}/boost_1_49_0
|
||||||
|
${MSVC_3RDPARTY_ROOT}/boost_1_48_0
|
||||||
|
${MSVC_3RDPARTY_ROOT}/boost_1_47_0
|
||||||
|
${MSVC_3RDPARTY_ROOT}/boost_1_46_1
|
||||||
|
${MSVC_3RDPARTY_ROOT}/boost_1_46_0
|
||||||
|
${MSVC_3RDPARTY_ROOT}/boost_1_45_0
|
||||||
|
${MSVC_3RDPARTY_ROOT}/boost_1_44_0
|
||||||
|
)
|
||||||
|
# set (BOOST_ROOT ${MSVC_3RDPARTY_ROOT}/boost_1_44_0)
|
||||||
message(STATUS "BOOST_ROOT is ${BOOST_ROOT}")
|
message(STATUS "BOOST_ROOT is ${BOOST_ROOT}")
|
||||||
set (OPENAL_INCLUDE_DIR ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/include)
|
set (OPENAL_INCLUDE_DIR ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/include)
|
||||||
set (ALUT_INCLUDE_DIR ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/include)
|
|
||||||
set (OPENAL_LIBRARY_DIR ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/lib)
|
set (OPENAL_LIBRARY_DIR ${MSVC_3RDPARTY_ROOT}/${MSVC_3RDPARTY_DIR}/lib)
|
||||||
endif (MSVC AND MSVC_3RDPARTY_ROOT)
|
endif (MSVC AND MSVC_3RDPARTY_ROOT)
|
||||||
|
|
||||||
|
if(APPLE)
|
||||||
|
find_library(COCOA_LIBRARY Cocoa)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Somehow this only works if included before searching for Boost...
|
||||||
|
include(BoostTestTargets)
|
||||||
|
|
||||||
find_package(Boost REQUIRED)
|
find_package(Boost REQUIRED)
|
||||||
set (BOOST_CXX_FLAGS "-DBOOST_MULTI_INDEX_DISABLE_SERIALIZATION -DBOOST_BIMAP_DISABLE_SERIALIZATION")
|
set (BOOST_CXX_FLAGS "-DBOOST_MULTI_INDEX_DISABLE_SERIALIZATION -DBOOST_BIMAP_DISABLE_SERIALIZATION")
|
||||||
|
|
||||||
find_package(ZLIB REQUIRED)
|
|
||||||
find_package(Threads REQUIRED)
|
|
||||||
|
|
||||||
if(SIMGEAR_HEADLESS)
|
if(SIMGEAR_HEADLESS)
|
||||||
message(STATUS "SimGear mode: HEADLESS")
|
message(STATUS "SimGear mode: HEADLESS")
|
||||||
|
set(ENABLE_SOUND 0)
|
||||||
else()
|
else()
|
||||||
message(STATUS "SimGear mode: NORMAL")
|
message(STATUS "SimGear mode: NORMAL")
|
||||||
find_package(OpenGL REQUIRED)
|
find_package(OpenGL REQUIRED)
|
||||||
find_package(OpenAL REQUIRED)
|
|
||||||
find_package(ALUT REQUIRED)
|
if (ENABLE_SOUND)
|
||||||
find_package(OpenSceneGraph 3.0.0 REQUIRED osgText osgSim osgDB osgParticle osgUtil)
|
find_package(OpenAL REQUIRED)
|
||||||
|
message(STATUS "Sound support: ENABLED")
|
||||||
|
endif(ENABLE_SOUND)
|
||||||
|
|
||||||
|
find_package(OpenSceneGraph 3.2.0 REQUIRED osgText osgSim osgDB osgParticle osgGA osgViewer osgUtil)
|
||||||
endif(SIMGEAR_HEADLESS)
|
endif(SIMGEAR_HEADLESS)
|
||||||
|
|
||||||
if(JPEG_FACTORY)
|
find_package(ZLIB REQUIRED)
|
||||||
message(STATUS "JPEG-factory: ENABLED")
|
find_package(Threads REQUIRED)
|
||||||
find_package(JPEG REQUIRED)
|
|
||||||
include_directories(${JPEG_INCLUDE_DIR})
|
if (SYSTEM_EXPAT)
|
||||||
|
message(STATUS "Requested to use system Expat library, forcing SIMGEAR_SHARED to true")
|
||||||
|
set(SIMGEAR_SHARED ON)
|
||||||
|
find_package(EXPAT REQUIRED)
|
||||||
|
|
||||||
else()
|
else()
|
||||||
message(STATUS "JPEG-factory: DISABLED")
|
message(STATUS "Using built-in expat code")
|
||||||
endif(JPEG_FACTORY)
|
# XML_STATIC is important to avoid sg_expat_external.h
|
||||||
|
# declaring symbols as declspec(import)
|
||||||
|
add_definitions(-DHAVE_EXPAT_CONFIG_H -DXML_STATIC)
|
||||||
|
set(EXPAT_INCLUDE_DIRS
|
||||||
|
${PROJECT_SOURCE_DIR}/3rdparty/expat
|
||||||
|
${PROJECT_BINARY_DIR}/3rdparty/expat)
|
||||||
|
endif(SYSTEM_EXPAT)
|
||||||
|
|
||||||
if(ENABLE_LIBSVN)
|
include_directories(${EXPAT_INCLUDE_DIRS})
|
||||||
find_package(SvnClient)
|
|
||||||
|
|
||||||
if(LIBSVN_FOUND)
|
|
||||||
message(STATUS "Subversion client support: ENABLED")
|
|
||||||
set(HAVE_SVN_CLIENT_H 1)
|
|
||||||
set(HAVE_LIBSVN_CLIENT_1 1)
|
|
||||||
else()
|
|
||||||
# Oops. ENABLE_LIBSVN is ON, but svn is still missing.
|
|
||||||
# Provide clearly visible warning/hint, so builders know what else they should install (or disable).
|
|
||||||
message(WARNING "Failed to enable subversion client support. Unable to find required subversion client library. Some features may not be available (scenery download).")
|
|
||||||
message(WARNING "Install 'libsvn' library/DLL (libsvn-devel/libsvnclient/...). Otherwise disable subversion support (set 'ENABLE_LIBSVN' to 'OFF').")
|
|
||||||
endif(LIBSVN_FOUND)
|
|
||||||
else()
|
|
||||||
message(STATUS "Subversion client support: DISABLED")
|
|
||||||
endif(ENABLE_LIBSVN)
|
|
||||||
|
|
||||||
|
check_include_file(inttypes.h HAVE_INTTYPES_H)
|
||||||
check_include_file(sys/time.h HAVE_SYS_TIME_H)
|
check_include_file(sys/time.h HAVE_SYS_TIME_H)
|
||||||
check_include_file(sys/timeb.h HAVE_SYS_TIMEB_H)
|
check_include_file(sys/timeb.h HAVE_SYS_TIMEB_H)
|
||||||
check_include_file(unistd.h HAVE_UNISTD_H)
|
check_include_file(unistd.h HAVE_UNISTD_H)
|
||||||
check_include_file(windows.h HAVE_WINDOWS_H)
|
check_include_file(windows.h HAVE_WINDOWS_H)
|
||||||
|
|
||||||
|
if(HAVE_INTTYPES_H)
|
||||||
|
# ShivaVG needs inttypes.h
|
||||||
|
add_definitions(-DHAVE_INTTYPES_H)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(ENABLE_RTI)
|
if(ENABLE_RTI)
|
||||||
# See if we have any rti library variant installed
|
# See if we have any rti library variant installed
|
||||||
message(STATUS "RTI: ENABLED")
|
message(STATUS "RTI: ENABLED")
|
||||||
@@ -190,6 +255,22 @@ if(HAVE_CLOCK_GETTIME)
|
|||||||
endif(HAVE_RT)
|
endif(HAVE_RT)
|
||||||
endif(HAVE_CLOCK_GETTIME)
|
endif(HAVE_CLOCK_GETTIME)
|
||||||
|
|
||||||
|
set(DL_LIBRARY "")
|
||||||
|
check_cxx_source_compiles(
|
||||||
|
"#include <dlfcn.h>
|
||||||
|
int main(void) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
HAVE_DLFCN_H)
|
||||||
|
|
||||||
|
if(HAVE_DLFCN_H)
|
||||||
|
check_library_exists(dl dlerror "" HAVE_DL)
|
||||||
|
if(HAVE_DL)
|
||||||
|
set(DL_LIBRARY "dl")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
SET(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "add a postfix, usually 'd' on windows")
|
SET(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "add a postfix, usually 'd' on windows")
|
||||||
SET(CMAKE_RELEASE_POSTFIX "" CACHE STRING "add a postfix, usually empty on windows")
|
SET(CMAKE_RELEASE_POSTFIX "" CACHE STRING "add a postfix, usually empty on windows")
|
||||||
SET(CMAKE_RELWITHDEBINFO_POSTFIX "" CACHE STRING "add a postfix, usually empty on windows")
|
SET(CMAKE_RELWITHDEBINFO_POSTFIX "" CACHE STRING "add a postfix, usually empty on windows")
|
||||||
@@ -198,9 +279,14 @@ SET(CMAKE_MINSIZEREL_POSTFIX "" CACHE STRING "add a postfix, usually empty on wi
|
|||||||
# isnan might not be real symbol, so can't check using function_exists
|
# isnan might not be real symbol, so can't check using function_exists
|
||||||
check_cxx_source_compiles(
|
check_cxx_source_compiles(
|
||||||
"#include <cmath>
|
"#include <cmath>
|
||||||
void f() { isnan(0.0);} "
|
int main() { return isnan(0.0);} "
|
||||||
HAVE_ISNAN)
|
HAVE_ISNAN)
|
||||||
|
|
||||||
|
check_cxx_source_compiles(
|
||||||
|
"#include <cmath>
|
||||||
|
int main() { return std::isnan(0.0);} "
|
||||||
|
HAVE_STD_ISNAN)
|
||||||
|
|
||||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||||
set(WARNING_FLAGS_CXX "-Wall")
|
set(WARNING_FLAGS_CXX "-Wall")
|
||||||
set(WARNING_FLAGS_C "-Wall")
|
set(WARNING_FLAGS_C "-Wall")
|
||||||
@@ -216,6 +302,17 @@ endif(CMAKE_COMPILER_IS_GNUCXX)
|
|||||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||||
set(WARNING_FLAGS_CXX "-Wall -Wno-overloaded-virtual")
|
set(WARNING_FLAGS_CXX "-Wall -Wno-overloaded-virtual")
|
||||||
set(WARNING_FLAGS_C "-Wall")
|
set(WARNING_FLAGS_C "-Wall")
|
||||||
|
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
|
||||||
|
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++11")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -stdlib=libc++")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||||
|
# boost goes haywire wrt static asserts
|
||||||
|
check_cxx_compiler_flag(-Wno-unused-local-typedefs HAS_NOWARN_UNUSED_TYPEDEFS)
|
||||||
|
if(HAS_NOWARN_UNUSED_TYPEDEFS)
|
||||||
|
set(WARNING_FLAGS_CXX " ${WARNING_FLAGS_CXX} -Wno-unused-local-typedefs")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
@@ -230,7 +327,10 @@ if(WIN32)
|
|||||||
# SET(WARNING_FLAGS "${WARNING_FLAGS} /wd${warning}")
|
# SET(WARNING_FLAGS "${WARNING_FLAGS} /wd${warning}")
|
||||||
# endforeach(warning)
|
# endforeach(warning)
|
||||||
|
|
||||||
set(MSVC_FLAGS "-DWIN32 -DNOMINMAX -D_USE_MATH_DEFINES -D_CRT_SECURE_NO_WARNINGS -D__CRT_NONSTDC_NO_WARNINGS /wd4996")
|
set(MSVC_FLAGS "-DWIN32 -DNOMINMAX -D_USE_MATH_DEFINES -D_CRT_SECURE_NO_WARNINGS -D__CRT_NONSTDC_NO_WARNINGS /wd4996 /wd4250 -Dstrdup=_strdup")
|
||||||
|
if (${MSVC_VERSION} GREATER 1599)
|
||||||
|
set( MSVC_LD_FLAGS "/FORCE:MULTIPLE" )
|
||||||
|
endif (${MSVC_VERSION} GREATER 1599)
|
||||||
endif(MSVC)
|
endif(MSVC)
|
||||||
|
|
||||||
# assumed on Windows
|
# assumed on Windows
|
||||||
@@ -242,17 +342,21 @@ endif(WIN32)
|
|||||||
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS_C} ${MSVC_FLAGS}")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS_C} ${MSVC_FLAGS}")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS_CXX} ${MSVC_FLAGS} ${BOOST_CXX_FLAGS}")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS_CXX} ${MSVC_FLAGS} ${BOOST_CXX_FLAGS}")
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${MSVC_LD_FLAGS}")
|
||||||
|
|
||||||
include_directories(${PROJECT_SOURCE_DIR})
|
# use BEFORE to ensure local directories are used first,
|
||||||
include_directories(${PROJECT_BINARY_DIR}/simgear)
|
# ahead of system-installed libs
|
||||||
include_directories(${PROJECT_BINARY_DIR}/simgear/xml)
|
include_directories(BEFORE ${PROJECT_SOURCE_DIR})
|
||||||
|
include_directories(BEFORE ${PROJECT_SOURCE_DIR}/simgear/canvas/ShivaVG/include)
|
||||||
|
include_directories(BEFORE ${PROJECT_BINARY_DIR}/simgear)
|
||||||
|
|
||||||
include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS}
|
include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS}
|
||||||
${Boost_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIR}
|
${Boost_INCLUDE_DIRS}
|
||||||
${ALUT_INCLUDE_DIR} ${OPENAL_INCLUDE_DIR} )
|
${ZLIB_INCLUDE_DIR}
|
||||||
|
${OPENAL_INCLUDE_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
add_definitions(-DHAVE_CONFIG_H)
|
add_definitions(-DHAVE_CONFIG_H)
|
||||||
add_definitions(-DHAVE_EXPAT_CONFIG_H)
|
|
||||||
|
|
||||||
# configure a header file to pass some of the CMake settings
|
# configure a header file to pass some of the CMake settings
|
||||||
# to the source code
|
# to the source code
|
||||||
@@ -261,22 +365,35 @@ configure_file (
|
|||||||
"${PROJECT_BINARY_DIR}/simgear/simgear_config.h"
|
"${PROJECT_BINARY_DIR}/simgear/simgear_config.h"
|
||||||
)
|
)
|
||||||
|
|
||||||
configure_file (
|
|
||||||
"${PROJECT_SOURCE_DIR}/simgear/xml/expat_config_cmake.in"
|
|
||||||
"${PROJECT_BINARY_DIR}/simgear/xml/expat_config.h"
|
|
||||||
)
|
|
||||||
|
|
||||||
if(ENABLE_TESTS)
|
if(ENABLE_TESTS)
|
||||||
# enable CTest / make test target
|
# enable CTest / make test target
|
||||||
message(STATUS "Tests: ENABLED")
|
message(STATUS "Tests: ENABLED")
|
||||||
|
|
||||||
include (Dart)
|
include (Dart)
|
||||||
enable_testing()
|
enable_testing()
|
||||||
else()
|
else()
|
||||||
message(STATUS "Tests: DISABLED")
|
message(STATUS "Tests: DISABLED")
|
||||||
endif(ENABLE_TESTS)
|
endif(ENABLE_TESTS)
|
||||||
|
|
||||||
|
# always set TEST_LIBS as it is also used by other tools/applications
|
||||||
|
set(TEST_LIBS_INTERNAL_CORE
|
||||||
|
${CMAKE_THREAD_LIBS_INIT}
|
||||||
|
${ZLIB_LIBRARY}
|
||||||
|
${WINSOCK_LIBRARY}
|
||||||
|
${RT_LIBRARY}
|
||||||
|
${DL_LIBRARY}
|
||||||
|
${COCOA_LIBRARY})
|
||||||
|
set(TEST_LIBS SimGearCore ${TEST_LIBS_INTERNAL_CORE})
|
||||||
|
|
||||||
|
if(NOT SIMGEAR_HEADLESS)
|
||||||
|
set(TEST_LIBS SimGearScene ${OPENGL_LIBRARIES} ${TEST_LIBS})
|
||||||
|
endif()
|
||||||
|
|
||||||
install (FILES ${PROJECT_BINARY_DIR}/simgear/simgear_config.h DESTINATION include/simgear/)
|
install (FILES ${PROJECT_BINARY_DIR}/simgear/simgear_config.h DESTINATION include/simgear/)
|
||||||
|
|
||||||
|
include_directories(3rdparty/utf8/source)
|
||||||
|
|
||||||
|
add_subdirectory(3rdparty)
|
||||||
add_subdirectory(simgear)
|
add_subdirectory(simgear)
|
||||||
|
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
@@ -288,3 +405,5 @@ CONFIGURE_FILE(
|
|||||||
IMMEDIATE @ONLY)
|
IMMEDIATE @ONLY)
|
||||||
ADD_CUSTOM_TARGET(uninstall
|
ADD_CUSTOM_TARGET(uninstall
|
||||||
"${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
|
"${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,256 @@
|
|||||||
|
# - Add tests using boost::test
|
||||||
|
#
|
||||||
|
# Add this line to your test files in place of including a basic boost test header:
|
||||||
|
# #include <BoostTestTargetConfig.h>
|
||||||
|
#
|
||||||
|
# If you cannot do that and must use the included form for a given test,
|
||||||
|
# include the line
|
||||||
|
# // OVERRIDE_BOOST_TEST_INCLUDED_WARNING
|
||||||
|
# in the same file with the boost test include.
|
||||||
|
#
|
||||||
|
# include(BoostTestTargets)
|
||||||
|
# add_boost_test(<testdriver_name> SOURCES <source1> [<more sources...>]
|
||||||
|
# [FAIL_REGULAR_EXPRESSION <additional fail regex>]
|
||||||
|
# [LAUNCHER <generic launcher script>]
|
||||||
|
# [LIBRARIES <library> [<library>...]]
|
||||||
|
# [RESOURCES <resource> [<resource>...]]
|
||||||
|
# [TESTS <testcasename> [<testcasename>...]])
|
||||||
|
#
|
||||||
|
# If for some reason you need access to the executable target created,
|
||||||
|
# it can be found in ${${testdriver_name}_TARGET_NAME} as specified when
|
||||||
|
# you called add_boost_test
|
||||||
|
#
|
||||||
|
# Requires CMake 2.6 or newer (uses the 'function' command)
|
||||||
|
#
|
||||||
|
# Requires:
|
||||||
|
# GetForceIncludeDefinitions
|
||||||
|
# CopyResourcesToBuildTree
|
||||||
|
#
|
||||||
|
# Original Author:
|
||||||
|
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
|
||||||
|
# http://academic.cleardefinition.com
|
||||||
|
# Iowa State University HCI Graduate Program/VRAC
|
||||||
|
#
|
||||||
|
# Copyright Iowa State University 2009-2010.
|
||||||
|
# Distributed under the Boost Software License, Version 1.0.
|
||||||
|
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
# http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
if(__add_boost_test)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
set(__add_boost_test YES)
|
||||||
|
|
||||||
|
set(BOOST_TEST_TARGET_PREFIX "test")
|
||||||
|
|
||||||
|
if(NOT Boost_FOUND)
|
||||||
|
find_package(Boost 1.34.0 QUIET)
|
||||||
|
endif()
|
||||||
|
if("${Boost_VERSION}0" LESS "1034000")
|
||||||
|
set(_shared_msg
|
||||||
|
"NOTE: boost::test-based targets and tests cannot "
|
||||||
|
"be added: boost >= 1.34.0 required but not found. "
|
||||||
|
"(found: '${Boost_VERSION}'; want >=103400) ")
|
||||||
|
if(ENABLE_TESTS)
|
||||||
|
message(FATAL_ERROR
|
||||||
|
${_shared_msg}
|
||||||
|
"You may disable ENABLE_TESTS to continue without the "
|
||||||
|
"tests.")
|
||||||
|
else()
|
||||||
|
message(STATUS
|
||||||
|
${_shared_msg}
|
||||||
|
"ENABLE_TESTS disabled, so continuing anyway.")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(GetForceIncludeDefinitions)
|
||||||
|
include(CopyResourcesToBuildTree)
|
||||||
|
|
||||||
|
if(Boost_FOUND AND NOT "${Boost_VERSION}0" LESS "1034000")
|
||||||
|
set(_boosttesttargets_libs)
|
||||||
|
set(_boostConfig "BoostTestTargetsIncluded.h")
|
||||||
|
if(NOT Boost_UNIT_TEST_FRAMEWORK_LIBRARY)
|
||||||
|
find_package(Boost 1.34.0 QUIET COMPONENTS unit_test_framework)
|
||||||
|
endif()
|
||||||
|
if(Boost_UNIT_TEST_FRAMEWORK_LIBRARY)
|
||||||
|
set(_boosttesttargets_libs "${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}")
|
||||||
|
if(Boost_USE_STATIC_LIBS)
|
||||||
|
set(_boostConfig "BoostTestTargetsStatic.h")
|
||||||
|
else()
|
||||||
|
set(_boostConfig "BoostTestTargetsDynamic.h")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
get_filename_component(_moddir ${CMAKE_CURRENT_LIST_FILE} PATH)
|
||||||
|
configure_file("${_moddir}/${_boostConfig}"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/BoostTestTargetConfig.h"
|
||||||
|
COPYONLY)
|
||||||
|
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
function(add_boost_test _name)
|
||||||
|
if(NOT ENABLE_TESTS)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# parse arguments
|
||||||
|
set(_nowhere)
|
||||||
|
set(_curdest _nowhere)
|
||||||
|
set(_val_args
|
||||||
|
SOURCES
|
||||||
|
FAIL_REGULAR_EXPRESSION
|
||||||
|
LAUNCHER
|
||||||
|
LIBRARIES
|
||||||
|
RESOURCES
|
||||||
|
TESTS)
|
||||||
|
set(_bool_args
|
||||||
|
USE_COMPILED_LIBRARY)
|
||||||
|
foreach(_arg ${_val_args} ${_bool_args})
|
||||||
|
set(${_arg})
|
||||||
|
endforeach()
|
||||||
|
foreach(_element ${ARGN})
|
||||||
|
list(FIND _val_args "${_element}" _val_arg_find)
|
||||||
|
list(FIND _bool_args "${_element}" _bool_arg_find)
|
||||||
|
if("${_val_arg_find}" GREATER "-1")
|
||||||
|
set(_curdest "${_element}")
|
||||||
|
elseif("${_bool_arg_find}" GREATER "-1")
|
||||||
|
set("${_element}" ON)
|
||||||
|
set(_curdest _nowhere)
|
||||||
|
else()
|
||||||
|
list(APPEND ${_curdest} "${_element}")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
if(_nowhere)
|
||||||
|
message(FATAL_ERROR "Syntax error in use of add_boost_test!")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT SOURCES)
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"Syntax error in use of add_boost_test: at least one source file required!")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(Boost_FOUND AND NOT "${Boost_VERSION}0" LESS "1034000")
|
||||||
|
|
||||||
|
include_directories(${Boost_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
set(includeType)
|
||||||
|
foreach(src ${SOURCES})
|
||||||
|
file(READ ${src} thefile)
|
||||||
|
if("${thefile}" MATCHES ".*BoostTestTargetConfig.h.*")
|
||||||
|
set(includeType CONFIGURED)
|
||||||
|
set(includeFileLoc ${src})
|
||||||
|
break()
|
||||||
|
elseif("${thefile}" MATCHES ".*boost/test/included/unit_test.hpp.*")
|
||||||
|
set(includeType INCLUDED)
|
||||||
|
set(includeFileLoc ${src})
|
||||||
|
set(_boosttesttargets_libs) # clear this out - linking would be a bad idea
|
||||||
|
if(NOT
|
||||||
|
"${thefile}"
|
||||||
|
MATCHES
|
||||||
|
".*OVERRIDE_BOOST_TEST_INCLUDED_WARNING.*")
|
||||||
|
message("Please replace the include line in ${src} with this alternate include line instead:")
|
||||||
|
message(" \#include <BoostTestTargetConfig.h>")
|
||||||
|
message("Once you've saved your changes, re-run CMake. (See BoostTestTargets.cmake for more info)")
|
||||||
|
endif()
|
||||||
|
break()
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
if(NOT _boostTestTargetsNagged${_name} STREQUAL "${includeType}")
|
||||||
|
if("includeType" STREQUAL "CONFIGURED")
|
||||||
|
message(STATUS
|
||||||
|
"Test '${_name}' uses the CMake-configurable form of the boost test framework - congrats! (Including File: ${includeFileLoc})")
|
||||||
|
elseif("${includeType}" STREQUAL "INCLUDED")
|
||||||
|
message("In test '${_name}': ${includeFileLoc} uses the 'included' form of the boost unit test framework.")
|
||||||
|
else()
|
||||||
|
message("In test '${_name}': Didn't detect the CMake-configurable boost test include.")
|
||||||
|
message("Please replace your existing boost test include in that test with the following:")
|
||||||
|
message(" \#include <BoostTestTargetConfig.h>")
|
||||||
|
message("Once you've saved your changes, re-run CMake. (See BoostTestTargets.cmake for more info)")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
set(_boostTestTargetsNagged${_name}
|
||||||
|
"${includeType}"
|
||||||
|
CACHE
|
||||||
|
INTERNAL
|
||||||
|
""
|
||||||
|
FORCE)
|
||||||
|
|
||||||
|
|
||||||
|
if(RESOURCES)
|
||||||
|
list(APPEND SOURCES ${RESOURCES})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Generate a unique target name, using the relative binary dir
|
||||||
|
# and provided name. (transform all / into _ and remove all other
|
||||||
|
# non-alphabet characters)
|
||||||
|
file(RELATIVE_PATH
|
||||||
|
targetpath
|
||||||
|
"${CMAKE_BINARY_DIR}"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}")
|
||||||
|
string(REGEX REPLACE "[^A-Za-z/_]" "" targetpath "${targetpath}")
|
||||||
|
string(REPLACE "/" "_" targetpath "${targetpath}")
|
||||||
|
|
||||||
|
set(_target_name ${BOOST_TEST_TARGET_PREFIX}-${targetpath}-${_name})
|
||||||
|
set(${_name}_TARGET_NAME "${_target_name}" PARENT_SCOPE)
|
||||||
|
|
||||||
|
# Build the test.
|
||||||
|
add_executable(${_target_name} ${SOURCES})
|
||||||
|
|
||||||
|
list(APPEND LIBRARIES ${_boosttesttargets_libs})
|
||||||
|
|
||||||
|
if(LIBRARIES)
|
||||||
|
target_link_libraries(${_target_name} ${LIBRARIES})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(RESOURCES)
|
||||||
|
set_property(TARGET ${_target_name} PROPERTY RESOURCE ${RESOURCES})
|
||||||
|
copy_resources_to_build_tree(${_target_name})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT Boost_TEST_FLAGS)
|
||||||
|
# set(Boost_TEST_FLAGS --catch_system_error=yes --output_format=XML)
|
||||||
|
set(Boost_TEST_FLAGS --catch_system_error=yes)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# TODO: Figure out why only recent boost handles individual test running properly
|
||||||
|
|
||||||
|
if(LAUNCHER)
|
||||||
|
set(_test_command ${LAUNCHER} "\$<TARGET_FILE:${_target_name}>")
|
||||||
|
else()
|
||||||
|
set(_test_command ${_target_name})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(TESTS AND ( "${Boost_VERSION}" VERSION_GREATER "103799" ))
|
||||||
|
foreach(_test ${TESTS})
|
||||||
|
add_test(
|
||||||
|
${_name}-${_test}
|
||||||
|
${_test_command} --run_test=${_test} ${Boost_TEST_FLAGS}
|
||||||
|
)
|
||||||
|
if(FAIL_REGULAR_EXPRESSION)
|
||||||
|
set_tests_properties(${_name}-${_test}
|
||||||
|
PROPERTIES
|
||||||
|
FAIL_REGULAR_EXPRESSION
|
||||||
|
"${FAIL_REGULAR_EXPRESSION}")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
else()
|
||||||
|
add_test(
|
||||||
|
${_name}-boost_test
|
||||||
|
${_test_command} ${Boost_TEST_FLAGS}
|
||||||
|
)
|
||||||
|
if(FAIL_REGULAR_EXPRESSION)
|
||||||
|
set_tests_properties(${_name}-boost_test
|
||||||
|
PROPERTIES
|
||||||
|
FAIL_REGULAR_EXPRESSION
|
||||||
|
"${FAIL_REGULAR_EXPRESSION}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# CppCheck the test if we can.
|
||||||
|
if(COMMAND add_cppcheck)
|
||||||
|
add_cppcheck(${_target_name} STYLE UNUSED_FUNCTIONS)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// Small header computed by CMake to set up boost test.
|
||||||
|
// include AFTER #define BOOST_TEST_MODULE whatever
|
||||||
|
// but before any other boost test includes.
|
||||||
|
|
||||||
|
// Using the Boost UTF dynamic library
|
||||||
|
|
||||||
|
#define BOOST_TEST_DYN_LINK
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
// Small header computed by CMake to set up boost test.
|
||||||
|
// include AFTER #define BOOST_TEST_MODULE whatever
|
||||||
|
// but before any other boost test includes.
|
||||||
|
|
||||||
|
// Using the Boost UTF included framework
|
||||||
|
|
||||||
|
#include <boost/test/included/unit_test.hpp>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
// Small header computed by CMake to set up boost test.
|
||||||
|
// include AFTER #define BOOST_TEST_MODULE whatever
|
||||||
|
// but before any other boost test includes.
|
||||||
|
|
||||||
|
// Using the Boost UTF static library
|
||||||
|
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
# - Copy the resources your app needs to the build tree.
|
||||||
|
#
|
||||||
|
# copy_resources_to_build_tree(<target_name>)
|
||||||
|
#
|
||||||
|
# Requires CMake 2.6 or newer (uses the 'function' command)
|
||||||
|
#
|
||||||
|
# Original Author:
|
||||||
|
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
|
||||||
|
# http://academic.cleardefinition.com
|
||||||
|
# Iowa State University HCI Graduate Program/VRAC
|
||||||
|
#
|
||||||
|
# Copyright Iowa State University 2009-2010.
|
||||||
|
# Distributed under the Boost Software License, Version 1.0.
|
||||||
|
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
# http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
if(__copy_resources_to_build_tree)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
set(__copy_resources_to_build_tree YES)
|
||||||
|
|
||||||
|
function(copy_resources_to_build_tree _target)
|
||||||
|
get_target_property(_resources ${_target} RESOURCE)
|
||||||
|
if(NOT _resources)
|
||||||
|
# Bail if no resources
|
||||||
|
message(STATUS
|
||||||
|
"Told to copy resources for target ${_target}, but "
|
||||||
|
"no resources are set!")
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
get_target_property(_path ${_target} LOCATION)
|
||||||
|
get_filename_component(_path "${_path}" PATH)
|
||||||
|
|
||||||
|
if(NOT MSVC AND NOT "${CMAKE_GENERATOR}" MATCHES "Makefiles")
|
||||||
|
foreach(_config ${CMAKE_CONFIGURATION_TYPES})
|
||||||
|
get_target_property(_path${_config} ${_target} LOCATION_${_config})
|
||||||
|
get_filename_component(_path${_config} "${_path${_config}}" PATH)
|
||||||
|
add_custom_command(TARGET ${_target}
|
||||||
|
POST_BUILD
|
||||||
|
COMMAND
|
||||||
|
${CMAKE_COMMAND}
|
||||||
|
ARGS -E make_directory "${_path${_config}}/"
|
||||||
|
COMMENT "Creating directory ${_path${_config}}/")
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
foreach(_res ${_resources})
|
||||||
|
if(NOT IS_ABSOLUTE "${_res}")
|
||||||
|
get_filename_component(_res "${_res}" ABSOLUTE)
|
||||||
|
endif()
|
||||||
|
get_filename_component(_name "${_res}" NAME)
|
||||||
|
|
||||||
|
if(MSVC)
|
||||||
|
# Working dir is solution file dir, not exe file dir.
|
||||||
|
add_custom_command(TARGET ${_target}
|
||||||
|
POST_BUILD
|
||||||
|
COMMAND
|
||||||
|
${CMAKE_COMMAND}
|
||||||
|
ARGS -E copy "${_res}" "${CMAKE_BINARY_DIR}/"
|
||||||
|
COMMENT "Copying ${_name} to ${CMAKE_BINARY_DIR}/ for MSVC")
|
||||||
|
else()
|
||||||
|
if("${CMAKE_GENERATOR}" MATCHES "Makefiles")
|
||||||
|
add_custom_command(TARGET ${_target}
|
||||||
|
POST_BUILD
|
||||||
|
COMMAND
|
||||||
|
${CMAKE_COMMAND}
|
||||||
|
ARGS -E copy "${_res}" "${_path}/"
|
||||||
|
COMMENT "Copying ${_name} to ${_path}/")
|
||||||
|
else()
|
||||||
|
foreach(_config ${CMAKE_CONFIGURATION_TYPES})
|
||||||
|
add_custom_command(TARGET ${_target}
|
||||||
|
POST_BUILD
|
||||||
|
COMMAND
|
||||||
|
${CMAKE_COMMAND}
|
||||||
|
ARGS -E copy "${_res}" "${_path${_config}}"
|
||||||
|
COMMENT "Copying ${_name} to ${_path${_config}}")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
endfunction()
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
# Locate ALUT
|
|
||||||
# This module defines
|
|
||||||
# ALUT_LIBRARY
|
|
||||||
# ALUT_FOUND, if false, do not try to link to ALUT
|
|
||||||
# ALUT_INCLUDE_DIR, where to find the headers
|
|
||||||
#
|
|
||||||
# $ALUTDIR is an environment variable that would
|
|
||||||
# correspond to the ./configure --prefix=$ALUTDIR
|
|
||||||
# used in building ALUT.
|
|
||||||
#
|
|
||||||
# Created by James Turner. This was influenced by the FindOpenAL.cmake module.
|
|
||||||
|
|
||||||
#=============================================================================
|
|
||||||
# Copyright 2005-2009 Kitware, Inc.
|
|
||||||
#
|
|
||||||
# Distributed under the OSI-approved BSD License (the "License");
|
|
||||||
# see accompanying file Copyright.txt for details.
|
|
||||||
#
|
|
||||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
|
||||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the License for more information.
|
|
||||||
#=============================================================================
|
|
||||||
# (To distributed this file outside of CMake, substitute the full
|
|
||||||
# License text for the above reference.)
|
|
||||||
|
|
||||||
# Per my request, CMake should search for frameworks first in
|
|
||||||
# the following order:
|
|
||||||
# ~/Library/Frameworks/OpenAL.framework/Headers
|
|
||||||
# /Library/Frameworks/OpenAL.framework/Headers
|
|
||||||
# /System/Library/Frameworks/OpenAL.framework/Headers
|
|
||||||
#
|
|
||||||
# On OS X, this will prefer the Framework version (if found) over others.
|
|
||||||
# People will have to manually change the cache values of
|
|
||||||
# OPENAL_LIBRARY to override this selection or set the CMake environment
|
|
||||||
# CMAKE_INCLUDE_PATH to modify the search paths.
|
|
||||||
|
|
||||||
FIND_LIBRARY(ALUT_LIBRARY
|
|
||||||
NAMES ALUT alut
|
|
||||||
HINTS
|
|
||||||
$ENV{ALUTDIR}
|
|
||||||
PATH_SUFFIXES lib64 lib libs64 libs libs/Win32 libs/Win64
|
|
||||||
PATHS
|
|
||||||
~/Library/Frameworks
|
|
||||||
/Library/Frameworks
|
|
||||||
/usr/local
|
|
||||||
/usr
|
|
||||||
/opt
|
|
||||||
)
|
|
||||||
|
|
||||||
FIND_PATH(ALUT_INCLUDE_DIR
|
|
||||||
NAMES ALUT/alut.h alut.h
|
|
||||||
HINTS
|
|
||||||
$ENV{ALUTDIR}
|
|
||||||
PATH_SUFFIXES include/AL include
|
|
||||||
PATHS
|
|
||||||
~/Library/Frameworks
|
|
||||||
/Library/Frameworks
|
|
||||||
/usr/local
|
|
||||||
/usr
|
|
||||||
/opt
|
|
||||||
)
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(ALUT DEFAULT_MSG ALUT_LIBRARY ALUT_INCLUDE_DIR)
|
|
||||||
|
|
||||||
MARK_AS_ADVANCED(ALUT_LIBRARY ALUT_INCLUDE_DIR)
|
|
||||||
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
# Find Subversion client libraries, and dependencies
|
|
||||||
# including APR (Apache Portable Runtime)
|
|
||||||
|
|
||||||
include (CheckFunctionExists)
|
|
||||||
include (CheckIncludeFile)
|
|
||||||
include (CheckLibraryExists)
|
|
||||||
|
|
||||||
macro(find_static_component comp libs)
|
|
||||||
# account for alternative Windows svn distribution naming
|
|
||||||
if(MSVC)
|
|
||||||
set(compLib "lib${comp}")
|
|
||||||
else(MSVC)
|
|
||||||
set(compLib "${comp}")
|
|
||||||
endif(MSVC)
|
|
||||||
|
|
||||||
string(TOUPPER "${comp}" compLibBase)
|
|
||||||
set( compLibName ${compLibBase}_LIBRARY )
|
|
||||||
|
|
||||||
FIND_LIBRARY(${compLibName}
|
|
||||||
NAMES ${compLib}
|
|
||||||
HINTS $ENV{PLIBDIR}
|
|
||||||
PATH_SUFFIXES lib64 lib libs64 libs libs/Win32 libs/Win64
|
|
||||||
PATHS
|
|
||||||
/usr/local
|
|
||||||
/usr
|
|
||||||
/opt
|
|
||||||
)
|
|
||||||
|
|
||||||
list(APPEND ${libs} ${${compLibName}})
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
find_program(HAVE_APR_CONFIG apr-1-config)
|
|
||||||
if(HAVE_APR_CONFIG)
|
|
||||||
|
|
||||||
execute_process(COMMAND apr-1-config --cppflags --includes
|
|
||||||
OUTPUT_VARIABLE APR_CFLAGS
|
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
||||||
|
|
||||||
execute_process(COMMAND apr-1-config --link-ld
|
|
||||||
OUTPUT_VARIABLE RAW_APR_LIBS
|
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
||||||
|
|
||||||
# clean up some vars, or other CMake pieces complain
|
|
||||||
string(STRIP "${RAW_APR_LIBS}" APR_LIBS)
|
|
||||||
|
|
||||||
else(HAVE_APR_CONFIG)
|
|
||||||
message(STATUS "apr-1-config not found, implement manual search for APR")
|
|
||||||
endif(HAVE_APR_CONFIG)
|
|
||||||
|
|
||||||
if(HAVE_APR_CONFIG OR MSVC)
|
|
||||||
find_path(LIBSVN_INCLUDE_DIR svn_client.h
|
|
||||||
HINTS
|
|
||||||
$ENV{LIBSVN_DIR}
|
|
||||||
PATH_SUFFIXES include/subversion-1
|
|
||||||
PATHS
|
|
||||||
/usr/local
|
|
||||||
/usr
|
|
||||||
/opt
|
|
||||||
)
|
|
||||||
|
|
||||||
set(LIBSVN_LIBRARIES "")
|
|
||||||
if (MSVC)
|
|
||||||
find_static_component("apr-1" LIBSVN_LIBRARIES)
|
|
||||||
else (MSVC)
|
|
||||||
list(APPEND LIBSVN_LIBRARIES ${APR_LIBS})
|
|
||||||
endif (MSVC)
|
|
||||||
find_static_component("svn_client-1" LIBSVN_LIBRARIES)
|
|
||||||
find_static_component("svn_subr-1" LIBSVN_LIBRARIES)
|
|
||||||
find_static_component("svn_ra-1" LIBSVN_LIBRARIES)
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LIBSVN DEFAULT_MSG LIBSVN_LIBRARIES LIBSVN_INCLUDE_DIR)
|
|
||||||
if(NOT LIBSVN_FOUND)
|
|
||||||
set(LIBSVN_LIBRARIES "")
|
|
||||||
endif(NOT LIBSVN_FOUND)
|
|
||||||
endif(HAVE_APR_CONFIG OR MSVC)
|
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
# - Get the platform-appropriate flags to add to force inclusion of a file
|
||||||
|
#
|
||||||
|
# The most common use of this is to use a generated config.h-type file
|
||||||
|
# placed out of the source tree in all files.
|
||||||
|
#
|
||||||
|
# get_force_include_definitions(var forcedincludefiles...) -
|
||||||
|
# where var is the name of your desired output variable, and everything
|
||||||
|
# else is a source file to forcibly include.
|
||||||
|
# a list item to be filtered.
|
||||||
|
#
|
||||||
|
# Original Author:
|
||||||
|
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
|
||||||
|
# http://academic.cleardefinition.com
|
||||||
|
# Iowa State University HCI Graduate Program/VRAC
|
||||||
|
#
|
||||||
|
# Copyright Iowa State University 2009-2010.
|
||||||
|
# Distributed under the Boost Software License, Version 1.0.
|
||||||
|
# (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
# http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
if(__get_force_include_definitions)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
set(__get_force_include_definitions YES)
|
||||||
|
|
||||||
|
function(get_force_include_definitions var)
|
||||||
|
set(_flagprefix)
|
||||||
|
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||||
|
set(_flag "-include")
|
||||||
|
elseif(MSVC)
|
||||||
|
set(_flag "/FI")
|
||||||
|
else()
|
||||||
|
message(SEND_ERROR "You don't seem to be using MSVC or GCC, but")
|
||||||
|
message(SEND_ERROR "the project called get_force_include_definitions.")
|
||||||
|
message(SEND_ERROR "Contact this project with the name of your")
|
||||||
|
message(FATAL_ERROR "compiler and preferably the flag to force includes")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(_out)
|
||||||
|
foreach(_item ${ARGN})
|
||||||
|
list(APPEND _out "${_flag} \"${_item}\"")
|
||||||
|
endforeach()
|
||||||
|
set(${var} "${_out}" PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
@@ -1,23 +1,21 @@
|
|||||||
|
|
||||||
macro(simgear_component_common name includePath sourcesList sources headers)
|
macro(simgear_component_common name includePath sourcesList sources headers)
|
||||||
if (SIMGEAR_SHARED)
|
set(fc${sourcesList} ${name})
|
||||||
|
set(fh${sourcesList} ${name})
|
||||||
|
foreach(s ${sources})
|
||||||
|
set_property(GLOBAL
|
||||||
|
APPEND PROPERTY ${sourcesList} "${CMAKE_CURRENT_SOURCE_DIR}/${s}")
|
||||||
|
set(fc${sourcesList} "${fc${sourcesList}}#${CMAKE_CURRENT_SOURCE_DIR}/${s}")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
foreach(s ${sources})
|
foreach(h ${headers})
|
||||||
set_property(GLOBAL
|
set_property(GLOBAL
|
||||||
APPEND PROPERTY ${sourcesList} "${CMAKE_CURRENT_SOURCE_DIR}/${s}")
|
APPEND PROPERTY PUBLIC_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/${h}")
|
||||||
endforeach()
|
set(fh${sourcesList} "${fh${sourcesList}}#${CMAKE_CURRENT_SOURCE_DIR}/${h}")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
foreach(h ${headers})
|
set_property(GLOBAL APPEND PROPERTY FG_GROUPS_${sourcesList}_C "${fc${sourcesList}}@")
|
||||||
set_property(GLOBAL
|
set_property(GLOBAL APPEND PROPERTY FG_GROUPS_${sourcesList}_H "${fh${sourcesList}}@")
|
||||||
APPEND PROPERTY PUBLIC_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/${h}")
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
else()
|
|
||||||
set(libName "sg${name}")
|
|
||||||
add_library(${libName} STATIC ${sources} ${headers})
|
|
||||||
|
|
||||||
install (TARGETS ${libName} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
install (FILES ${headers} DESTINATION include/simgear/${includePath})
|
install (FILES ${headers} DESTINATION include/simgear/${includePath})
|
||||||
endmacro()
|
endmacro()
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ SimGear depends on a number of 3rd party libraries, the most notable
|
|||||||
being:
|
being:
|
||||||
|
|
||||||
* OpenSceneGraph (OSG) - see README.OSG
|
* OpenSceneGraph (OSG) - see README.OSG
|
||||||
* Portable Games Library (PLIB) - see README.plib
|
|
||||||
* zlib compression library - see README.zlib
|
* zlib compression library - see README.zlib
|
||||||
* Open Audio Library (OpenAL) - see README.OpenAL
|
* Open Audio Library (OpenAL) - see README.OpenAL
|
||||||
* Subversion Client Library (optional dependency)
|
* Subversion Client Library (optional dependency)
|
||||||
|
|||||||
@@ -18,12 +18,3 @@ ccmake .
|
|||||||
then press 'g' to generate and exit ]
|
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
|
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -20,8 +20,8 @@ Probably you want to specify an install prefix:
|
|||||||
cmake ../simgear -DCMAKE_INSTALL_PREFIX=/usr
|
cmake ../simgear -DCMAKE_INSTALL_PREFIX=/usr
|
||||||
|
|
||||||
Note the install prefix is automatically searched for required libraries
|
Note the install prefix is automatically searched for required libraries
|
||||||
and header files, so if you install PLIB, OpenSceneGraph to the
|
and header files, so if you install OpenSceneGraph to the same prefix,
|
||||||
same prefix, most configuration options are unnecessary.
|
most configuration options are unnecessary.
|
||||||
|
|
||||||
If for some reason you have a dependency (or several) at a different prefix,
|
If for some reason you have a dependency (or several) at a different prefix,
|
||||||
you can specify one or more via CMAKE_PREFIX_PATH:
|
you can specify one or more via CMAKE_PREFIX_PATH:
|
||||||
@@ -33,7 +33,7 @@ you can specify one or more via CMAKE_PREFIX_PATH:
|
|||||||
Standard prefixes are searched automatically (/usr, /usr/local, /opt/local)
|
Standard prefixes are searched automatically (/usr, /usr/local, /opt/local)
|
||||||
|
|
||||||
Most dependencies also expose an environment variable to specify their
|
Most dependencies also expose an environment variable to specify their
|
||||||
installation directory explicitly eg OSG_DIR or PLIBDIR. Any of the methods
|
installation directory explicitly eg OSG_DIR. Any of the methods
|
||||||
described above will work, but specifying an INSTALL_PREFIX or PREFIX_PATH is
|
described above will work, but specifying an INSTALL_PREFIX or PREFIX_PATH is
|
||||||
usually simpler.
|
usually simpler.
|
||||||
|
|
||||||
|
|||||||
-32
@@ -1,32 +0,0 @@
|
|||||||
[This file is mirrored in both the FlightGear and SimGear packages.]
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
You can get the latest version of plib from:
|
|
||||||
|
|
||||||
http://plib.sourceforge.net
|
|
||||||
|
|
||||||
Build notes:
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
Building a SimGear RPM package for Red Hat
|
||||||
|
|
||||||
|
Please see the "package/openSUSE" directory for an
|
||||||
|
example how to build a SimGear RPM package with
|
||||||
|
shared SimGear libraries.
|
||||||
|
|
||||||
|
You may need to adapt the names (exact spelling) of some
|
||||||
|
of the package dependencies in the openSUSE RPM spec,
|
||||||
|
since these may slightly differ for Red Hat.
|
||||||
|
|
||||||
|
(If you have a working and tested Red Hat RPM spec,
|
||||||
|
you're welcome to contribute it to this project.)
|
||||||
|
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
Building a SimGear RPM package for openSUSE
|
||||||
|
|
||||||
|
(Last tested with openSUSE 11.4+12.1)
|
||||||
|
|
||||||
|
This directory contains the files which, along with
|
||||||
|
the source code tar files, can be used to build
|
||||||
|
an RPM package targeted at an openSUSE Linux system.
|
||||||
|
|
||||||
|
To build SimGear from source do the following:
|
||||||
|
|
||||||
|
1. obtain simgear-2.8.0.tar.bz2 (adapt version if
|
||||||
|
necessary) and copy it into ~/rpmbuild/SOURCES
|
||||||
|
|
||||||
|
2. look in the BuildRequires section of SimGear.spec
|
||||||
|
and check that all the packages referred to are
|
||||||
|
installed (note, some of these packages may be part
|
||||||
|
of openSUSE's "games" repository).
|
||||||
|
|
||||||
|
3. run 'rpmbuild -ba simgear.spec' and find the RPM
|
||||||
|
build result in ~/rpmbuild/RPMS
|
||||||
|
|
||||||
|
That's all!
|
||||||
|
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
Summary: Simulator Construction Gear
|
||||||
|
Name: SimGear
|
||||||
|
Version: 2.8.0
|
||||||
|
Release: 1
|
||||||
|
License: LGPL
|
||||||
|
URL: http://www.flightgear.org
|
||||||
|
Group: Amusements/Games/3D/Simulation
|
||||||
|
Source: http://mirrors.ibiblio.org/pub/mirrors/flightgear/ftp/Source/simgear-%{version}.tar.bz2
|
||||||
|
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||||
|
|
||||||
|
BuildRequires: gcc, gcc-c++, cmake
|
||||||
|
BuildRequires: libopenal1-soft, openal-soft
|
||||||
|
BuildRequires: libOpenSceneGraph-devel >= 3.0
|
||||||
|
BuildRequires: zlib, zlib-devel
|
||||||
|
BuildRequires: libjpeg62, libjpeg62-devel
|
||||||
|
BuildRequires: boost-devel >= 1.37
|
||||||
|
BuildRequires: subversion-devel, libapr1-devel
|
||||||
|
Requires: OpenSceneGraph-plugins >= 3.0
|
||||||
|
|
||||||
|
%description
|
||||||
|
This package contains a tools and libraries useful for constructing
|
||||||
|
simulation and visualization applications such as FlightGear or TerraGear.
|
||||||
|
|
||||||
|
%package devel
|
||||||
|
Group: Development/Libraries/Other
|
||||||
|
Summary: Development header files for SimGear
|
||||||
|
Requires: SimGear = %{version}
|
||||||
|
|
||||||
|
%description devel
|
||||||
|
Development headers and libraries for building applications against SimGear.
|
||||||
|
|
||||||
|
%prep
|
||||||
|
%setup -T -q -n simgear-%{version} -b 0
|
||||||
|
|
||||||
|
%build
|
||||||
|
export CFLAGS="$RPM_OPT_FLAGS"
|
||||||
|
export CXXFLAGS="$RPM_OPT_FLAGS"
|
||||||
|
# build SHARED simgear libraries
|
||||||
|
cmake -DCMAKE_INSTALL_PREFIX=%{_prefix} -DSIMGEAR_SHARED:BOOL=ON -DENABLE_TESTS:BOOL=OFF -DJPEG_FACTORY:BOOL=ON
|
||||||
|
make %{?_smp_mflags}
|
||||||
|
|
||||||
|
%install
|
||||||
|
make DESTDIR=%{buildroot} install
|
||||||
|
|
||||||
|
%post -p /sbin/ldconfig
|
||||||
|
|
||||||
|
%postun -p /sbin/ldconfig
|
||||||
|
|
||||||
|
%files
|
||||||
|
%defattr (-, root, root, -)
|
||||||
|
%doc AUTHORS COPYING ChangeLog NEWS README
|
||||||
|
%{_libdir}/libSimGear*.so.*
|
||||||
|
|
||||||
|
%files devel
|
||||||
|
%defattr(-,root,root,-)
|
||||||
|
%dir %{_includedir}/simgear
|
||||||
|
%{_includedir}/simgear/*
|
||||||
|
%{_libdir}/libSimGear*.so
|
||||||
|
|
||||||
|
%changelog
|
||||||
|
* Mon Jul 02 2012 thorstenb@flightgear.org
|
||||||
|
- Initial version
|
||||||
|
|
||||||
+84
-34
@@ -3,6 +3,7 @@ file(WRITE ${PROJECT_BINARY_DIR}/simgear/version.h "#define SIMGEAR_VERSION ${SI
|
|||||||
|
|
||||||
foreach( mylibfolder
|
foreach( mylibfolder
|
||||||
bucket
|
bucket
|
||||||
|
bvh
|
||||||
debug
|
debug
|
||||||
ephemeris
|
ephemeris
|
||||||
io
|
io
|
||||||
@@ -10,12 +11,14 @@ foreach( mylibfolder
|
|||||||
math
|
math
|
||||||
misc
|
misc
|
||||||
nasal
|
nasal
|
||||||
|
nasal/cppbind
|
||||||
props
|
props
|
||||||
serial
|
serial
|
||||||
structure
|
structure
|
||||||
threads
|
threads
|
||||||
timing
|
timing
|
||||||
xml
|
xml
|
||||||
|
package
|
||||||
)
|
)
|
||||||
|
|
||||||
add_subdirectory(${mylibfolder})
|
add_subdirectory(${mylibfolder})
|
||||||
@@ -23,6 +26,7 @@ foreach( mylibfolder
|
|||||||
endforeach( mylibfolder )
|
endforeach( mylibfolder )
|
||||||
|
|
||||||
if(NOT SIMGEAR_HEADLESS)
|
if(NOT SIMGEAR_HEADLESS)
|
||||||
|
add_subdirectory(canvas)
|
||||||
add_subdirectory(environment)
|
add_subdirectory(environment)
|
||||||
add_subdirectory(screen)
|
add_subdirectory(screen)
|
||||||
add_subdirectory(scene)
|
add_subdirectory(scene)
|
||||||
@@ -38,56 +42,102 @@ endif(ENABLE_RTI)
|
|||||||
set(HEADERS compiler.h constants.h sg_inlines.h ${PROJECT_BINARY_DIR}/simgear/version.h)
|
set(HEADERS compiler.h constants.h sg_inlines.h ${PROJECT_BINARY_DIR}/simgear/version.h)
|
||||||
install (FILES ${HEADERS} DESTINATION include/simgear/)
|
install (FILES ${HEADERS} DESTINATION include/simgear/)
|
||||||
|
|
||||||
|
get_property(coreSources GLOBAL PROPERTY CORE_SOURCES)
|
||||||
|
get_property(sceneSources GLOBAL PROPERTY SCENE_SOURCES)
|
||||||
|
get_property(publicHeaders GLOBAL PROPERTY PUBLIC_HEADERS)
|
||||||
|
get_property(localExpatSources GLOBAL PROPERTY LOCAL_EXPAT_SOURCES)
|
||||||
|
|
||||||
if(SIMGEAR_SHARED)
|
if(SIMGEAR_SHARED)
|
||||||
message(STATUS "Library building mode: SHARED LIBRARIES")
|
message(STATUS "Library building mode: SHARED LIBRARIES")
|
||||||
get_property(coreSources GLOBAL PROPERTY CORE_SOURCES)
|
add_library(SimGearCore SHARED ${coreSources} ${localExpatSources})
|
||||||
get_property(sceneSources GLOBAL PROPERTY SCENE_SOURCES)
|
|
||||||
get_property(publicHeaders GLOBAL PROPERTY PUBLIC_HEADERS)
|
|
||||||
|
|
||||||
add_library(SimGearCore SHARED ${coreSources})
|
|
||||||
|
|
||||||
# set_property(TARGET SimGearCore PROPERTY FRAMEWORK 1)
|
|
||||||
# message(STATUS "public header: ${publicHeaders}")
|
|
||||||
# set_property(TARGET SimGearCore PROPERTY PUBLIC_HEADER "${publicHeaders}")
|
|
||||||
set_property(TARGET SimGearCore PROPERTY LINKER_LANGUAGE CXX)
|
set_property(TARGET SimGearCore PROPERTY LINKER_LANGUAGE CXX)
|
||||||
|
|
||||||
set_property(TARGET SimGearCore PROPERTY VERSION ${SIMGEAR_VERSION})
|
set_property(TARGET SimGearCore PROPERTY VERSION ${SIMGEAR_VERSION})
|
||||||
set_property(TARGET SimGearCore PROPERTY SOVERSION ${SIMGEAR_SOVERSION})
|
set_property(TARGET SimGearCore PROPERTY SOVERSION ${SIMGEAR_SOVERSION})
|
||||||
|
install(TARGETS SimGearCore EXPORT SimGearCoreConfig LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||||
target_link_libraries(SimGearCore ${ZLIB_LIBRARY} ${RT_LIBRARY})
|
install(EXPORT SimGearCoreConfig DESTINATION share/SimGearCore)
|
||||||
install(TARGETS SimGearCore LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
|
||||||
|
|
||||||
if(LIBSVN_FOUND)
|
|
||||||
add_definitions(${APR_CFLAGS})
|
|
||||||
|
|
||||||
IF(APPLE)
|
|
||||||
set_property(SOURCE scene/tsync/terrasync.cxx PROPERTY COMPILE_FLAGS "-iwithsysroot ${LIBSVN_INCLUDE_DIR}")
|
|
||||||
ELSE()
|
|
||||||
include_directories(${LIBSVN_INCLUDE_DIR})
|
|
||||||
ENDIF(APPLE)
|
|
||||||
target_link_libraries(SimGearCore ${LIBSVN_LIBRARIES})
|
|
||||||
endif(LIBSVN_FOUND)
|
|
||||||
|
|
||||||
if(NOT SIMGEAR_HEADLESS)
|
if(NOT SIMGEAR_HEADLESS)
|
||||||
add_library(SimGearScene SHARED ${sceneSources})
|
add_library(SimGearScene SHARED ${sceneSources})
|
||||||
# set_property(TARGET SimGearScene PROPERTY FRAMEWORK 1)
|
|
||||||
# set_property(TARGET SimGearScene PROPERTY PUBLIC_HEADER "${publicHeaders}")
|
|
||||||
set_property(TARGET SimGearScene PROPERTY LINKER_LANGUAGE CXX)
|
set_property(TARGET SimGearScene PROPERTY LINKER_LANGUAGE CXX)
|
||||||
set_property(TARGET SimGearScene PROPERTY VERSION ${SIMGEAR_VERSION})
|
set_property(TARGET SimGearScene PROPERTY VERSION ${SIMGEAR_VERSION})
|
||||||
set_property(TARGET SimGearScene PROPERTY SOVERSION ${SIMGEAR_SOVERSION})
|
set_property(TARGET SimGearScene PROPERTY SOVERSION ${SIMGEAR_SOVERSION})
|
||||||
|
|
||||||
target_link_libraries(SimGearScene
|
# EXPORT SimGearSceneConfig
|
||||||
SimGearCore
|
install(TARGETS SimGearScene LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} )
|
||||||
${ZLIB_LIBRARY}
|
# install(EXPORT SimGearSceneConfig DESTINATION share/SimGearScene)
|
||||||
${OPENSCENEGRAPH_LIBRARIES}
|
|
||||||
${OPENAL_LIBRARY} ${ALUT_LIBRARY}
|
|
||||||
${OPENGL_LIBRARY}
|
|
||||||
${JPEG_LIBRARY})
|
|
||||||
|
|
||||||
install(TARGETS SimGearScene LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
else()
|
else()
|
||||||
message(STATUS "Library building mode: STATIC LIBRARIES")
|
message(STATUS "Library building mode: STATIC LIBRARIES")
|
||||||
|
|
||||||
|
get_property(FG_GROUPS_CORE_SOURCES_C GLOBAL PROPERTY FG_GROUPS_CORE_SOURCES_C)
|
||||||
|
string(REPLACE "@" ";" groups ${FG_GROUPS_CORE_SOURCES_C} )
|
||||||
|
foreach(g ${groups})
|
||||||
|
string(REPLACE "#" ";" g2 ${g})
|
||||||
|
list(GET g2 0 name)
|
||||||
|
list(REMOVE_AT g2 0)
|
||||||
|
source_group("${name}\\Sources" FILES ${g2})
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
get_property(FG_GROUPS_CORE_SOURCES_H GLOBAL PROPERTY FG_GROUPS_CORE_SOURCES_H)
|
||||||
|
string(REPLACE "@" ";" groups ${FG_GROUPS_CORE_SOURCES_H} )
|
||||||
|
foreach(g ${groups})
|
||||||
|
string(REPLACE "#" ";" g2 ${g})
|
||||||
|
list(GET g2 0 name)
|
||||||
|
list(REMOVE_AT g2 0)
|
||||||
|
source_group("${name}\\Headers" FILES ${g2})
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
add_library(SimGearCore STATIC ${coreSources} ${localExpatSources})
|
||||||
|
install(TARGETS SimGearCore ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||||
|
|
||||||
|
if(NOT SIMGEAR_HEADLESS)
|
||||||
|
get_property(FG_GROUPS_SCENE_SOURCES_C GLOBAL PROPERTY FG_GROUPS_SCENE_SOURCES_C)
|
||||||
|
string(REPLACE "@" ";" groups ${FG_GROUPS_SCENE_SOURCES_C} )
|
||||||
|
foreach(g ${groups})
|
||||||
|
string(REPLACE "#" ";" g2 ${g})
|
||||||
|
list(GET g2 0 name)
|
||||||
|
list(REMOVE_AT g2 0)
|
||||||
|
source_group("${name}\\Sources" FILES ${g2})
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
get_property(FG_GROUPS_SCENE_SOURCES_H GLOBAL PROPERTY FG_GROUPS_SCENE_SOURCES_H)
|
||||||
|
string(REPLACE "@" ";" groups ${FG_GROUPS_SCENE_SOURCES_H} )
|
||||||
|
foreach(g ${groups})
|
||||||
|
string(REPLACE "#" ";" g2 ${g})
|
||||||
|
list(GET g2 0 name)
|
||||||
|
list(REMOVE_AT g2 0)
|
||||||
|
source_group("${name}\\Headers" FILES ${g2})
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
add_library(SimGearScene STATIC ${sceneSources})
|
||||||
|
install(TARGETS SimGearScene ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||||
|
endif(NOT SIMGEAR_HEADLESS)
|
||||||
endif(SIMGEAR_SHARED)
|
endif(SIMGEAR_SHARED)
|
||||||
|
|
||||||
|
target_link_libraries(SimGearCore
|
||||||
|
${ZLIB_LIBRARY}
|
||||||
|
${RT_LIBRARY}
|
||||||
|
${DL_LIBRARY}
|
||||||
|
${EXPAT_LIBRARIES}
|
||||||
|
${CMAKE_THREAD_LIBS_INIT}
|
||||||
|
${COCOA_LIBRARY})
|
||||||
|
|
||||||
|
if(NOT SIMGEAR_HEADLESS)
|
||||||
|
target_link_libraries(SimGearScene
|
||||||
|
SimGearCore
|
||||||
|
${ZLIB_LIBRARY}
|
||||||
|
${OPENSCENEGRAPH_LIBRARIES}
|
||||||
|
${OPENAL_LIBRARY}
|
||||||
|
${OPENGL_LIBRARY}
|
||||||
|
${JPEG_LIBRARY})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(ENABLE_RTI)
|
||||||
|
# Ugly first aid to make hla compile agian
|
||||||
|
set_property(SOURCE hla/RTI13InteractionClass.cxx hla/RTI13ObjectClass.cxx
|
||||||
|
hla/RTI13ObjectInstance.cxx hla/RTI13Federate.cxx
|
||||||
|
hla/RTI13FederateFactory.cxx
|
||||||
|
APPEND PROPERTY COMPILE_FLAGS "-I${RTI_INCLUDE_DIR}")
|
||||||
|
endif(ENABLE_RTI)
|
||||||
|
|||||||
@@ -5,3 +5,12 @@ set(HEADERS newbucket.hxx)
|
|||||||
set(SOURCES newbucket.cxx)
|
set(SOURCES newbucket.cxx)
|
||||||
|
|
||||||
simgear_component(bucket bucket "${SOURCES}" "${HEADERS}")
|
simgear_component(bucket bucket "${SOURCES}" "${HEADERS}")
|
||||||
|
|
||||||
|
|
||||||
|
if(ENABLE_TESTS)
|
||||||
|
|
||||||
|
add_executable(test_bucket test_bucket.cxx)
|
||||||
|
add_test(test_bucket ${EXECUTABLE_OUTPUT_PATH}/test_bucket)
|
||||||
|
target_link_libraries(test_bucket ${TEST_LIBS})
|
||||||
|
|
||||||
|
endif(ENABLE_TESTS)
|
||||||
+168
-98
@@ -27,36 +27,56 @@
|
|||||||
# include <simgear_config.h>
|
# include <simgear_config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <math.h>
|
#include <cmath>
|
||||||
|
#include <cstdio> // some platforms need this for ::snprintf
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include <simgear/misc/sg_path.hxx>
|
#include <simgear/misc/sg_path.hxx>
|
||||||
|
#include <simgear/debug/logstream.hxx>
|
||||||
|
|
||||||
#include "newbucket.hxx"
|
#include "newbucket.hxx"
|
||||||
|
|
||||||
|
|
||||||
// default constructor
|
// default constructor
|
||||||
SGBucket::SGBucket() {
|
SGBucket::SGBucket() :
|
||||||
|
lon(-1000),
|
||||||
|
lat(-1000),
|
||||||
|
x(0),
|
||||||
|
y(0)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SGBucket::isValid() const
|
||||||
|
{
|
||||||
|
// The most northerly valid latitude is 89, not 90. There is no tile
|
||||||
|
// whose *bottom* latitude is 90. Similar there is no tile whose left egde
|
||||||
|
// is 180 longitude.
|
||||||
|
return (lon >= -180) &&
|
||||||
|
(lon < 180) &&
|
||||||
|
(lat >= -90) &&
|
||||||
|
(lat < 90) &&
|
||||||
|
(x < 8) && (y < 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SGBucket::make_bad()
|
||||||
|
{
|
||||||
|
lon = -1000;
|
||||||
|
lat = -1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NO_DEPRECATED_API
|
||||||
|
|
||||||
// constructor for specified location
|
// constructor for specified location
|
||||||
SGBucket::SGBucket(const double dlon, const double dlat) {
|
SGBucket::SGBucket(const double dlon, const double dlat) {
|
||||||
set_bucket(dlon, dlat);
|
set_bucket(dlon, dlat);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
SGBucket::SGBucket(const SGGeod& geod) {
|
SGBucket::SGBucket(const SGGeod& geod) {
|
||||||
set_bucket(geod);
|
innerSet(geod.getLongitudeDeg(),
|
||||||
|
geod.getLatitudeDeg());
|
||||||
}
|
}
|
||||||
|
|
||||||
// create an impossible bucket if false
|
|
||||||
SGBucket::SGBucket(const bool is_good) {
|
|
||||||
set_bucket(0.0, 0.0);
|
|
||||||
if ( !is_good ) {
|
|
||||||
lon = -1000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Parse a unique scenery tile index and find the lon, lat, x, and y
|
// Parse a unique scenery tile index and find the lon, lat, x, and y
|
||||||
SGBucket::SGBucket(const long int bindex) {
|
SGBucket::SGBucket(const long int bindex) {
|
||||||
long int index = bindex;
|
long int index = bindex;
|
||||||
@@ -75,48 +95,59 @@ SGBucket::SGBucket(const long int bindex) {
|
|||||||
x = index;
|
x = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Calculate the greatest integral value less than
|
||||||
|
* or equal to the given value (floor(x)),
|
||||||
|
* but attribute coordinates close to the boundary to the next
|
||||||
|
* (increasing) integral
|
||||||
|
*/
|
||||||
|
static int floorWithEpsilon(double x)
|
||||||
|
{
|
||||||
|
return static_cast<int>(floor(x + SG_EPSILON));
|
||||||
|
}
|
||||||
|
|
||||||
// Set the bucket params for the specified lat and lon
|
#ifndef NO_DEPRECATED_API
|
||||||
void SGBucket::set_bucket( double *lonlat ) {
|
|
||||||
set_bucket( lonlat[0], lonlat[1] );
|
void SGBucket::set_bucket(double dlon, double dlat)
|
||||||
|
{
|
||||||
|
innerSet(dlon, dlat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SGBucket::set_bucket(const SGGeod& geod)
|
||||||
|
{
|
||||||
|
innerSet(geod.getLongitudeDeg(), geod.getLatitudeDeg());
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
// Set the bucket params for the specified lat and lon
|
// Set the bucket params for the specified lat and lon
|
||||||
void SGBucket::set_bucket( double dlon, double dlat ) {
|
void SGBucket::innerSet( double dlon, double dlat )
|
||||||
//
|
{
|
||||||
// latitude first
|
if ((dlon < -180.0) || (dlon >= 180.0)) {
|
||||||
//
|
SG_LOG(SG_TERRAIN, SG_WARN, "SGBucket::set_bucket: passed longitude:" << dlon);
|
||||||
double span = sg_bucket_span( dlat );
|
dlon = SGMiscd::normalizePeriodic(-180.0, 180.0, dlon);
|
||||||
double diff = dlon - (double)(int)dlon;
|
|
||||||
|
|
||||||
// cout << "diff = " << diff << " span = " << span << endl;
|
|
||||||
|
|
||||||
/* Calculate the greatest integral longitude less than
|
|
||||||
* or equal to the given longitude (floor(dlon)),
|
|
||||||
* but attribute coordinates near the east border
|
|
||||||
* to the next tile.
|
|
||||||
*/
|
|
||||||
if ( (dlon >= 0) || (fabs(diff) < SG_EPSILON) ) {
|
|
||||||
lon = (int)dlon;
|
|
||||||
} else {
|
|
||||||
lon = (int)dlon - 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((dlat < -90.0) || (dlat > 90.0)) {
|
||||||
|
SG_LOG(SG_TERRAIN, SG_WARN, "SGBucket::set_bucket: passed latitude" << dlat);
|
||||||
|
dlat = SGMiscd::clip(dlat, -90.0, 90.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// longitude first
|
||||||
|
//
|
||||||
|
double span = sg_bucket_span( dlat );
|
||||||
|
// we do NOT need to special case lon=180 here, since
|
||||||
|
// normalizePeriodic will never return 180; it will
|
||||||
|
// return -180, which is what we want.
|
||||||
|
lon = floorWithEpsilon(dlon);
|
||||||
|
|
||||||
// find subdivision or super lon if needed
|
// find subdivision or super lon if needed
|
||||||
if ( span < SG_EPSILON ) {
|
if ( span <= 1.0 ) {
|
||||||
/* sg_bucket_span() never returns 0.0
|
|
||||||
* or anything near it, so this really
|
|
||||||
* should not occur at any time.
|
|
||||||
*/
|
|
||||||
// polar cap
|
|
||||||
lon = 0;
|
|
||||||
x = 0;
|
|
||||||
} else if ( span <= 1.0 ) {
|
|
||||||
/* We have more than one tile per degree of
|
/* We have more than one tile per degree of
|
||||||
* longitude, so we need an x offset.
|
* longitude, so we need an x offset.
|
||||||
*/
|
*/
|
||||||
x = (int)((dlon - lon) / span);
|
x = floorWithEpsilon((dlon - lon) / span);
|
||||||
} else {
|
} else {
|
||||||
/* We have one or more degrees per tile,
|
/* We have one or more degrees per tile,
|
||||||
* so we need to find the base longitude
|
* so we need to find the base longitude
|
||||||
@@ -129,48 +160,28 @@ void SGBucket::set_bucket( double dlon, double dlat ) {
|
|||||||
*
|
*
|
||||||
* That way, the Greenwich Meridian is always
|
* That way, the Greenwich Meridian is always
|
||||||
* a tile border.
|
* a tile border.
|
||||||
*
|
|
||||||
* This gets us into trouble with the polar caps,
|
|
||||||
* which have width 360 and thus either span
|
|
||||||
* the range from 0 to 360 or from -360 to 0
|
|
||||||
* degrees, depending on whether lon is positive
|
|
||||||
* or negative!
|
|
||||||
*
|
|
||||||
* We also get into trouble with the 8 degree tiles
|
|
||||||
* north of 88N and south of 88S, because the west-
|
|
||||||
* and east-most tiles in that range will cover 184W
|
|
||||||
* to 176W and 176E to 184E respectively, with their
|
|
||||||
* center at 180E/W!
|
|
||||||
*/
|
*/
|
||||||
lon=(int)floor(floor((lon+SG_EPSILON)/span)*span);
|
lon=static_cast<int>(floor(lon / span) * span);
|
||||||
/* Correct the polar cap issue */
|
x = 0;
|
||||||
if ( lon < -180 ) {
|
|
||||||
lon = -180;
|
|
||||||
}
|
|
||||||
x = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// then latitude
|
// then latitude
|
||||||
//
|
//
|
||||||
diff = dlat - (double)(int)dlat;
|
lat = floorWithEpsilon(dlat);
|
||||||
|
|
||||||
/* Again, a modified floor() function (see longitude) */
|
// special case when passing in the north pole point (possibly due to
|
||||||
if ( (dlat >= 0) || (fabs(diff) < SG_EPSILON) ) {
|
// clipping latitude above). Ensures we generate a valid bucket in this
|
||||||
lat = (int)dlat;
|
// scenario
|
||||||
|
if (lat == 90) {
|
||||||
|
lat = 89;
|
||||||
|
y = 7;
|
||||||
} else {
|
} else {
|
||||||
lat = (int)dlat - 1;
|
/* Latitude base and offset are easier, as
|
||||||
|
* tiles always are 1/8 degree of latitude wide.
|
||||||
|
*/
|
||||||
|
y = floorWithEpsilon((dlat - lat) * 8);
|
||||||
}
|
}
|
||||||
/* Latitude base and offset are easier, as
|
|
||||||
* tiles always are 1/8 degree of latitude wide.
|
|
||||||
*/
|
|
||||||
y = (int)((dlat - lat) * 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SGBucket::set_bucket(const SGGeod& geod)
|
|
||||||
{
|
|
||||||
set_bucket(geod.getLongitudeDeg(), geod.getLatitudeDeg());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the path name for this bucket
|
// Build the path name for this bucket
|
||||||
@@ -212,7 +223,7 @@ std::string SGBucket::gen_base_path() const {
|
|||||||
main_lat *= -1;
|
main_lat *= -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(raw_path, "%c%03d%c%02d/%c%03d%c%02d",
|
::snprintf(raw_path, 256, "%c%03d%c%02d/%c%03d%c%02d",
|
||||||
hem, top_lon, pole, top_lat,
|
hem, top_lon, pole, top_lat,
|
||||||
hem, main_lon, pole, main_lat);
|
hem, main_lon, pole, main_lat);
|
||||||
|
|
||||||
@@ -224,17 +235,6 @@ std::string SGBucket::gen_base_path() const {
|
|||||||
|
|
||||||
// return width of the tile in degrees
|
// return width of the tile in degrees
|
||||||
double SGBucket::get_width() const {
|
double SGBucket::get_width() const {
|
||||||
if (lon==-180 && (lat==-89 || lat==88) ) {
|
|
||||||
/* Normally the tile at 180W in 88N and 89S
|
|
||||||
* would cover 184W to 176W and the next
|
|
||||||
* on the east side starts at 176W.
|
|
||||||
* To correct, make this a special tile
|
|
||||||
* from 180W to 176W with 4 degrees width
|
|
||||||
* instead of the normal 8 degrees at
|
|
||||||
* that latitude.
|
|
||||||
*/
|
|
||||||
return 4.0;
|
|
||||||
}
|
|
||||||
return sg_bucket_span( get_center_lat() );
|
return sg_bucket_span( get_center_lat() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,17 +244,32 @@ double SGBucket::get_height() const {
|
|||||||
return SG_BUCKET_SPAN;
|
return SG_BUCKET_SPAN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double SGBucket::get_highest_lat() const
|
||||||
// return width of the tile in meters
|
{
|
||||||
double SGBucket::get_width_m() const {
|
unsigned char adjustedY = y;
|
||||||
double clat = (int)get_center_lat();
|
if (lat >= 0) {
|
||||||
if ( clat > 0 ) {
|
// tile is north of the equator, so we want the top edge. Add one
|
||||||
clat = (int)clat + 0.5;
|
// to y to achieve this.
|
||||||
} else {
|
++adjustedY;
|
||||||
clat = (int)clat - 0.5;
|
|
||||||
}
|
}
|
||||||
double clat_rad = clat * SGD_DEGREES_TO_RADIANS;
|
|
||||||
|
return lat + (adjustedY / 8.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// return width of the tile in meters. This function is used by the
|
||||||
|
// tile-manager to estimate how many tiles are in the view distance, so
|
||||||
|
// we care about the smallest width, which occurs at the highest latitude.
|
||||||
|
double SGBucket::get_width_m() const
|
||||||
|
{
|
||||||
|
double clat_rad = get_highest_lat() * SGD_DEGREES_TO_RADIANS;
|
||||||
double cos_lat = cos( clat_rad );
|
double cos_lat = cos( clat_rad );
|
||||||
|
if (fabs(cos_lat) < SG_EPSILON) {
|
||||||
|
// happens for polar tiles, since we pass in a latitude of 90
|
||||||
|
// return an arbitrary small value so all tiles are loaded
|
||||||
|
return 10.0;
|
||||||
|
}
|
||||||
|
|
||||||
double local_radius = cos_lat * SG_EQUATORIAL_RADIUS_M;
|
double local_radius = cos_lat * SG_EQUATORIAL_RADIUS_M;
|
||||||
double local_perimeter = local_radius * SGD_2PI;
|
double local_perimeter = local_radius * SGD_2PI;
|
||||||
double degree_width = local_perimeter / 360.0;
|
double degree_width = local_perimeter / 360.0;
|
||||||
@@ -271,7 +286,41 @@ double SGBucket::get_height_m() const {
|
|||||||
return SG_BUCKET_SPAN * degree_height;
|
return SG_BUCKET_SPAN * degree_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SGBucket SGBucket::sibling(int dx, int dy) const
|
||||||
|
{
|
||||||
|
if (!isValid()) {
|
||||||
|
SG_LOG(SG_TERRAIN, SG_WARN, "SGBucket::sibling: requesting sibling of invalid bucket");
|
||||||
|
return SGBucket();
|
||||||
|
}
|
||||||
|
|
||||||
|
double clat = get_center_lat() + dy * SG_BUCKET_SPAN;
|
||||||
|
// return invalid here instead of clipping, so callers can discard
|
||||||
|
// invalid buckets without having to check if it's an existing one
|
||||||
|
if ((clat < -90.0) || (clat > 90.0)) {
|
||||||
|
return SGBucket();
|
||||||
|
}
|
||||||
|
|
||||||
|
// find the lon span for the new latitude
|
||||||
|
double span = sg_bucket_span( clat );
|
||||||
|
|
||||||
|
double tmp = get_center_lon() + dx * span;
|
||||||
|
tmp = SGMiscd::normalizePeriodic(-180.0, 180.0, tmp);
|
||||||
|
|
||||||
|
SGBucket b;
|
||||||
|
b.innerSet(tmp, clat);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string SGBucket::gen_index_str() const
|
||||||
|
{
|
||||||
|
char tmp[20];
|
||||||
|
::snprintf(tmp, 20, "%ld",
|
||||||
|
(((long)lon + 180) << 14) + ((lat + 90) << 6)
|
||||||
|
+ (y << 3) + x);
|
||||||
|
return (std::string)tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NO_DEPRECATED_API
|
||||||
// find the bucket which is offset by the specified tile units in the
|
// find the bucket which is offset by the specified tile units in the
|
||||||
// X & Y direction. We need the current lon and lat to resolve
|
// X & Y direction. We need the current lon and lat to resolve
|
||||||
// ambiguities when going from a wider tile to a narrower one above or
|
// ambiguities when going from a wider tile to a narrower one above or
|
||||||
@@ -298,7 +347,7 @@ SGBucket sgBucketOffset( double dlon, double dlat, int dx, int dy ) {
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// calculate the offset between two buckets
|
// calculate the offset between two buckets
|
||||||
void sgBucketDiff( const SGBucket& b1, const SGBucket& b2, int *dx, int *dy ) {
|
void sgBucketDiff( const SGBucket& b1, const SGBucket& b2, int *dx, int *dy ) {
|
||||||
@@ -356,4 +405,25 @@ void sgBucketDiff( const SGBucket& b1, const SGBucket& b2, int *dx, int *dy ) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sgGetBuckets( const SGGeod& min, const SGGeod& max, std::vector<SGBucket>& list ) {
|
||||||
|
double lon, lat, span;
|
||||||
|
|
||||||
|
for (lat = min.getLatitudeDeg(); lat < max.getLatitudeDeg()+SG_BUCKET_SPAN; lat += SG_BUCKET_SPAN) {
|
||||||
|
span = sg_bucket_span( lat );
|
||||||
|
for (lon = min.getLongitudeDeg(); lon <= max.getLongitudeDeg(); lon += span)
|
||||||
|
{
|
||||||
|
SGBucket b(SGGeod::fromDeg(lon, lat));
|
||||||
|
if (!b.isValid()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
list.push_back(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& operator<< ( std::ostream& out, const SGBucket& b )
|
||||||
|
{
|
||||||
|
return out << b.lon << ":" << (int)b.x << ", " << b.lat << ":" << (int)b.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,9 +39,11 @@
|
|||||||
#include <simgear/math/SGMath.hxx>
|
#include <simgear/math/SGMath.hxx>
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdio> // sprintf()
|
|
||||||
#include <ostream>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <iosfwd>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
// #define NO_DEPRECATED_API
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* standard size of a bucket in degrees (1/8 of a degree)
|
* standard size of a bucket in degrees (1/8 of a degree)
|
||||||
@@ -57,9 +59,7 @@
|
|||||||
// return the horizontal tile span factor based on latitude
|
// return the horizontal tile span factor based on latitude
|
||||||
static double sg_bucket_span( double l ) {
|
static double sg_bucket_span( double l ) {
|
||||||
if ( l >= 89.0 ) {
|
if ( l >= 89.0 ) {
|
||||||
return 360.0;
|
return 12.0;
|
||||||
} else if ( l >= 88.0 ) {
|
|
||||||
return 8.0;
|
|
||||||
} else if ( l >= 86.0 ) {
|
} else if ( l >= 86.0 ) {
|
||||||
return 4.0;
|
return 4.0;
|
||||||
} else if ( l >= 83.0 ) {
|
} else if ( l >= 83.0 ) {
|
||||||
@@ -80,12 +80,10 @@ static double sg_bucket_span( double l ) {
|
|||||||
return 1.0;
|
return 1.0;
|
||||||
} else if ( l >= -86.0 ) {
|
} else if ( l >= -86.0 ) {
|
||||||
return 2.0;
|
return 2.0;
|
||||||
} else if ( l >= -88.0 ) {
|
|
||||||
return 4.0;
|
|
||||||
} else if ( l >= -89.0 ) {
|
} else if ( l >= -89.0 ) {
|
||||||
return 8.0;
|
return 4.0;
|
||||||
} else {
|
} else {
|
||||||
return 360.0;
|
return 12.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,63 +100,60 @@ class SGBucket {
|
|||||||
private:
|
private:
|
||||||
short lon; // longitude index (-180 to 179)
|
short lon; // longitude index (-180 to 179)
|
||||||
short lat; // latitude index (-90 to 89)
|
short lat; // latitude index (-90 to 89)
|
||||||
char x; // x subdivision (0 to 7)
|
unsigned char x; // x subdivision (0 to 7)
|
||||||
char y; // y subdivision (0 to 7)
|
unsigned char y; // y subdivision (0 to 7)
|
||||||
|
|
||||||
|
void innerSet( double dlon, double dlat );
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor.
|
* Default constructor, creates an invalid SGBucket
|
||||||
*/
|
*/
|
||||||
SGBucket();
|
SGBucket();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if this bucket refers to a valid tile, or not.
|
||||||
|
*/
|
||||||
|
bool isValid() const;
|
||||||
|
|
||||||
|
#ifndef NO_DEPRECATED_API
|
||||||
/**
|
/**
|
||||||
* Construct a bucket given a specific location.
|
* Construct a bucket given a specific location.
|
||||||
* @param dlon longitude specified in degrees
|
* @param dlon longitude specified in degrees
|
||||||
* @param dlat latitude specified in degrees
|
* @param dlat latitude specified in degrees
|
||||||
*/
|
*/
|
||||||
SGBucket(const double dlon, const double dlat);
|
SGBucket(const double dlon, const double dlat);
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a bucket given a specific location.
|
* Construct a bucket given a specific location.
|
||||||
* @param dlon longitude specified in degrees
|
*
|
||||||
* @param dlat latitude specified in degrees
|
* @param geod Geodetic location
|
||||||
*/
|
*/
|
||||||
SGBucket(const SGGeod& geod);
|
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
|
|
||||||
* you want to * make sure last_bucket starts out as something
|
|
||||||
* impossible.
|
|
||||||
*/
|
|
||||||
SGBucket(const bool is_good);
|
|
||||||
|
|
||||||
/** Construct a bucket given a unique bucket index number.
|
/** Construct a bucket given a unique bucket index number.
|
||||||
|
*
|
||||||
* @param bindex unique bucket index
|
* @param bindex unique bucket index
|
||||||
*/
|
*/
|
||||||
SGBucket(const long int bindex);
|
SGBucket(const long int bindex);
|
||||||
|
|
||||||
|
#ifndef NO_DEPRECATED_API
|
||||||
|
/**
|
||||||
|
* Reset a bucket to represent a new location.
|
||||||
|
*
|
||||||
|
* @param geod New geodetic location
|
||||||
|
*/
|
||||||
|
void set_bucket(const SGGeod& geod);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset a bucket to represent a new lat and lon
|
* Reset a bucket to represent a new lat and lon
|
||||||
* @param dlon longitude specified in degrees
|
* @param dlon longitude specified in degrees
|
||||||
* @param dlat latitude specified in degrees
|
* @param dlat latitude specified in degrees
|
||||||
*/
|
*/
|
||||||
void set_bucket( double dlon, double dlat );
|
void set_bucket( double dlon, double dlat );
|
||||||
|
#endif
|
||||||
/**
|
|
||||||
* Reset a bucket to represent a new lat and lon
|
|
||||||
* @param lonlat an array of double[2] holding lon and lat
|
|
||||||
* (specified) in degrees
|
|
||||||
*/
|
|
||||||
void set_bucket( double *lonlat );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
* Create an impossible bucket.
|
||||||
@@ -166,10 +161,7 @@ public:
|
|||||||
* and you want to make sure last_bucket starts out as something
|
* and you want to make sure last_bucket starts out as something
|
||||||
* impossible.
|
* impossible.
|
||||||
*/
|
*/
|
||||||
inline void make_bad() {
|
void make_bad();
|
||||||
set_bucket(0.0, 0.0);
|
|
||||||
lon = -1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate the unique scenery tile index for this bucket
|
* Generate the unique scenery tile index for this bucket
|
||||||
@@ -195,13 +187,7 @@ public:
|
|||||||
* string form.
|
* string form.
|
||||||
* @return tile index in string form
|
* @return tile index in string form
|
||||||
*/
|
*/
|
||||||
inline std::string gen_index_str() const {
|
std::string gen_index_str() const;
|
||||||
char tmp[20];
|
|
||||||
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.
|
* Build the base path name for this bucket.
|
||||||
@@ -229,6 +215,13 @@ public:
|
|||||||
return lat + y / 8.0 + SG_HALF_BUCKET_SPAN;
|
return lat + y / 8.0 + SG_HALF_BUCKET_SPAN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the highest (furthest from the equator) latitude of this
|
||||||
|
* tile. This is the top edge for tiles north of the equator, and
|
||||||
|
* the bottom edge for tiles south
|
||||||
|
*/
|
||||||
|
double get_highest_lat() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the width of the tile in degrees.
|
* @return the width of the tile in degrees.
|
||||||
*/
|
*/
|
||||||
@@ -290,6 +283,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
inline int get_y() const { return y; }
|
inline int get_y() const { return y; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bucket offset from this by dx,dy
|
||||||
|
*/
|
||||||
|
SGBucket sibling(int dx, int dy) const;
|
||||||
|
|
||||||
// friends
|
// friends
|
||||||
|
|
||||||
friend std::ostream& operator<< ( std::ostream&, const SGBucket& );
|
friend std::ostream& operator<< ( std::ostream&, const SGBucket& );
|
||||||
@@ -301,7 +299,7 @@ inline bool operator!= (const SGBucket& lhs, const SGBucket& rhs)
|
|||||||
return !(lhs == rhs);
|
return !(lhs == rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NO_DEPRECATED_API
|
||||||
/**
|
/**
|
||||||
* \relates SGBucket
|
* \relates SGBucket
|
||||||
* Return the bucket which is offset from the specified dlon, dlat by
|
* Return the bucket which is offset from the specified dlon, dlat by
|
||||||
@@ -313,6 +311,7 @@ inline bool operator!= (const SGBucket& lhs, const SGBucket& rhs)
|
|||||||
* @return offset bucket
|
* @return offset bucket
|
||||||
*/
|
*/
|
||||||
SGBucket sgBucketOffset( double dlon, double dlat, int x, int y );
|
SGBucket sgBucketOffset( double dlon, double dlat, int x, int y );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -326,17 +325,21 @@ SGBucket sgBucketOffset( double dlon, double dlat, int x, int y );
|
|||||||
void sgBucketDiff( const SGBucket& b1, const SGBucket& b2, int *dx, int *dy );
|
void sgBucketDiff( const SGBucket& b1, const SGBucket& b2, int *dx, int *dy );
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \relates SGBucket
|
||||||
|
* retrieve a list of buckets in the given bounding box
|
||||||
|
* @param min min lon,lat of bounding box in degrees
|
||||||
|
* @param max max lon,lat of bounding box in degrees
|
||||||
|
* @param list standard vector of buckets within the bounding box
|
||||||
|
*/
|
||||||
|
void sgGetBuckets( const SGGeod& min, const SGGeod& max, std::vector<SGBucket>& list );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write the bucket lon, lat, x, and y to the output stream.
|
* Write the bucket lon, lat, x, and y to the output stream.
|
||||||
* @param out output stream
|
* @param out output stream
|
||||||
* @param b bucket
|
* @param b bucket
|
||||||
*/
|
*/
|
||||||
inline std::ostream&
|
std::ostream& operator<< ( std::ostream& out, const SGBucket& b );
|
||||||
operator<< ( std::ostream& out, const SGBucket& b )
|
|
||||||
{
|
|
||||||
return out << b.lon << ":" << (int)b.x << ", " << b.lat << ":" << (int)b.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare two bucket structures for equality.
|
* Compare two bucket structures for equality.
|
||||||
|
|||||||
@@ -0,0 +1,283 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
* test_bucket.cxx -- unit-tests for SGBucket class
|
||||||
|
*
|
||||||
|
* Copyright (C) 2014 James Turner - <zakalawe@mac.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.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include <simgear/compiler.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
using std::cout;
|
||||||
|
using std::cerr;
|
||||||
|
using std::endl;
|
||||||
|
|
||||||
|
#include <simgear/bucket/newbucket.hxx>
|
||||||
|
#include <simgear/misc/test_macros.hxx>
|
||||||
|
|
||||||
|
void testBucketSpans()
|
||||||
|
{
|
||||||
|
COMPARE(sg_bucket_span(0.0), 0.125);
|
||||||
|
COMPARE(sg_bucket_span(-20), 0.125);
|
||||||
|
COMPARE(sg_bucket_span(-40), 0.25);
|
||||||
|
COMPARE(sg_bucket_span(89.9), 12.0);
|
||||||
|
COMPARE(sg_bucket_span(88.1), 4.0);
|
||||||
|
COMPARE(sg_bucket_span(-89.9), 12.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testBasic()
|
||||||
|
{
|
||||||
|
SGBucket b1(5.1, 55.05);
|
||||||
|
COMPARE(b1.get_chunk_lon(), 5);
|
||||||
|
COMPARE(b1.get_chunk_lat(), 55);
|
||||||
|
COMPARE(b1.get_x(), 0);
|
||||||
|
COMPARE(b1.get_y(), 0);
|
||||||
|
COMPARE(b1.gen_index(), 3040320);
|
||||||
|
COMPARE(b1.gen_base_path(), "e000n50/e005n55");
|
||||||
|
VERIFY(b1.isValid());
|
||||||
|
|
||||||
|
SGBucket b2(-10.1, -43.8);
|
||||||
|
COMPARE(b2.get_chunk_lon(), -11);
|
||||||
|
COMPARE(b2.get_chunk_lat(), -44);
|
||||||
|
COMPARE(b2.get_x(), 3);
|
||||||
|
COMPARE(b2.get_y(), 1); // latitude chunks numbered bottom to top, it seems
|
||||||
|
COMPARE(b2.gen_base_path(), "w020s50/w011s44");
|
||||||
|
VERIFY(b2.isValid());
|
||||||
|
|
||||||
|
SGBucket b3(123.48, 9.01);
|
||||||
|
COMPARE(b3.get_chunk_lon(), 123);
|
||||||
|
COMPARE(b3.get_chunk_lat(), 9);
|
||||||
|
COMPARE(b3.get_x(), 3);
|
||||||
|
COMPARE(b3.get_y(), 0);
|
||||||
|
COMPARE(b3.gen_base_path(), "e120n00/e123n09");
|
||||||
|
VERIFY(b3.isValid());
|
||||||
|
|
||||||
|
SGBucket defBuck;
|
||||||
|
VERIFY(!defBuck.isValid());
|
||||||
|
|
||||||
|
b3.make_bad();
|
||||||
|
VERIFY(!b3.isValid());
|
||||||
|
|
||||||
|
SGBucket atAntiMeridian(180.0, 12.3);
|
||||||
|
VERIFY(atAntiMeridian.isValid());
|
||||||
|
COMPARE(atAntiMeridian.get_chunk_lon(), -180);
|
||||||
|
COMPARE(atAntiMeridian.get_x(), 0);
|
||||||
|
|
||||||
|
SGBucket atAntiMeridian2(-180.0, -78.1);
|
||||||
|
VERIFY(atAntiMeridian2.isValid());
|
||||||
|
COMPARE(atAntiMeridian2.get_chunk_lon(), -180);
|
||||||
|
COMPARE(atAntiMeridian2.get_x(), 0);
|
||||||
|
|
||||||
|
// check comparisom operator overload
|
||||||
|
SGBucket b4(5.11, 55.1);
|
||||||
|
VERIFY(b1 == b4); // should be equal
|
||||||
|
VERIFY(b1 == b1);
|
||||||
|
VERIFY(b1 != defBuck);
|
||||||
|
VERIFY(b1 != b2);
|
||||||
|
|
||||||
|
// check wrapping/clipping of inputs
|
||||||
|
SGBucket wrapMeridian(-200.0, 45.0);
|
||||||
|
COMPARE(wrapMeridian.get_chunk_lon(), 160);
|
||||||
|
|
||||||
|
SGBucket clipPole(48.9, 91);
|
||||||
|
COMPARE(clipPole.get_chunk_lat(), 89);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testPolar()
|
||||||
|
{
|
||||||
|
SGBucket b1(0.0, 89.92);
|
||||||
|
SGBucket b2(10.0, 89.96);
|
||||||
|
COMPARE(b1.get_chunk_lat(), 89);
|
||||||
|
COMPARE(b1.get_chunk_lon(), 0);
|
||||||
|
COMPARE(b1.get_x(), 0);
|
||||||
|
COMPARE(b1.get_y(), 7);
|
||||||
|
|
||||||
|
COMPARE_EP(b1.get_highest_lat(), 90.0);
|
||||||
|
COMPARE_EP(b1.get_width_m(), 10.0);
|
||||||
|
|
||||||
|
COMPARE(b2.get_chunk_lat(), 89);
|
||||||
|
COMPARE(b2.get_chunk_lon(), 0);
|
||||||
|
COMPARE(b2.get_x(), 0);
|
||||||
|
COMPARE(b2.get_y(), 7);
|
||||||
|
|
||||||
|
COMPARE(b1.gen_index(), b2.gen_index());
|
||||||
|
|
||||||
|
SGGeod actualNorthPole1 = b1.get_corner(2);
|
||||||
|
SGGeod actualNorthPole2 = b1.get_corner(3);
|
||||||
|
COMPARE_EP(actualNorthPole1.getLatitudeDeg(), 90.0);
|
||||||
|
COMPARE_EP(actualNorthPole1.getLongitudeDeg(), 12.0);
|
||||||
|
COMPARE_EP(actualNorthPole2.getLatitudeDeg(), 90.0);
|
||||||
|
COMPARE_EP(actualNorthPole2.getLongitudeDeg(), 0.0);
|
||||||
|
|
||||||
|
SGBucket b3(-2, 89.88);
|
||||||
|
SGBucket b4(-7, 89.88);
|
||||||
|
COMPARE(b3.gen_index(), b4.gen_index());
|
||||||
|
|
||||||
|
// south pole
|
||||||
|
SGBucket b5(-170, -89.88);
|
||||||
|
SGBucket b6(-179, -89.88);
|
||||||
|
|
||||||
|
COMPARE(b5.get_chunk_lat(), -90);
|
||||||
|
COMPARE(b5.get_chunk_lon(), -180);
|
||||||
|
COMPARE(b5.get_x(), 0);
|
||||||
|
COMPARE(b5.get_y(), 0);
|
||||||
|
COMPARE(b5.gen_index(), b6.gen_index());
|
||||||
|
COMPARE_EP(b5.get_highest_lat(), -90.0);
|
||||||
|
COMPARE_EP(b5.get_width_m(), 10.0);
|
||||||
|
|
||||||
|
SGGeod actualSouthPole1 = b5.get_corner(0);
|
||||||
|
SGGeod actualSouthPole2 = b5.get_corner(1);
|
||||||
|
COMPARE_EP(actualSouthPole1.getLatitudeDeg(), -90.0);
|
||||||
|
COMPARE_EP(actualSouthPole1.getLongitudeDeg(), -180);
|
||||||
|
COMPARE_EP(actualSouthPole2.getLatitudeDeg(), -90.0);
|
||||||
|
COMPARE_EP(actualSouthPole2.getLongitudeDeg(), -168);
|
||||||
|
|
||||||
|
SGBucket b7(200, 89.88);
|
||||||
|
COMPARE(b7.get_chunk_lon(), -168);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// test the tiles just below the pole (between 86 & 89 degrees N/S)
|
||||||
|
void testNearPolar()
|
||||||
|
{
|
||||||
|
SGBucket b1(1, 88.5);
|
||||||
|
SGBucket b2(-1, 88.8);
|
||||||
|
COMPARE(b1.get_chunk_lon(), 0);
|
||||||
|
COMPARE(b1.get_chunk_lat(), 88);
|
||||||
|
VERIFY(b1.gen_index() != b2.gen_index());
|
||||||
|
|
||||||
|
SGBucket b3(176.1, 88.5);
|
||||||
|
COMPARE(b3.get_chunk_lon(), 176);
|
||||||
|
|
||||||
|
SGBucket b4(-178, 88.5);
|
||||||
|
COMPARE(b4.get_chunk_lon(), -180);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testOffset()
|
||||||
|
{
|
||||||
|
// bucket just below the 22 degree cutoff, so the next tile north
|
||||||
|
// is twice the width
|
||||||
|
SGBucket b1(-59.8, 21.9);
|
||||||
|
COMPARE(b1.get_chunk_lat(), 21);
|
||||||
|
COMPARE(b1.get_chunk_lon(), -60);
|
||||||
|
COMPARE(b1.get_x(), 1);
|
||||||
|
COMPARE(b1.get_y(), 7);
|
||||||
|
|
||||||
|
// offset vertically
|
||||||
|
SGBucket b2(b1.sibling(0, 1));
|
||||||
|
COMPARE(b2.get_chunk_lat(), 22);
|
||||||
|
COMPARE(b2.get_chunk_lon(), -60);
|
||||||
|
COMPARE(b2.get_x(), 0);
|
||||||
|
COMPARE(b2.get_y(), 0);
|
||||||
|
|
||||||
|
COMPARE(b2.gen_index(), sgBucketOffset(-59.8, 21.9, 0, 1));
|
||||||
|
|
||||||
|
// offset vertically and horizontally. We compute horizontal (x)
|
||||||
|
// movement at the target latitude, so this should move 0.25 * -3 degrees,
|
||||||
|
// NOT 0.125 * -3 degrees.
|
||||||
|
SGBucket b3(b1.sibling(-3, 1));
|
||||||
|
COMPARE(b3.get_chunk_lat(), 22);
|
||||||
|
COMPARE(b3.get_chunk_lon(), -61);
|
||||||
|
COMPARE(b3.get_x(), 1);
|
||||||
|
COMPARE(b3.get_y(), 0);
|
||||||
|
|
||||||
|
COMPARE(b3.gen_index(), sgBucketOffset(-59.8, 21.9, -3, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void testPolarOffset()
|
||||||
|
{
|
||||||
|
SGBucket b1(-11.7, -89.6);
|
||||||
|
COMPARE(b1.get_chunk_lat(), -90);
|
||||||
|
COMPARE(b1.get_chunk_lon(), -12);
|
||||||
|
COMPARE(b1.get_x(), 0);
|
||||||
|
COMPARE(b1.get_y(), 3);
|
||||||
|
|
||||||
|
// offset horizontally
|
||||||
|
SGBucket b2(b1.sibling(-2, 0));
|
||||||
|
COMPARE(b2.get_chunk_lat(), -90);
|
||||||
|
COMPARE(b2.get_chunk_lon(), -36);
|
||||||
|
COMPARE(b2.get_x(), 0);
|
||||||
|
COMPARE(b2.get_y(), 3);
|
||||||
|
|
||||||
|
COMPARE(b2.gen_index(), sgBucketOffset(-11.7, -89.6, -2, 0));
|
||||||
|
|
||||||
|
// offset and wrap
|
||||||
|
SGBucket b3(-170, 89.1);
|
||||||
|
SGBucket b4(b3.sibling(-1, 0));
|
||||||
|
COMPARE(b4.get_chunk_lat(), 89);
|
||||||
|
COMPARE(b4.get_chunk_lon(), 168);
|
||||||
|
COMPARE(b4.get_x(), 0);
|
||||||
|
COMPARE(b4.get_y(), 0);
|
||||||
|
|
||||||
|
COMPARE(b4.gen_index(), sgBucketOffset(-170, 89.1, -1, 0));
|
||||||
|
|
||||||
|
|
||||||
|
SGBucket b5(177, 87.3);
|
||||||
|
SGBucket b6(b5.sibling(1, 1));
|
||||||
|
COMPARE(b6.get_chunk_lat(), 87);
|
||||||
|
COMPARE(b6.get_chunk_lon(), -180);
|
||||||
|
COMPARE(b6.get_x(), 0);
|
||||||
|
COMPARE(b6.get_y(), 3);
|
||||||
|
|
||||||
|
COMPARE(b6.gen_index(), sgBucketOffset(177, 87.3, 1, 1));
|
||||||
|
|
||||||
|
// offset vertically towards the pole
|
||||||
|
SGBucket b7(b1.sibling(0, -5));
|
||||||
|
VERIFY(!b7.isValid());
|
||||||
|
|
||||||
|
VERIFY(!SGBucket(0, 90).sibling(0, 1).isValid());
|
||||||
|
}
|
||||||
|
|
||||||
|
// test behaviour of bucket-offset near the anti-meridian (180-meridian)
|
||||||
|
void testOffsetWrap()
|
||||||
|
{
|
||||||
|
// near the equator
|
||||||
|
SGBucket b1(-179.8, 16.8);
|
||||||
|
COMPARE(b1.get_chunk_lat(), 16);
|
||||||
|
COMPARE(b1.get_chunk_lon(), -180);
|
||||||
|
COMPARE(b1.get_x(), 1);
|
||||||
|
COMPARE(b1.get_y(), 6);
|
||||||
|
|
||||||
|
SGBucket b2(b1.sibling(-2, 0));
|
||||||
|
COMPARE(b2.get_chunk_lat(), 16);
|
||||||
|
COMPARE(b2.get_chunk_lon(), 179);
|
||||||
|
COMPARE(b2.get_x(), 7);
|
||||||
|
COMPARE(b2.get_y(), 6);
|
||||||
|
COMPARE(b2.gen_index(), sgBucketOffset(-179.8, 16.8, -2, 0));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
testBucketSpans();
|
||||||
|
|
||||||
|
testBasic();
|
||||||
|
testPolar();
|
||||||
|
testNearPolar();
|
||||||
|
testOffset();
|
||||||
|
testOffsetWrap();
|
||||||
|
testPolarOffset();
|
||||||
|
|
||||||
|
cout << "all tests passed OK" << endl;
|
||||||
|
return 0; // passed
|
||||||
|
}
|
||||||
|
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
#include "BVHVisitor.hxx"
|
#include "BVHVisitor.hxx"
|
||||||
#include "BVHNode.hxx"
|
#include "BVHNode.hxx"
|
||||||
#include "BVHGroup.hxx"
|
#include "BVHGroup.hxx"
|
||||||
|
#include "BVHPageNode.hxx"
|
||||||
#include "BVHTransform.hxx"
|
#include "BVHTransform.hxx"
|
||||||
#include "BVHMotionTransform.hxx"
|
#include "BVHMotionTransform.hxx"
|
||||||
#include "BVHLineGeometry.hxx"
|
#include "BVHLineGeometry.hxx"
|
||||||
@@ -45,6 +46,8 @@ public:
|
|||||||
|
|
||||||
virtual void apply(BVHGroup& node)
|
virtual void apply(BVHGroup& node)
|
||||||
{ expandBy(node.getBoundingSphere()); }
|
{ expandBy(node.getBoundingSphere()); }
|
||||||
|
virtual void apply(BVHPageNode& node)
|
||||||
|
{ expandBy(node.getBoundingSphere()); }
|
||||||
virtual void apply(BVHTransform& node)
|
virtual void apply(BVHTransform& node)
|
||||||
{ expandBy(node.getBoundingSphere()); }
|
{ expandBy(node.getBoundingSphere()); }
|
||||||
virtual void apply(BVHMotionTransform& node)
|
virtual void apply(BVHMotionTransform& node)
|
||||||
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include "BVHNode.hxx"
|
#include "BVHNode.hxx"
|
||||||
#include "BVHGroup.hxx"
|
#include "BVHGroup.hxx"
|
||||||
|
#include "BVHPageNode.hxx"
|
||||||
#include "BVHTransform.hxx"
|
#include "BVHTransform.hxx"
|
||||||
#include "BVHMotionTransform.hxx"
|
#include "BVHMotionTransform.hxx"
|
||||||
#include "BVHLineGeometry.hxx"
|
#include "BVHLineGeometry.hxx"
|
||||||
@@ -48,6 +49,14 @@ BVHLineSegmentVisitor::apply(BVHGroup& group)
|
|||||||
group.traverse(*this);
|
group.traverse(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BVHLineSegmentVisitor::apply(BVHPageNode& pageNode)
|
||||||
|
{
|
||||||
|
if (!intersects(_lineSegment, pageNode.getBoundingSphere()))
|
||||||
|
return;
|
||||||
|
pageNode.traverse(*this);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BVHLineSegmentVisitor::apply(BVHTransform& transform)
|
BVHLineSegmentVisitor::apply(BVHTransform& transform)
|
||||||
{
|
{
|
||||||
@@ -20,13 +20,14 @@
|
|||||||
|
|
||||||
#include <simgear/math/SGGeometry.hxx>
|
#include <simgear/math/SGGeometry.hxx>
|
||||||
#include <simgear/structure/SGSharedPtr.hxx>
|
#include <simgear/structure/SGSharedPtr.hxx>
|
||||||
#include <simgear/scene/material/mat.hxx>
|
|
||||||
|
|
||||||
#include "BVHVisitor.hxx"
|
#include "BVHVisitor.hxx"
|
||||||
#include "BVHNode.hxx"
|
#include "BVHNode.hxx"
|
||||||
|
|
||||||
namespace simgear {
|
namespace simgear {
|
||||||
|
|
||||||
|
class BVHMaterial;
|
||||||
|
|
||||||
class BVHLineSegmentVisitor : public BVHVisitor {
|
class BVHLineSegmentVisitor : public BVHVisitor {
|
||||||
public:
|
public:
|
||||||
BVHLineSegmentVisitor(const SGLineSegmentd& lineSegment,
|
BVHLineSegmentVisitor(const SGLineSegmentd& lineSegment,
|
||||||
@@ -54,12 +55,13 @@ public:
|
|||||||
{ return _linearVelocity; }
|
{ return _linearVelocity; }
|
||||||
const SGVec3d& getAngularVelocity() const
|
const SGVec3d& getAngularVelocity() const
|
||||||
{ return _angularVelocity; }
|
{ return _angularVelocity; }
|
||||||
const SGMaterial* getMaterial() const
|
const BVHMaterial* getMaterial() const
|
||||||
{ return _material; }
|
{ return _material; }
|
||||||
BVHNode::Id getId() const
|
BVHNode::Id getId() const
|
||||||
{ return _id; }
|
{ return _id; }
|
||||||
|
|
||||||
virtual void apply(BVHGroup& group);
|
virtual void apply(BVHGroup& group);
|
||||||
|
virtual void apply(BVHPageNode& node);
|
||||||
virtual void apply(BVHTransform& transform);
|
virtual void apply(BVHTransform& transform);
|
||||||
virtual void apply(BVHMotionTransform& transform);
|
virtual void apply(BVHMotionTransform& transform);
|
||||||
virtual void apply(BVHLineGeometry&);
|
virtual void apply(BVHLineGeometry&);
|
||||||
@@ -87,7 +89,7 @@ private:
|
|||||||
SGVec3d _normal;
|
SGVec3d _normal;
|
||||||
SGVec3d _linearVelocity;
|
SGVec3d _linearVelocity;
|
||||||
SGVec3d _angularVelocity;
|
SGVec3d _angularVelocity;
|
||||||
const SGMaterial* _material;
|
const BVHMaterial* _material;
|
||||||
BVHNode::Id _id;
|
BVHNode::Id _id;
|
||||||
|
|
||||||
bool _haveHit;
|
bool _haveHit;
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
// Copyright (C) 2008 - 2012 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.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "BVHMaterial.hxx"
|
||||||
|
|
||||||
|
namespace simgear {
|
||||||
|
|
||||||
|
BVHMaterial::BVHMaterial() :
|
||||||
|
_solid(true),
|
||||||
|
_friction_factor(1),
|
||||||
|
_rolling_friction(0.02),
|
||||||
|
_bumpiness(0),
|
||||||
|
_load_resistance(1e30)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
BVHMaterial::~BVHMaterial()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
// Copyright (C) 2008 - 2012 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 BVHMaterial_hxx
|
||||||
|
#define BVHMaterial_hxx
|
||||||
|
|
||||||
|
#include <simgear/structure/SGReferenced.hxx>
|
||||||
|
|
||||||
|
namespace simgear {
|
||||||
|
|
||||||
|
class BVHMaterial : public SGReferenced {
|
||||||
|
public:
|
||||||
|
BVHMaterial();
|
||||||
|
virtual ~BVHMaterial();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return if the surface material is solid, if it is not solid, a fluid
|
||||||
|
* can be assumed, that is usually water.
|
||||||
|
*/
|
||||||
|
bool get_solid () const { return _solid; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the friction factor for that material
|
||||||
|
*/
|
||||||
|
double get_friction_factor () const { return _friction_factor; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the rolling friction for that material
|
||||||
|
*/
|
||||||
|
double get_rolling_friction () const { return _rolling_friction; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the bumpines for that material
|
||||||
|
*/
|
||||||
|
double get_bumpiness () const { return _bumpiness; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the load resistance
|
||||||
|
*/
|
||||||
|
double get_load_resistance () const { return _load_resistance; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// True if the material is solid, false if it is a fluid
|
||||||
|
bool _solid;
|
||||||
|
|
||||||
|
// the friction factor of that surface material
|
||||||
|
double _friction_factor;
|
||||||
|
|
||||||
|
// the rolling friction of that surface material
|
||||||
|
double _rolling_friction;
|
||||||
|
|
||||||
|
// the bumpiness of that surface material
|
||||||
|
double _bumpiness;
|
||||||
|
|
||||||
|
// the load resistance of that surface material
|
||||||
|
double _load_resistance;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
+9
-2
@@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include "BVHNode.hxx"
|
#include "BVHNode.hxx"
|
||||||
#include "BVHGroup.hxx"
|
#include "BVHGroup.hxx"
|
||||||
|
#include "BVHPageNode.hxx"
|
||||||
#include "BVHTransform.hxx"
|
#include "BVHTransform.hxx"
|
||||||
#include "BVHLineGeometry.hxx"
|
#include "BVHLineGeometry.hxx"
|
||||||
#include "BVHStaticGeometry.hxx"
|
#include "BVHStaticGeometry.hxx"
|
||||||
@@ -52,6 +53,12 @@ public:
|
|||||||
return;
|
return;
|
||||||
leaf.traverse(*this);
|
leaf.traverse(*this);
|
||||||
}
|
}
|
||||||
|
virtual void apply(BVHPageNode& leaf)
|
||||||
|
{
|
||||||
|
if (!intersects(_sphere, leaf.getBoundingSphere()))
|
||||||
|
return;
|
||||||
|
leaf.traverse(*this);
|
||||||
|
}
|
||||||
virtual void apply(BVHTransform& transform)
|
virtual void apply(BVHTransform& transform)
|
||||||
{
|
{
|
||||||
if (!intersects(_sphere, transform.getBoundingSphere()))
|
if (!intersects(_sphere, transform.getBoundingSphere()))
|
||||||
@@ -140,7 +147,7 @@ public:
|
|||||||
{ return _linearVelocity; }
|
{ return _linearVelocity; }
|
||||||
const SGVec3d& getAngularVelocity() const
|
const SGVec3d& getAngularVelocity() const
|
||||||
{ return _angularVelocity; }
|
{ return _angularVelocity; }
|
||||||
const SGMaterial* getMaterial() const
|
const BVHMaterial* getMaterial() const
|
||||||
{ return _material; }
|
{ return _material; }
|
||||||
BVHNode::Id getId() const
|
BVHNode::Id getId() const
|
||||||
{ return _id; }
|
{ return _id; }
|
||||||
@@ -155,7 +162,7 @@ private:
|
|||||||
SGVec3d _point;
|
SGVec3d _point;
|
||||||
SGVec3d _linearVelocity;
|
SGVec3d _linearVelocity;
|
||||||
SGVec3d _angularVelocity;
|
SGVec3d _angularVelocity;
|
||||||
const SGMaterial* _material;
|
const BVHMaterial* _material;
|
||||||
BVHNode::Id _id;
|
BVHNode::Id _id;
|
||||||
|
|
||||||
bool _havePoint;
|
bool _havePoint;
|
||||||
@@ -26,6 +26,7 @@ namespace simgear {
|
|||||||
|
|
||||||
class BVHGroup;
|
class BVHGroup;
|
||||||
class BVHVisitor;
|
class BVHVisitor;
|
||||||
|
class BVHPageNode;
|
||||||
|
|
||||||
// Base for the tree nodes
|
// Base for the tree nodes
|
||||||
class BVHNode : public SGReferenced {
|
class BVHNode : public SGReferenced {
|
||||||
@@ -55,6 +56,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class BVHGroup;
|
friend class BVHGroup;
|
||||||
|
friend class BVHPageNode;
|
||||||
void addParent(BVHNode* parent);
|
void addParent(BVHNode* parent);
|
||||||
void removeParent(BVHNode* parent);
|
void removeParent(BVHNode* parent);
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
|
// Copyright (C) 2008 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||||
//
|
//
|
||||||
// This library is free software; you can redistribute it and/or
|
// This library is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU Library General Public
|
// modify it under the terms of the GNU Library General Public
|
||||||
@@ -15,17 +15,26 @@
|
|||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef HLAVariantDataElement_hxx
|
#include "BVHPageNode.hxx"
|
||||||
#define HLAVariantDataElement_hxx
|
|
||||||
|
|
||||||
#include "HLAVariantDataType.hxx"
|
#include "BVHPager.hxx"
|
||||||
#include "HLAVariantRecordDataElement.hxx"
|
|
||||||
|
|
||||||
namespace simgear {
|
namespace simgear {
|
||||||
|
|
||||||
typedef HLAAbstractVariantRecordDataElement HLAAbstractVariantDataElement;
|
BVHPageNode::BVHPageNode() :
|
||||||
typedef HLAVariantRecordDataElement HLAVariantDataElement;
|
_useStamp(0),
|
||||||
|
_requested(false)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
BVHPageNode::~BVHPageNode()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BVHPageNode::accept(BVHVisitor& visitor)
|
||||||
|
{
|
||||||
|
visitor.apply(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
// Copyright (C) 2008 - 2012 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 BVHPageNode_hxx
|
||||||
|
#define BVHPageNode_hxx
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
#include <simgear/structure/SGSharedPtr.hxx>
|
||||||
|
|
||||||
|
#include "BVHGroup.hxx"
|
||||||
|
#include "BVHVisitor.hxx"
|
||||||
|
|
||||||
|
namespace simgear {
|
||||||
|
|
||||||
|
class BVHPager;
|
||||||
|
class BVHPageRequest;
|
||||||
|
|
||||||
|
class BVHPageNode : public BVHGroup {
|
||||||
|
public:
|
||||||
|
BVHPageNode();
|
||||||
|
virtual ~BVHPageNode();
|
||||||
|
|
||||||
|
virtual void accept(BVHVisitor& visitor);
|
||||||
|
|
||||||
|
/// Return the usage stamp of the last access
|
||||||
|
unsigned getUseStamp() const
|
||||||
|
{ return _useStamp; }
|
||||||
|
|
||||||
|
virtual SGSphered computeBoundingSphere() const = 0;
|
||||||
|
|
||||||
|
virtual BVHPageRequest* newRequest() = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void invalidateBound() = 0;
|
||||||
|
|
||||||
|
bool getRequested() const
|
||||||
|
{ return _requested; }
|
||||||
|
void setRequested(bool requested)
|
||||||
|
{ _requested = requested; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class BVHPager;
|
||||||
|
|
||||||
|
std::list<SGSharedPtr<BVHPageNode> >::iterator _iterator;
|
||||||
|
unsigned _useStamp;
|
||||||
|
bool _requested;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
|
// Copyright (C) 2008 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||||
//
|
//
|
||||||
// This library is free software; you can redistribute it and/or
|
// This library is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU Library General Public
|
// modify it under the terms of the GNU Library General Public
|
||||||
@@ -15,15 +15,12 @@
|
|||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef HLAVariantDataType_hxx
|
#include "BVHPageRequest.hxx"
|
||||||
#define HLAVariantDataType_hxx
|
|
||||||
|
|
||||||
#include "HLAVariantRecordDataType.hxx"
|
|
||||||
|
|
||||||
namespace simgear {
|
namespace simgear {
|
||||||
|
|
||||||
typedef HLAVariantRecordDataType HLAVariantDataType;
|
BVHPageRequest::~BVHPageRequest()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace simgear
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
// Copyright (C) 2008 - 2012 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 BVHPageRequest_hxx
|
||||||
|
#define BVHPageRequest_hxx
|
||||||
|
|
||||||
|
#include <simgear/structure/SGReferenced.hxx>
|
||||||
|
|
||||||
|
namespace simgear {
|
||||||
|
|
||||||
|
class BVHPageNode;
|
||||||
|
|
||||||
|
class BVHPageRequest : public SGReferenced {
|
||||||
|
public:
|
||||||
|
virtual ~BVHPageRequest();
|
||||||
|
|
||||||
|
/// Happens in the pager thread, do not modify the calling bvh tree
|
||||||
|
virtual void load() = 0;
|
||||||
|
/// Happens in the bvh main thread where the bvh is actually used.
|
||||||
|
/// So inside here it is safe to modify the paged node
|
||||||
|
virtual void insert() = 0;
|
||||||
|
/// The page node this request is for
|
||||||
|
virtual BVHPageNode* getPageNode() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,236 @@
|
|||||||
|
// Copyright (C) 2008 - 2012 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.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "BVHPager.hxx"
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
#include <simgear/threads/SGThread.hxx>
|
||||||
|
#include <simgear/threads/SGGuard.hxx>
|
||||||
|
|
||||||
|
#include "BVHPageNode.hxx"
|
||||||
|
#include "BVHPageRequest.hxx"
|
||||||
|
|
||||||
|
namespace simgear {
|
||||||
|
|
||||||
|
struct BVHPager::_PrivateData : protected SGThread {
|
||||||
|
typedef SGSharedPtr<BVHPageRequest> _Request;
|
||||||
|
typedef std::list<_Request> _RequestList;
|
||||||
|
typedef std::list<SGSharedPtr<BVHPageNode> > _PageNodeList;
|
||||||
|
|
||||||
|
struct _LockedQueue {
|
||||||
|
void _push(const _Request& request)
|
||||||
|
{
|
||||||
|
SGGuard<SGMutex> scopeLock(_mutex);
|
||||||
|
_requestList.push_back(request);
|
||||||
|
}
|
||||||
|
_Request _pop()
|
||||||
|
{
|
||||||
|
SGGuard<SGMutex> scopeLock(_mutex);
|
||||||
|
if (_requestList.empty())
|
||||||
|
return _Request();
|
||||||
|
_Request request;
|
||||||
|
request.swap(_requestList.front());
|
||||||
|
_requestList.pop_front();
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
SGMutex _mutex;
|
||||||
|
_RequestList _requestList;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _WorkQueue {
|
||||||
|
void _stop()
|
||||||
|
{
|
||||||
|
_push(_Request());
|
||||||
|
}
|
||||||
|
void _push(const _Request& request)
|
||||||
|
{
|
||||||
|
SGGuard<SGMutex> scopeLock(_mutex);
|
||||||
|
bool needSignal = _requestList.empty();
|
||||||
|
_requestList.push_back(request);
|
||||||
|
if (needSignal)
|
||||||
|
_waitCondition.signal();
|
||||||
|
}
|
||||||
|
_Request _pop()
|
||||||
|
{
|
||||||
|
SGGuard<SGMutex> scopeLock(_mutex);
|
||||||
|
while (_requestList.empty())
|
||||||
|
_waitCondition.wait(_mutex);
|
||||||
|
_Request request;
|
||||||
|
request.swap(_requestList.front());
|
||||||
|
_requestList.pop_front();
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
SGMutex _mutex;
|
||||||
|
SGWaitCondition _waitCondition;
|
||||||
|
_RequestList _requestList;
|
||||||
|
};
|
||||||
|
|
||||||
|
_PrivateData() :
|
||||||
|
_started(false),
|
||||||
|
_useStamp(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
virtual ~_PrivateData()
|
||||||
|
{
|
||||||
|
_stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void run()
|
||||||
|
{
|
||||||
|
for (;;) {
|
||||||
|
_Request request = _pendingRequests._pop();
|
||||||
|
// This means stop working
|
||||||
|
if (!request.valid())
|
||||||
|
return;
|
||||||
|
request->load();
|
||||||
|
_processedRequests._push(request);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _start()
|
||||||
|
{
|
||||||
|
if (_started)
|
||||||
|
return true;
|
||||||
|
if (!start())
|
||||||
|
return false;
|
||||||
|
_started = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _stop()
|
||||||
|
{
|
||||||
|
if (!_started)
|
||||||
|
return;
|
||||||
|
// send a stop request ...
|
||||||
|
_pendingRequests._stop();
|
||||||
|
// ... and wait for the thread to finish
|
||||||
|
join();
|
||||||
|
_started = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _use(BVHPageNode& pageNode)
|
||||||
|
{
|
||||||
|
if (pageNode._requested) {
|
||||||
|
// move it forward in the lru list
|
||||||
|
_pageNodeList.splice(_pageNodeList.end(), _pageNodeList,
|
||||||
|
pageNode._iterator);
|
||||||
|
} else {
|
||||||
|
_Request request = pageNode.newRequest();
|
||||||
|
if (!request.valid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
pageNode._iterator = _pageNodeList.insert(_pageNodeList.end(),
|
||||||
|
&pageNode);
|
||||||
|
pageNode._requested = true;
|
||||||
|
|
||||||
|
if (_started) {
|
||||||
|
_pendingRequests._push(request);
|
||||||
|
} else {
|
||||||
|
request->load();
|
||||||
|
request->insert();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pageNode._useStamp = _useStamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _update(unsigned expiry)
|
||||||
|
{
|
||||||
|
// Insert all processed requests
|
||||||
|
for (;;) {
|
||||||
|
SGSharedPtr<BVHPageRequest> request;
|
||||||
|
request = _processedRequests._pop();
|
||||||
|
if (!request.valid())
|
||||||
|
break;
|
||||||
|
request->insert();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ... and throw away stuff that is not used for a long time
|
||||||
|
unsigned useStamp = _useStamp - expiry;
|
||||||
|
_PageNodeList::iterator i = _pageNodeList.begin();
|
||||||
|
while (i != _pageNodeList.end()) {
|
||||||
|
// Ok, this means if the highest bit in the below difference
|
||||||
|
// is set which is aequivalent to having a negative difference
|
||||||
|
// but being wraparound save.
|
||||||
|
unsigned diff = (*i)->_useStamp - useStamp;
|
||||||
|
// test the sign bit of the difference
|
||||||
|
if (!(diff & (~((~0u) >> 1))))
|
||||||
|
break;
|
||||||
|
(*i)->clear();
|
||||||
|
(*i)->_requested = false;
|
||||||
|
i = _pageNodeList.erase(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _started;
|
||||||
|
unsigned _useStamp;
|
||||||
|
_WorkQueue _pendingRequests;
|
||||||
|
_LockedQueue _processedRequests;
|
||||||
|
// Store the rcu list of loaded nodes so that they can expire
|
||||||
|
_PageNodeList _pageNodeList;
|
||||||
|
};
|
||||||
|
|
||||||
|
BVHPager::BVHPager() :
|
||||||
|
_privateData(new _PrivateData)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
BVHPager::~BVHPager()
|
||||||
|
{
|
||||||
|
delete _privateData;
|
||||||
|
_privateData = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
BVHPager::start()
|
||||||
|
{
|
||||||
|
return _privateData->_start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BVHPager::stop()
|
||||||
|
{
|
||||||
|
_privateData->_stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BVHPager::use(BVHPageNode& pageNode)
|
||||||
|
{
|
||||||
|
_privateData->_use(pageNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BVHPager::update(unsigned expiry)
|
||||||
|
{
|
||||||
|
_privateData->_update(expiry);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BVHPager::setUseStamp(unsigned stamp)
|
||||||
|
{
|
||||||
|
_privateData->_useStamp = stamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
BVHPager::getUseStamp() const
|
||||||
|
{
|
||||||
|
return _privateData->_useStamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
// Copyright (C) 2008 - 2012 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 BVHPager_hxx
|
||||||
|
#define BVHPager_hxx
|
||||||
|
|
||||||
|
#include <simgear/structure/SGSharedPtr.hxx>
|
||||||
|
|
||||||
|
namespace simgear {
|
||||||
|
|
||||||
|
class BVHPageNode;
|
||||||
|
class BVHPageRequest;
|
||||||
|
|
||||||
|
class BVHPager {
|
||||||
|
public:
|
||||||
|
BVHPager();
|
||||||
|
~BVHPager();
|
||||||
|
|
||||||
|
/// Starts the pager thread
|
||||||
|
bool start();
|
||||||
|
|
||||||
|
/// Stops the pager thread
|
||||||
|
void stop();
|
||||||
|
|
||||||
|
/// Use this page node, if loaded make it as used, if not loaded schedule
|
||||||
|
void use(BVHPageNode& pageNode);
|
||||||
|
|
||||||
|
/// Call this from the main thread to incorporate the processed page
|
||||||
|
/// requests into the bounding volume tree
|
||||||
|
void update(unsigned expiry);
|
||||||
|
|
||||||
|
/// The usage stamp to mark usage of BVHPageNodes
|
||||||
|
void setUseStamp(unsigned stamp);
|
||||||
|
unsigned getUseStamp() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
BVHPager(const BVHPager&);
|
||||||
|
BVHPager& operator=(const BVHPager&);
|
||||||
|
|
||||||
|
struct _PrivateData;
|
||||||
|
_PrivateData* _privateData;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -22,11 +22,7 @@
|
|||||||
#include <simgear/structure/SGReferenced.hxx>
|
#include <simgear/structure/SGReferenced.hxx>
|
||||||
#include <simgear/structure/SGSharedPtr.hxx>
|
#include <simgear/structure/SGSharedPtr.hxx>
|
||||||
#include <simgear/math/SGGeometry.hxx>
|
#include <simgear/math/SGGeometry.hxx>
|
||||||
|
#include "BVHMaterial.hxx"
|
||||||
/// FIXME, the SGMaterial class is too much tied to the scenegraph aspects of
|
|
||||||
/// the materials. Use some class more decribing the
|
|
||||||
/// nature of the surface we live on ...
|
|
||||||
class SGMaterial;
|
|
||||||
|
|
||||||
namespace simgear {
|
namespace simgear {
|
||||||
|
|
||||||
@@ -40,20 +36,20 @@ public:
|
|||||||
{ return _vertices[i]; }
|
{ return _vertices[i]; }
|
||||||
|
|
||||||
|
|
||||||
unsigned addMaterial(const SGMaterial* material)
|
unsigned addMaterial(const BVHMaterial* material)
|
||||||
{ _materials.push_back(material); return _materials.size() - 1; }
|
{ _materials.push_back(material); return _materials.size() - 1; }
|
||||||
const SGMaterial* getMaterial(unsigned i) const
|
const BVHMaterial* getMaterial(unsigned i) const
|
||||||
{ if (_materials.size() <= i) return 0; return _materials[i]; }
|
{ if (_materials.size() <= i) return 0; return _materials[i]; }
|
||||||
|
|
||||||
void trim()
|
void trim()
|
||||||
{
|
{
|
||||||
std::vector<SGVec3f>(_vertices).swap(_vertices);
|
std::vector<SGVec3f>(_vertices).swap(_vertices);
|
||||||
std::vector<const SGMaterial*>(_materials).swap(_materials);
|
std::vector<SGSharedPtr<const BVHMaterial> >(_materials).swap(_materials);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<SGVec3f> _vertices;
|
std::vector<SGVec3f> _vertices;
|
||||||
std::vector<const SGMaterial*> _materials;
|
std::vector<SGSharedPtr<const BVHMaterial> > _materials;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
+5
-5
@@ -78,16 +78,16 @@ public:
|
|||||||
typedef std::set<SGVec3<unsigned> > TriangleSet;
|
typedef std::set<SGVec3<unsigned> > TriangleSet;
|
||||||
TriangleSet _triangleSet;
|
TriangleSet _triangleSet;
|
||||||
|
|
||||||
void setCurrentMaterial(const SGMaterial* material)
|
void setCurrentMaterial(const BVHMaterial* material)
|
||||||
{
|
{
|
||||||
_currentMaterial = material;
|
_currentMaterial = material;
|
||||||
_currentMaterialIndex = addMaterial(material);
|
_currentMaterialIndex = addMaterial(material);
|
||||||
}
|
}
|
||||||
const SGMaterial* getCurrentMaterial() const
|
const BVHMaterial* getCurrentMaterial() const
|
||||||
{
|
{
|
||||||
return _currentMaterial;
|
return _currentMaterial;
|
||||||
}
|
}
|
||||||
unsigned addMaterial(const SGMaterial* material)
|
unsigned addMaterial(const BVHMaterial* material)
|
||||||
{
|
{
|
||||||
MaterialMap::const_iterator i = _materialMap.find(material);
|
MaterialMap::const_iterator i = _materialMap.find(material);
|
||||||
if (i != _materialMap.end())
|
if (i != _materialMap.end())
|
||||||
@@ -97,9 +97,9 @@ public:
|
|||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef std::map<const SGMaterial*, unsigned> MaterialMap;
|
typedef std::map<const BVHMaterial*, unsigned> MaterialMap;
|
||||||
MaterialMap _materialMap;
|
MaterialMap _materialMap;
|
||||||
const SGMaterial* _currentMaterial;
|
const BVHMaterial* _currentMaterial;
|
||||||
unsigned _currentMaterialIndex;
|
unsigned _currentMaterialIndex;
|
||||||
|
|
||||||
void addTriangle(const SGVec3f& v1, const SGVec3f& v2, const SGVec3f& v3)
|
void addTriangle(const SGVec3f& v1, const SGVec3f& v2, const SGVec3f& v3)
|
||||||
@@ -59,6 +59,22 @@ BVHSubTreeCollector::apply(BVHGroup& group)
|
|||||||
popNodeList(parentNodeList);
|
popNodeList(parentNodeList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BVHSubTreeCollector::apply(BVHPageNode& group)
|
||||||
|
{
|
||||||
|
if (!intersects(_sphere, group.getBoundingSphere()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// The _nodeList content is somehow the 'return value' of the subtree.
|
||||||
|
// Set it to zero to see if we have something to collect down there.
|
||||||
|
NodeList parentNodeList;
|
||||||
|
pushNodeList(parentNodeList);
|
||||||
|
|
||||||
|
group.traverse(*this);
|
||||||
|
|
||||||
|
popNodeList(parentNodeList);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BVHSubTreeCollector::apply(BVHTransform& transform)
|
BVHSubTreeCollector::apply(BVHTransform& transform)
|
||||||
{
|
{
|
||||||
@@ -43,6 +43,7 @@ public:
|
|||||||
virtual ~BVHSubTreeCollector();
|
virtual ~BVHSubTreeCollector();
|
||||||
|
|
||||||
virtual void apply(BVHGroup&);
|
virtual void apply(BVHGroup&);
|
||||||
|
virtual void apply(BVHPageNode&);
|
||||||
virtual void apply(BVHTransform&);
|
virtual void apply(BVHTransform&);
|
||||||
virtual void apply(BVHMotionTransform&);
|
virtual void apply(BVHMotionTransform&);
|
||||||
virtual void apply(BVHLineGeometry&);
|
virtual void apply(BVHLineGeometry&);
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright (C) 2008 - 2009 Mathias Froehlich - Mathias.Froehlich@web.de
|
// Copyright (C) 2008 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
|
||||||
//
|
//
|
||||||
// This library is free software; you can redistribute it and/or
|
// This library is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU Library General Public
|
// modify it under the terms of the GNU Library General Public
|
||||||
@@ -23,6 +23,7 @@ namespace simgear {
|
|||||||
class BVHStaticData;
|
class BVHStaticData;
|
||||||
|
|
||||||
class BVHGroup;
|
class BVHGroup;
|
||||||
|
class BVHPageNode;
|
||||||
class BVHTransform;
|
class BVHTransform;
|
||||||
class BVHMotionTransform;
|
class BVHMotionTransform;
|
||||||
class BVHStaticGeometry;
|
class BVHStaticGeometry;
|
||||||
@@ -41,6 +42,7 @@ public:
|
|||||||
|
|
||||||
// High level nodes to handle
|
// High level nodes to handle
|
||||||
virtual void apply(BVHGroup&) = 0;
|
virtual void apply(BVHGroup&) = 0;
|
||||||
|
virtual void apply(BVHPageNode&) = 0;
|
||||||
virtual void apply(BVHTransform&) = 0;
|
virtual void apply(BVHTransform&) = 0;
|
||||||
virtual void apply(BVHMotionTransform&) = 0;
|
virtual void apply(BVHMotionTransform&) = 0;
|
||||||
virtual void apply(BVHLineGeometry&) = 0;
|
virtual void apply(BVHLineGeometry&) = 0;
|
||||||
@@ -2,13 +2,15 @@ include (SimGearComponent)
|
|||||||
|
|
||||||
set(HEADERS
|
set(HEADERS
|
||||||
BVHBoundingBoxVisitor.hxx
|
BVHBoundingBoxVisitor.hxx
|
||||||
BVHDebugCollectVisitor.hxx
|
|
||||||
BVHGroup.hxx
|
BVHGroup.hxx
|
||||||
BVHLineGeometry.hxx
|
BVHLineGeometry.hxx
|
||||||
BVHLineSegmentVisitor.hxx
|
BVHLineSegmentVisitor.hxx
|
||||||
BVHMotionTransform.hxx
|
BVHMotionTransform.hxx
|
||||||
BVHNearestPointVisitor.hxx
|
BVHNearestPointVisitor.hxx
|
||||||
BVHNode.hxx
|
BVHNode.hxx
|
||||||
|
BVHPageNode.hxx
|
||||||
|
BVHPageRequest.hxx
|
||||||
|
BVHPager.hxx
|
||||||
BVHStaticBinary.hxx
|
BVHStaticBinary.hxx
|
||||||
BVHStaticData.hxx
|
BVHStaticData.hxx
|
||||||
BVHStaticGeometry.hxx
|
BVHStaticGeometry.hxx
|
||||||
@@ -17,9 +19,10 @@ set(HEADERS
|
|||||||
BVHStaticNode.hxx
|
BVHStaticNode.hxx
|
||||||
BVHStaticTriangle.hxx
|
BVHStaticTriangle.hxx
|
||||||
BVHSubTreeCollector.hxx
|
BVHSubTreeCollector.hxx
|
||||||
|
BVHMaterial.hxx
|
||||||
BVHTransform.hxx
|
BVHTransform.hxx
|
||||||
BVHVisitor.hxx
|
BVHVisitor.hxx
|
||||||
)
|
)
|
||||||
|
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
BVHGroup.cxx
|
BVHGroup.cxx
|
||||||
@@ -27,13 +30,23 @@ set(SOURCES
|
|||||||
BVHLineSegmentVisitor.cxx
|
BVHLineSegmentVisitor.cxx
|
||||||
BVHMotionTransform.cxx
|
BVHMotionTransform.cxx
|
||||||
BVHNode.cxx
|
BVHNode.cxx
|
||||||
|
BVHPageNode.cxx
|
||||||
|
BVHPageRequest.cxx
|
||||||
|
BVHPager.cxx
|
||||||
BVHStaticBinary.cxx
|
BVHStaticBinary.cxx
|
||||||
BVHStaticGeometry.cxx
|
BVHStaticGeometry.cxx
|
||||||
BVHStaticLeaf.cxx
|
BVHStaticLeaf.cxx
|
||||||
BVHStaticNode.cxx
|
BVHStaticNode.cxx
|
||||||
BVHStaticTriangle.cxx
|
BVHStaticTriangle.cxx
|
||||||
BVHSubTreeCollector.cxx
|
BVHSubTreeCollector.cxx
|
||||||
|
BVHMaterial.cxx
|
||||||
BVHTransform.cxx
|
BVHTransform.cxx
|
||||||
)
|
)
|
||||||
|
|
||||||
simgear_scene_component(bvh scene/bvh "${SOURCES}" "${HEADERS}")
|
simgear_component(bvh bvh "${SOURCES}" "${HEADERS}")
|
||||||
|
|
||||||
|
if(ENABLE_TESTS)
|
||||||
|
add_executable(bvhtest bvhtest.cxx)
|
||||||
|
target_link_libraries(bvhtest SimGearCore)
|
||||||
|
add_test(bvhtest ${EXECUTABLE_OUTPUT_PATH}/bvhtest)
|
||||||
|
endif(ENABLE_TESTS)
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
include (SimGearComponent)
|
||||||
|
|
||||||
|
set(HEADERS
|
||||||
|
canvas_fwd.hxx
|
||||||
|
Canvas.hxx
|
||||||
|
CanvasEvent.hxx
|
||||||
|
CanvasEventManager.hxx
|
||||||
|
CanvasEventTypes.hxx
|
||||||
|
CanvasEventVisitor.hxx
|
||||||
|
CanvasMgr.hxx
|
||||||
|
CanvasObjectPlacement.hxx
|
||||||
|
CanvasPlacement.hxx
|
||||||
|
CanvasSystemAdapter.hxx
|
||||||
|
CanvasWindow.hxx
|
||||||
|
ODGauge.hxx
|
||||||
|
VGInitOperation.hxx
|
||||||
|
)
|
||||||
|
|
||||||
|
set(SOURCES
|
||||||
|
Canvas.cxx
|
||||||
|
CanvasEvent.cxx
|
||||||
|
CanvasEventManager.cxx
|
||||||
|
CanvasEventVisitor.cxx
|
||||||
|
CanvasMgr.cxx
|
||||||
|
CanvasObjectPlacement.cxx
|
||||||
|
CanvasPlacement.cxx
|
||||||
|
CanvasWindow.cxx
|
||||||
|
ODGauge.cxx
|
||||||
|
VGInitOperation.cxx
|
||||||
|
)
|
||||||
|
|
||||||
|
add_subdirectory(ShivaVG/src)
|
||||||
|
add_subdirectory(elements)
|
||||||
|
add_subdirectory(events)
|
||||||
|
add_subdirectory(layout)
|
||||||
|
|
||||||
|
simgear_scene_component(canvas canvas "${SOURCES}" "${HEADERS}")
|
||||||
@@ -0,0 +1,718 @@
|
|||||||
|
// The canvas for rendering with the 2d API
|
||||||
|
//
|
||||||
|
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.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 Library General Public
|
||||||
|
// License along with this library; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
|
||||||
|
#include "Canvas.hxx"
|
||||||
|
#include "CanvasEventManager.hxx"
|
||||||
|
#include "CanvasEventVisitor.hxx"
|
||||||
|
#include "CanvasPlacement.hxx"
|
||||||
|
#include <simgear/canvas/events/KeyboardEvent.hxx>
|
||||||
|
#include <simgear/canvas/events/MouseEvent.hxx>
|
||||||
|
#include <simgear/scene/util/parse_color.hxx>
|
||||||
|
#include <simgear/scene/util/RenderConstants.hxx>
|
||||||
|
|
||||||
|
#include <osg/Camera>
|
||||||
|
#include <osg/Geode>
|
||||||
|
#include <osgText/Text>
|
||||||
|
#include <osgViewer/Viewer>
|
||||||
|
|
||||||
|
#include <boost/algorithm/string/predicate.hpp>
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
|
namespace simgear
|
||||||
|
{
|
||||||
|
namespace canvas
|
||||||
|
{
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
Canvas::CullCallback::CullCallback(const CanvasWeakPtr& canvas):
|
||||||
|
_canvas( canvas )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Canvas::CullCallback::operator()( osg::Node* node,
|
||||||
|
osg::NodeVisitor* nv )
|
||||||
|
{
|
||||||
|
if( (nv->getTraversalMask() & simgear::MODEL_BIT) )
|
||||||
|
{
|
||||||
|
CanvasPtr canvas = _canvas.lock();
|
||||||
|
if( canvas )
|
||||||
|
canvas->enableRendering();
|
||||||
|
}
|
||||||
|
|
||||||
|
traverse(node, nv);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
Canvas::Canvas(SGPropertyNode* node):
|
||||||
|
PropertyBasedElement(node),
|
||||||
|
_canvas_mgr(0),
|
||||||
|
_event_manager(new EventManager),
|
||||||
|
_size_x(-1),
|
||||||
|
_size_y(-1),
|
||||||
|
_view_width(-1),
|
||||||
|
_view_height(-1),
|
||||||
|
_status(node, "status"),
|
||||||
|
_status_msg(node, "status-msg"),
|
||||||
|
_sampling_dirty(false),
|
||||||
|
_render_dirty(true),
|
||||||
|
_visible(true),
|
||||||
|
_render_always(false)
|
||||||
|
{
|
||||||
|
_status = 0;
|
||||||
|
setStatusFlags(MISSING_SIZE_X | MISSING_SIZE_Y);
|
||||||
|
|
||||||
|
_root_group.reset( new Group(this, _node) );
|
||||||
|
|
||||||
|
// Remove automatically created property listener as we forward them on our
|
||||||
|
// own
|
||||||
|
_root_group->removeListener();
|
||||||
|
_cull_callback = new CullCallback(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
Canvas::~Canvas()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Canvas::onDestroy()
|
||||||
|
{
|
||||||
|
if( _root_group )
|
||||||
|
{
|
||||||
|
_root_group->clearEventListener();
|
||||||
|
_root_group->onDestroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Canvas::setCanvasMgr(CanvasMgr* canvas_mgr)
|
||||||
|
{
|
||||||
|
_canvas_mgr = canvas_mgr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
CanvasMgr* Canvas::getCanvasMgr() const
|
||||||
|
{
|
||||||
|
return _canvas_mgr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool Canvas::isInit() const
|
||||||
|
{
|
||||||
|
return _texture.serviceable();
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Canvas::addParentCanvas(const CanvasWeakPtr& canvas)
|
||||||
|
{
|
||||||
|
if( canvas.expired() )
|
||||||
|
{
|
||||||
|
SG_LOG
|
||||||
|
(
|
||||||
|
SG_GENERAL,
|
||||||
|
SG_WARN,
|
||||||
|
"Canvas::addParentCanvas(" << _node->getPath(true) << "): "
|
||||||
|
"got an expired parent!"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_parent_canvases.insert(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Canvas::addChildCanvas(const CanvasWeakPtr& canvas)
|
||||||
|
{
|
||||||
|
if( canvas.expired() )
|
||||||
|
{
|
||||||
|
SG_LOG
|
||||||
|
(
|
||||||
|
SG_GENERAL,
|
||||||
|
SG_WARN,
|
||||||
|
"Canvas::addChildCanvas(" << _node->getPath(true) << "): "
|
||||||
|
" got an expired child!"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_child_canvases.insert(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Canvas::removeParentCanvas(const CanvasWeakPtr& canvas)
|
||||||
|
{
|
||||||
|
_parent_canvases.erase(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Canvas::removeChildCanvas(const CanvasWeakPtr& canvas)
|
||||||
|
{
|
||||||
|
_child_canvases.erase(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
GroupPtr Canvas::createGroup(const std::string& name)
|
||||||
|
{
|
||||||
|
return _root_group->createChild<Group>(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
GroupPtr Canvas::getGroup(const std::string& name)
|
||||||
|
{
|
||||||
|
return _root_group->getChild<Group>(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
GroupPtr Canvas::getOrCreateGroup(const std::string& name)
|
||||||
|
{
|
||||||
|
return _root_group->getOrCreateChild<Group>(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
GroupPtr Canvas::getRootGroup()
|
||||||
|
{
|
||||||
|
return _root_group;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Canvas::setLayout(const LayoutRef& layout)
|
||||||
|
{
|
||||||
|
_layout = layout;
|
||||||
|
_layout->setCanvas(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Canvas::setFocusElement(const ElementPtr& el)
|
||||||
|
{
|
||||||
|
if( el && el->getCanvas().lock() != this )
|
||||||
|
{
|
||||||
|
SG_LOG(SG_GUI, SG_WARN, "setFocusElement: element not from this canvas");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO focus out/in events
|
||||||
|
_focus_element = el;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Canvas::clearFocusElement()
|
||||||
|
{
|
||||||
|
_focus_element.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Canvas::enableRendering(bool force)
|
||||||
|
{
|
||||||
|
_visible = true;
|
||||||
|
if( force )
|
||||||
|
_render_dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Canvas::update(double delta_time_sec)
|
||||||
|
{
|
||||||
|
if( _status & (CREATE_FAILED | MISSING_SIZE) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( _status & STATUS_DIRTY )
|
||||||
|
{
|
||||||
|
_texture.setSize(_size_x, _size_y);
|
||||||
|
|
||||||
|
if( !_texture.serviceable() )
|
||||||
|
{
|
||||||
|
_texture.useImageCoords(true);
|
||||||
|
_texture.useStencil(true);
|
||||||
|
_texture.allocRT(/*_camera_callback*/);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Resizing causes a new texture to be created so we need to reapply all
|
||||||
|
// existing placements
|
||||||
|
reloadPlacements();
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::Camera* camera = _texture.getCamera();
|
||||||
|
|
||||||
|
// TODO Allow custom render order? For now just keep in order with
|
||||||
|
// property tree.
|
||||||
|
camera->setRenderOrder(osg::Camera::PRE_RENDER, _node->getIndex());
|
||||||
|
|
||||||
|
osg::Vec4 clear_color(0.0f, 0.0f, 0.0f , 1.0f);
|
||||||
|
parseColor(_node->getStringValue("background"), clear_color);
|
||||||
|
camera->setClearColor(clear_color);
|
||||||
|
|
||||||
|
camera->addChild(_root_group->getMatrixTransform());
|
||||||
|
|
||||||
|
if( _texture.serviceable() )
|
||||||
|
{
|
||||||
|
setStatusFlags(STATUS_OK);
|
||||||
|
setStatusFlags(STATUS_DIRTY, false);
|
||||||
|
_render_dirty = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setStatusFlags(CREATE_FAILED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( _layout )
|
||||||
|
_layout->setGeometry(SGRecti(0, 0, _view_width, _view_height));
|
||||||
|
|
||||||
|
if( _visible || _render_always )
|
||||||
|
{
|
||||||
|
BOOST_FOREACH(CanvasWeakPtr canvas_weak, _child_canvases)
|
||||||
|
{
|
||||||
|
// TODO should we check if the image the child canvas is displayed
|
||||||
|
// within is really visible?
|
||||||
|
CanvasPtr canvas = canvas_weak.lock();
|
||||||
|
if( canvas )
|
||||||
|
canvas->_visible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( _render_dirty )
|
||||||
|
{
|
||||||
|
// Also mark all canvases this canvas is displayed within as dirty
|
||||||
|
BOOST_FOREACH(CanvasWeakPtr canvas_weak, _parent_canvases)
|
||||||
|
{
|
||||||
|
CanvasPtr canvas = canvas_weak.lock();
|
||||||
|
if( canvas )
|
||||||
|
canvas->_render_dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_texture.setRender(_render_dirty);
|
||||||
|
|
||||||
|
_render_dirty = false;
|
||||||
|
_visible = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_texture.setRender(false);
|
||||||
|
|
||||||
|
_root_group->update(delta_time_sec);
|
||||||
|
|
||||||
|
if( _sampling_dirty )
|
||||||
|
{
|
||||||
|
_texture.setSampling(
|
||||||
|
_node->getBoolValue("mipmapping"),
|
||||||
|
_node->getIntValue("coverage-samples"),
|
||||||
|
_node->getIntValue("color-samples")
|
||||||
|
);
|
||||||
|
_sampling_dirty = false;
|
||||||
|
_render_dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
while( !_dirty_placements.empty() )
|
||||||
|
{
|
||||||
|
SGPropertyNode *node = _dirty_placements.back();
|
||||||
|
_dirty_placements.pop_back();
|
||||||
|
|
||||||
|
if( node->getIndex() >= static_cast<int>(_placements.size()) )
|
||||||
|
// New placement
|
||||||
|
_placements.resize(node->getIndex() + 1);
|
||||||
|
else
|
||||||
|
// Remove possibly existing placements
|
||||||
|
_placements[ node->getIndex() ].clear();
|
||||||
|
|
||||||
|
// Get new placements
|
||||||
|
PlacementFactoryMap::const_iterator placement_factory =
|
||||||
|
_placement_factories.find( node->getStringValue("type", "object") );
|
||||||
|
if( placement_factory != _placement_factories.end() )
|
||||||
|
{
|
||||||
|
Placements& placements = _placements[ node->getIndex() ] =
|
||||||
|
placement_factory->second(node, this);
|
||||||
|
node->setStringValue
|
||||||
|
(
|
||||||
|
"status-msg",
|
||||||
|
placements.empty() ? "No match" : "Ok"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
node->setStringValue("status-msg", "Unknown placement type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool Canvas::addEventListener( const std::string& type,
|
||||||
|
const EventListener& cb )
|
||||||
|
{
|
||||||
|
if( !_root_group.get() )
|
||||||
|
throw std::runtime_error("Canvas::addEventListener: no root group!");
|
||||||
|
|
||||||
|
return _root_group->addEventListener(type, cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool Canvas::dispatchEvent(const EventPtr& event)
|
||||||
|
{
|
||||||
|
if( !_root_group.get() )
|
||||||
|
throw std::runtime_error("Canvas::dispatchEvent: no root group!");
|
||||||
|
|
||||||
|
return _root_group->dispatchEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Canvas::setSizeX(int sx)
|
||||||
|
{
|
||||||
|
if( _size_x == sx )
|
||||||
|
return;
|
||||||
|
_size_x = sx;
|
||||||
|
setStatusFlags(STATUS_DIRTY);
|
||||||
|
|
||||||
|
if( _size_x <= 0 )
|
||||||
|
setStatusFlags(MISSING_SIZE_X);
|
||||||
|
else
|
||||||
|
setStatusFlags(MISSING_SIZE_X, false);
|
||||||
|
|
||||||
|
// reset flag to allow creation with new size
|
||||||
|
setStatusFlags(CREATE_FAILED, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Canvas::setSizeY(int sy)
|
||||||
|
{
|
||||||
|
if( _size_y == sy )
|
||||||
|
return;
|
||||||
|
_size_y = sy;
|
||||||
|
setStatusFlags(STATUS_DIRTY);
|
||||||
|
|
||||||
|
if( _size_y <= 0 )
|
||||||
|
setStatusFlags(MISSING_SIZE_Y);
|
||||||
|
else
|
||||||
|
setStatusFlags(MISSING_SIZE_Y, false);
|
||||||
|
|
||||||
|
// reset flag to allow creation with new size
|
||||||
|
setStatusFlags(CREATE_FAILED, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
int Canvas::getSizeX() const
|
||||||
|
{
|
||||||
|
return _size_x;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
int Canvas::getSizeY() const
|
||||||
|
{
|
||||||
|
return _size_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Canvas::setViewWidth(int w)
|
||||||
|
{
|
||||||
|
if( _view_width == w )
|
||||||
|
return;
|
||||||
|
_view_width = w;
|
||||||
|
|
||||||
|
_texture.setViewSize(_view_width, _view_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Canvas::setViewHeight(int h)
|
||||||
|
{
|
||||||
|
if( _view_height == h )
|
||||||
|
return;
|
||||||
|
_view_height = h;
|
||||||
|
|
||||||
|
_texture.setViewSize(_view_width, _view_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
int Canvas::getViewWidth() const
|
||||||
|
{
|
||||||
|
return _texture.getViewSize().x();
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
int Canvas::getViewHeight() const
|
||||||
|
{
|
||||||
|
return _texture.getViewSize().y();
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
SGRect<int> Canvas::getViewport() const
|
||||||
|
{
|
||||||
|
return SGRect<int>(0, 0, getViewWidth(), getViewHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool Canvas::handleMouseEvent(const MouseEventPtr& event)
|
||||||
|
{
|
||||||
|
if( !_root_group )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
EventVisitor visitor( EventVisitor::TRAVERSE_DOWN,
|
||||||
|
event->getClientPos(),
|
||||||
|
_root_group );
|
||||||
|
if( !_root_group->accept(visitor) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return _event_manager->handleEvent(event, visitor.getPropagationPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool Canvas::handleKeyboardEvent(const KeyboardEventPtr& event)
|
||||||
|
{
|
||||||
|
ElementPtr target = _focus_element.lock();
|
||||||
|
if( !target )
|
||||||
|
target = _root_group;
|
||||||
|
if( !target )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return target->dispatchEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool Canvas::propagateEvent( EventPtr const& event,
|
||||||
|
EventPropagationPath const& path )
|
||||||
|
{
|
||||||
|
return _event_manager->propagateEvent(event, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Canvas::childAdded( SGPropertyNode * parent,
|
||||||
|
SGPropertyNode * child )
|
||||||
|
{
|
||||||
|
if( parent != _node )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( child->getNameString() == "placement" )
|
||||||
|
_dirty_placements.push_back(child);
|
||||||
|
else if( _root_group.get() )
|
||||||
|
static_cast<Element*>(_root_group.get())->childAdded(parent, child);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Canvas::childRemoved( SGPropertyNode * parent,
|
||||||
|
SGPropertyNode * child )
|
||||||
|
{
|
||||||
|
_render_dirty = true;
|
||||||
|
|
||||||
|
if( parent != _node )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( child->getNameString() == "placement" )
|
||||||
|
_placements[ child->getIndex() ].clear();
|
||||||
|
else if( _root_group.get() )
|
||||||
|
static_cast<Element*>(_root_group.get())->childRemoved(parent, child);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Canvas::valueChanged(SGPropertyNode* node)
|
||||||
|
{
|
||||||
|
const std::string& name = node->getNameString();
|
||||||
|
|
||||||
|
if( boost::starts_with(name, "status")
|
||||||
|
|| boost::starts_with(name, "data-") )
|
||||||
|
return;
|
||||||
|
_render_dirty = true;
|
||||||
|
|
||||||
|
bool handled = true;
|
||||||
|
if( node->getParent()->getParent() == _node
|
||||||
|
&& node->getParent()->getNameString() == "placement" )
|
||||||
|
{
|
||||||
|
size_t index = node->getIndex();
|
||||||
|
if( index < _placements.size() )
|
||||||
|
{
|
||||||
|
Placements& placements = _placements[index];
|
||||||
|
if( !placements.empty() )
|
||||||
|
{
|
||||||
|
bool placement_dirty = false;
|
||||||
|
BOOST_FOREACH(PlacementPtr& placement, placements)
|
||||||
|
{
|
||||||
|
// check if change can be directly handled by placement
|
||||||
|
if( placement->getProps() == node->getParent()
|
||||||
|
&& !placement->childChanged(node) )
|
||||||
|
placement_dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !placement_dirty )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// prevent double updates...
|
||||||
|
for( size_t i = 0; i < _dirty_placements.size(); ++i )
|
||||||
|
{
|
||||||
|
if( node->getParent() == _dirty_placements[i] )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_dirty_placements.push_back(node->getParent());
|
||||||
|
}
|
||||||
|
else if( node->getParent() == _node )
|
||||||
|
{
|
||||||
|
if( name == "background" )
|
||||||
|
{
|
||||||
|
osg::Vec4 color;
|
||||||
|
if( _texture.getCamera() && parseColor(node->getStringValue(), color) )
|
||||||
|
{
|
||||||
|
_texture.getCamera()->setClearColor(color);
|
||||||
|
_render_dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( name == "mipmapping"
|
||||||
|
|| name == "coverage-samples"
|
||||||
|
|| name == "color-samples" )
|
||||||
|
{
|
||||||
|
_sampling_dirty = true;
|
||||||
|
}
|
||||||
|
else if( name == "additive-blend" )
|
||||||
|
{
|
||||||
|
_texture.useAdditiveBlend( node->getBoolValue() );
|
||||||
|
}
|
||||||
|
else if( name == "render-always" )
|
||||||
|
{
|
||||||
|
_render_always = node->getBoolValue();
|
||||||
|
}
|
||||||
|
else if( name == "size" )
|
||||||
|
{
|
||||||
|
if( node->getIndex() == 0 )
|
||||||
|
setSizeX( node->getIntValue() );
|
||||||
|
else if( node->getIndex() == 1 )
|
||||||
|
setSizeY( node->getIntValue() );
|
||||||
|
}
|
||||||
|
else if( name == "update" )
|
||||||
|
{
|
||||||
|
if( _root_group )
|
||||||
|
_root_group->update(0);
|
||||||
|
return update(0);
|
||||||
|
}
|
||||||
|
else if( name == "view" )
|
||||||
|
{
|
||||||
|
if( node->getIndex() == 0 )
|
||||||
|
setViewWidth( node->getIntValue() );
|
||||||
|
else if( node->getIndex() == 1 )
|
||||||
|
setViewHeight( node->getIntValue() );
|
||||||
|
}
|
||||||
|
else if( name == "freeze" )
|
||||||
|
_texture.setRender( node->getBoolValue() );
|
||||||
|
else
|
||||||
|
handled = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
handled = false;
|
||||||
|
|
||||||
|
if( !handled && _root_group.get() )
|
||||||
|
_root_group->valueChanged(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
osg::Texture2D* Canvas::getTexture() const
|
||||||
|
{
|
||||||
|
return _texture.getTexture();
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
Canvas::CullCallbackPtr Canvas::getCullCallback() const
|
||||||
|
{
|
||||||
|
return _cull_callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Canvas::reloadPlacements(const std::string& type)
|
||||||
|
{
|
||||||
|
for(size_t i = 0; i < _placements.size(); ++i)
|
||||||
|
{
|
||||||
|
if( _placements[i].empty() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
SGPropertyNode* child = _placements[i].front()->getProps();
|
||||||
|
if( type.empty()
|
||||||
|
// reload if type matches or no type specified
|
||||||
|
|| child->getStringValue("type", type.c_str()) == type )
|
||||||
|
{
|
||||||
|
_dirty_placements.push_back(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Canvas::addPlacementFactory( const std::string& type,
|
||||||
|
PlacementFactory factory )
|
||||||
|
{
|
||||||
|
if( _placement_factories.find(type) != _placement_factories.end() )
|
||||||
|
SG_LOG
|
||||||
|
(
|
||||||
|
SG_GENERAL,
|
||||||
|
SG_WARN,
|
||||||
|
"Canvas::addPlacementFactory: replace existing factory '" << type << "'"
|
||||||
|
);
|
||||||
|
|
||||||
|
_placement_factories[type] = factory;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Canvas::removePlacementFactory(const std::string& type)
|
||||||
|
{
|
||||||
|
PlacementFactoryMap::iterator it = _placement_factories.find(type);
|
||||||
|
if( it == _placement_factories.end() )
|
||||||
|
SG_LOG
|
||||||
|
(
|
||||||
|
SG_GENERAL,
|
||||||
|
SG_WARN,
|
||||||
|
"Canvas::removePlacementFactory: no such factory '" << type << "'"
|
||||||
|
);
|
||||||
|
else
|
||||||
|
_placement_factories.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Canvas::setSystemAdapter(const SystemAdapterPtr& system_adapter)
|
||||||
|
{
|
||||||
|
_system_adapter = system_adapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
SystemAdapterPtr Canvas::getSystemAdapter()
|
||||||
|
{
|
||||||
|
return _system_adapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Canvas::setStatusFlags(unsigned int flags, bool set)
|
||||||
|
{
|
||||||
|
if( set )
|
||||||
|
_status |= flags;
|
||||||
|
else
|
||||||
|
_status &= ~flags;
|
||||||
|
|
||||||
|
if( (_status & MISSING_SIZE_X) && (_status & MISSING_SIZE_Y) )
|
||||||
|
_status_msg = "Missing size";
|
||||||
|
else if( _status & MISSING_SIZE_X )
|
||||||
|
_status_msg = "Missing size-x";
|
||||||
|
else if( _status & MISSING_SIZE_Y )
|
||||||
|
_status_msg = "Missing size-y";
|
||||||
|
else if( _status & CREATE_FAILED )
|
||||||
|
_status_msg = "Creating render target failed";
|
||||||
|
else if( _status & STATUS_DIRTY )
|
||||||
|
_status_msg = "Creation pending...";
|
||||||
|
else
|
||||||
|
_status_msg = "Ok";
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
Canvas::PlacementFactoryMap Canvas::_placement_factories;
|
||||||
|
SystemAdapterPtr Canvas::_system_adapter;
|
||||||
|
|
||||||
|
} // namespace canvas
|
||||||
|
} // namespace simgear
|
||||||
@@ -0,0 +1,262 @@
|
|||||||
|
///@file
|
||||||
|
/// The canvas for rendering with the 2d API
|
||||||
|
//
|
||||||
|
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.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 Library General Public
|
||||||
|
// License along with this library; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
|
||||||
|
#ifndef CANVAS_HXX_
|
||||||
|
#define CANVAS_HXX_
|
||||||
|
|
||||||
|
#include "canvas_fwd.hxx"
|
||||||
|
#include "ODGauge.hxx"
|
||||||
|
|
||||||
|
#include <simgear/canvas/elements/CanvasGroup.hxx>
|
||||||
|
#include <simgear/canvas/layout/Layout.hxx>
|
||||||
|
#include <simgear/math/SGRect.hxx>
|
||||||
|
#include <simgear/nasal/cppbind/NasalObject.hxx>
|
||||||
|
#include <simgear/props/PropertyBasedElement.hxx>
|
||||||
|
#include <simgear/props/propertyObject.hxx>
|
||||||
|
|
||||||
|
#include <osg/NodeCallback>
|
||||||
|
#include <osg/observer_ptr>
|
||||||
|
|
||||||
|
#include <boost/scoped_ptr.hpp>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace simgear
|
||||||
|
{
|
||||||
|
/// Canvas 2D drawing API
|
||||||
|
namespace canvas
|
||||||
|
{
|
||||||
|
class CanvasMgr;
|
||||||
|
class MouseEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Canvas to draw onto (to an off-screen render target).
|
||||||
|
*/
|
||||||
|
class Canvas:
|
||||||
|
public PropertyBasedElement,
|
||||||
|
public nasal::Object
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum StatusFlags
|
||||||
|
{
|
||||||
|
STATUS_OK,
|
||||||
|
STATUS_DIRTY = 1,
|
||||||
|
MISSING_SIZE_X = STATUS_DIRTY << 1,
|
||||||
|
MISSING_SIZE_Y = MISSING_SIZE_X << 1,
|
||||||
|
MISSING_SIZE = MISSING_SIZE_X | MISSING_SIZE_Y,
|
||||||
|
CREATE_FAILED = MISSING_SIZE_Y << 1
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This callback is installed on every placement of the canvas in the
|
||||||
|
* scene to only render the canvas if at least one placement is visible
|
||||||
|
*/
|
||||||
|
class CullCallback:
|
||||||
|
public osg::NodeCallback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CullCallback(const CanvasWeakPtr& canvas);
|
||||||
|
|
||||||
|
private:
|
||||||
|
CanvasWeakPtr _canvas;
|
||||||
|
|
||||||
|
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
|
||||||
|
};
|
||||||
|
typedef osg::ref_ptr<CullCallback> CullCallbackPtr;
|
||||||
|
|
||||||
|
Canvas(SGPropertyNode* node);
|
||||||
|
virtual ~Canvas();
|
||||||
|
virtual void onDestroy();
|
||||||
|
|
||||||
|
void setCanvasMgr(CanvasMgr* canvas_mgr);
|
||||||
|
CanvasMgr* getCanvasMgr() const;
|
||||||
|
|
||||||
|
bool isInit() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a canvas which should be marked as dirty upon any change to this
|
||||||
|
* canvas.
|
||||||
|
*
|
||||||
|
* This mechanism is used to eg. redraw a canvas if it's displaying
|
||||||
|
* another canvas (recursive canvases)
|
||||||
|
*/
|
||||||
|
void addParentCanvas(const CanvasWeakPtr& canvas);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a canvas which should be marked visible if this canvas is visible.
|
||||||
|
*/
|
||||||
|
void addChildCanvas(const CanvasWeakPtr& canvas);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop notifying the given canvas upon changes
|
||||||
|
*/
|
||||||
|
void removeParentCanvas(const CanvasWeakPtr& canvas);
|
||||||
|
void removeChildCanvas(const CanvasWeakPtr& canvas);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new group
|
||||||
|
*/
|
||||||
|
GroupPtr createGroup(const std::string& name = "");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an existing group with the given name
|
||||||
|
*/
|
||||||
|
GroupPtr getGroup(const std::string& name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an existing group with the given name or otherwise create a new
|
||||||
|
* group
|
||||||
|
*/
|
||||||
|
GroupPtr getOrCreateGroup(const std::string& name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the root group of the canvas
|
||||||
|
*/
|
||||||
|
GroupPtr getRootGroup();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the layout of the canvas (the layout will automatically update with
|
||||||
|
* the viewport size of the canvas)
|
||||||
|
*/
|
||||||
|
void setLayout(const LayoutRef& layout);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the focus to the given element.
|
||||||
|
*
|
||||||
|
* The focus element will receive all keyboard events propagated to this
|
||||||
|
* canvas. If there is no valid focus element the root group will receive
|
||||||
|
* the events instead.
|
||||||
|
*/
|
||||||
|
void setFocusElement(const ElementPtr& el);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the focus element.
|
||||||
|
*
|
||||||
|
* @see setFocusElement()
|
||||||
|
*/
|
||||||
|
void clearFocusElement();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable rendering for the next frame
|
||||||
|
*
|
||||||
|
* @param force Force redraw even if nothing has changed (if dirty flag
|
||||||
|
* is not set)
|
||||||
|
*/
|
||||||
|
void enableRendering(bool force = false);
|
||||||
|
|
||||||
|
void update(double delta_time_sec);
|
||||||
|
|
||||||
|
bool addEventListener(const std::string& type, const EventListener& cb);
|
||||||
|
bool dispatchEvent(const EventPtr& event);
|
||||||
|
|
||||||
|
void setSizeX(int sx);
|
||||||
|
void setSizeY(int sy);
|
||||||
|
|
||||||
|
int getSizeX() const;
|
||||||
|
int getSizeY() const;
|
||||||
|
|
||||||
|
void setViewWidth(int w);
|
||||||
|
void setViewHeight(int h);
|
||||||
|
|
||||||
|
int getViewWidth() const;
|
||||||
|
int getViewHeight() const;
|
||||||
|
SGRect<int> getViewport() const;
|
||||||
|
|
||||||
|
bool handleMouseEvent(const MouseEventPtr& event);
|
||||||
|
bool handleKeyboardEvent(const KeyboardEventPtr& event);
|
||||||
|
|
||||||
|
bool propagateEvent( EventPtr const& event,
|
||||||
|
EventPropagationPath const& path );
|
||||||
|
|
||||||
|
virtual void childAdded( SGPropertyNode * parent,
|
||||||
|
SGPropertyNode * child );
|
||||||
|
virtual void childRemoved( SGPropertyNode * parent,
|
||||||
|
SGPropertyNode * child );
|
||||||
|
virtual void valueChanged (SGPropertyNode * node);
|
||||||
|
|
||||||
|
osg::Texture2D* getTexture() const;
|
||||||
|
|
||||||
|
CullCallbackPtr getCullCallback() const;
|
||||||
|
|
||||||
|
void reloadPlacements( const std::string& type = std::string() );
|
||||||
|
static void addPlacementFactory( const std::string& type,
|
||||||
|
PlacementFactory factory );
|
||||||
|
static void removePlacementFactory(const std::string& type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set global SystemAdapter for all Canvas/ODGauge instances.
|
||||||
|
*
|
||||||
|
* The SystemAdapter is responsible for application specific operations
|
||||||
|
* like loading images/fonts and adding/removing cameras to the scene
|
||||||
|
* graph.
|
||||||
|
*/
|
||||||
|
static void setSystemAdapter(const SystemAdapterPtr& system_adapter);
|
||||||
|
static SystemAdapterPtr getSystemAdapter();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
CanvasMgr *_canvas_mgr;
|
||||||
|
|
||||||
|
boost::scoped_ptr<EventManager> _event_manager;
|
||||||
|
|
||||||
|
int _size_x,
|
||||||
|
_size_y,
|
||||||
|
_view_width,
|
||||||
|
_view_height;
|
||||||
|
|
||||||
|
PropertyObject<int> _status;
|
||||||
|
PropertyObject<std::string> _status_msg;
|
||||||
|
|
||||||
|
bool _sampling_dirty,
|
||||||
|
_render_dirty,
|
||||||
|
_visible;
|
||||||
|
|
||||||
|
ODGauge _texture;
|
||||||
|
|
||||||
|
GroupPtr _root_group;
|
||||||
|
LayoutRef _layout;
|
||||||
|
|
||||||
|
ElementWeakPtr _focus_element;
|
||||||
|
|
||||||
|
CullCallbackPtr _cull_callback;
|
||||||
|
bool _render_always; //!< Used to disable automatic lazy rendering (culling)
|
||||||
|
|
||||||
|
std::vector<SGPropertyNode*> _dirty_placements;
|
||||||
|
std::vector<Placements> _placements;
|
||||||
|
std::set<CanvasWeakPtr> _parent_canvases, //!< Canvases showing this canvas
|
||||||
|
_child_canvases; //!< Canvases displayed within
|
||||||
|
// this canvas
|
||||||
|
|
||||||
|
typedef std::map<std::string, PlacementFactory> PlacementFactoryMap;
|
||||||
|
static PlacementFactoryMap _placement_factories;
|
||||||
|
|
||||||
|
void setStatusFlags(unsigned int flags, bool set = true);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
static SystemAdapterPtr _system_adapter;
|
||||||
|
|
||||||
|
Canvas(const Canvas&); // = delete;
|
||||||
|
Canvas& operator=(const Canvas&); // = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace canvas
|
||||||
|
} // namespace simgear
|
||||||
|
|
||||||
|
#endif /* CANVAS_HXX_ */
|
||||||
@@ -0,0 +1,151 @@
|
|||||||
|
// Canvas Event for event model similar to DOM Level 3 Event Model
|
||||||
|
//
|
||||||
|
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.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 Library General Public
|
||||||
|
// License along with this library; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
|
||||||
|
#include "CanvasEvent.hxx"
|
||||||
|
|
||||||
|
namespace simgear
|
||||||
|
{
|
||||||
|
namespace canvas
|
||||||
|
{
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
Event::Event():
|
||||||
|
type(UNKNOWN),
|
||||||
|
time(-1),
|
||||||
|
propagation_stopped(false),
|
||||||
|
default_prevented(false)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
Event::~Event()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool Event::canBubble() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
int Event::getType() const
|
||||||
|
{
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
std::string Event::getTypeString() const
|
||||||
|
{
|
||||||
|
return typeToStr(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
ElementWeakPtr Event::getTarget() const
|
||||||
|
{
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
ElementWeakPtr Event::getCurrentTarget() const
|
||||||
|
{
|
||||||
|
return current_target;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
double Event::getTime() const
|
||||||
|
{
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Event::stopPropagation()
|
||||||
|
{
|
||||||
|
propagation_stopped = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void Event::preventDefault()
|
||||||
|
{
|
||||||
|
default_prevented = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool Event::defaultPrevented() const
|
||||||
|
{
|
||||||
|
return default_prevented;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
int Event::getOrRegisterType(const std::string& type_str)
|
||||||
|
{
|
||||||
|
int type = strToType(type_str);
|
||||||
|
|
||||||
|
if( type == UNKNOWN )
|
||||||
|
{
|
||||||
|
// Register new type
|
||||||
|
TypeMap& type_map = getTypeMap();
|
||||||
|
type = type_map.size() + 1; // ids start with 1 (after UNKNOWN)
|
||||||
|
type_map.insert(TypeMap::value_type(type_str, type));
|
||||||
|
}
|
||||||
|
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
int Event::strToType(const std::string& str)
|
||||||
|
{
|
||||||
|
TypeMap const& type_map = getTypeMap();
|
||||||
|
|
||||||
|
TypeMap::map_by<name>::const_iterator it = type_map.by<name>().find(str);
|
||||||
|
if( it == type_map.by<name>().end() )
|
||||||
|
return UNKNOWN;
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
std::string Event::typeToStr(int type)
|
||||||
|
{
|
||||||
|
TypeMap const& type_map = getTypeMap();
|
||||||
|
|
||||||
|
TypeMap::map_by<id>::const_iterator it = type_map.by<id>().find(type);
|
||||||
|
if( it == type_map.by<id>().end() )
|
||||||
|
return "unknown";
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
Event::TypeMap& Event::getTypeMap()
|
||||||
|
{
|
||||||
|
static TypeMap type_map;
|
||||||
|
|
||||||
|
if( type_map.empty() )
|
||||||
|
{
|
||||||
|
# define ENUM_MAPPING(type, str, class_name)\
|
||||||
|
type_map.insert(TypeMap::value_type(str, type));
|
||||||
|
# include "CanvasEventTypes.hxx"
|
||||||
|
# undef ENUM_MAPPING
|
||||||
|
}
|
||||||
|
|
||||||
|
return type_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace canvas
|
||||||
|
} // namespace simgear
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user