mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-01 17:10:26 +08:00
Compare commits
2450 Commits
0.10.10
...
0.21.4-noe
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
81e249b56c | ||
|
|
ff7c8af56f | ||
|
|
a11ea291d8 | ||
|
|
cd615c6e52 | ||
|
|
1bd2d9fe81 | ||
|
|
510aef19e4 | ||
|
|
1dadd50cf2 | ||
|
|
b2a86d640a | ||
|
|
c27507bc77 | ||
|
|
b374c6cd8e | ||
|
|
29dc6c67fa | ||
|
|
10de748531 | ||
|
|
dcd5994456 | ||
|
|
13cd5e7a5e | ||
|
|
856e372dde | ||
|
|
423e67558b | ||
|
|
ace653593b | ||
|
|
7b31c737be | ||
|
|
0b534c9427 | ||
|
|
cdbdcfe676 | ||
|
|
b7239fdc84 | ||
|
|
a0559b156b | ||
|
|
79db6b2811 | ||
|
|
096592e4fc | ||
|
|
d135ef02e2 | ||
|
|
ee09e92496 | ||
|
|
e619c57759 | ||
|
|
f6a0323d46 | ||
|
|
933d26f005 | ||
|
|
ec8f9fdcfd | ||
|
|
f4a60f0b6f | ||
|
|
ade94cde1c | ||
|
|
71415992ac | ||
|
|
45392fcfc6 | ||
|
|
be3e6c538c | ||
|
|
f56875db4a | ||
|
|
0876603325 | ||
|
|
3a7f88dc6c | ||
|
|
07c24e95ba | ||
|
|
7ab1ee0a0b | ||
|
|
fc8ead2237 | ||
|
|
a1d43d2353 | ||
|
|
aaff1abc4f | ||
|
|
9c56a429cc | ||
|
|
757d3eb90b | ||
|
|
4812ce4eaf | ||
|
|
56552afa6c | ||
|
|
45a3b59a23 | ||
|
|
08d0ef7408 | ||
|
|
8da6ea1707 | ||
|
|
64962e8e3d | ||
|
|
71bb0cf226 | ||
|
|
948e15c72c | ||
|
|
f06cc0b17f | ||
|
|
2aa139b579 | ||
|
|
67c6a15b93 | ||
|
|
78c029d833 | ||
|
|
afd10b1aa6 | ||
|
|
f1cd819673 | ||
|
|
fb466a6a96 | ||
|
|
0b7181fc88 | ||
|
|
97f2b4b65d | ||
|
|
39dedba93a | ||
|
|
49daa211ea | ||
|
|
01c2e70b11 | ||
|
|
fa4a2eb5e3 | ||
|
|
9e86faa4ad | ||
|
|
e31eec2c55 | ||
|
|
2d7d0ec424 | ||
|
|
191e4250ef | ||
|
|
e56e0c37f7 | ||
|
|
6a5b844bac | ||
|
|
20ad6cca2c | ||
|
|
f90fede65c | ||
|
|
61dbe51ee3 | ||
|
|
f2687ed1ff | ||
|
|
cdd8cd9e34 | ||
|
|
6d36fc1fcd | ||
|
|
ba5579f063 | ||
|
|
6395487b58 | ||
|
|
f0ba56bf5e | ||
|
|
a94a4c9802 | ||
|
|
e2f037189a | ||
|
|
bcb29cfb66 | ||
|
|
d25bb758ca | ||
|
|
424dc90dce | ||
|
|
5d6875ed98 | ||
|
|
f8b761d79b | ||
|
|
446590b19f | ||
|
|
3feb03cf35 | ||
|
|
a593b0d525 | ||
|
|
ca4276a951 | ||
|
|
e8b54de94a | ||
|
|
f9719c197d | ||
|
|
d391f237eb | ||
|
|
0b4f5d2925 | ||
|
|
7d2272beb3 | ||
|
|
6d690a315a | ||
|
|
ce81fe445a | ||
|
|
a2a75a28ba | ||
|
|
ddeca4585d | ||
|
|
64f79813cd | ||
|
|
b8c298efd9 | ||
|
|
97be9d4ace | ||
|
|
a1168ba8a9 | ||
|
|
c307f5c65f | ||
|
|
b0cf2e9927 | ||
|
|
c7e46c1431 | ||
|
|
092f6abccc | ||
|
|
dcbad6a0aa | ||
|
|
337832e1b8 | ||
|
|
d901fb23e3 | ||
|
|
59d5675fe6 | ||
|
|
ab3ade0309 | ||
|
|
720d50fe74 | ||
|
|
33fb2f75ad | ||
|
|
36c0054070 | ||
|
|
55a84cfdaa | ||
|
|
2dd64a6283 | ||
|
|
f75839294a | ||
|
|
e219152e8f | ||
|
|
d031d79369 | ||
|
|
0c476936e3 | ||
|
|
d86193036f | ||
|
|
0c3b202006 | ||
|
|
1cc7c2818f | ||
|
|
1e145550df | ||
|
|
2a3580e060 | ||
|
|
d3facb1a84 | ||
|
|
bf5c70d2e2 | ||
|
|
7f7609075f | ||
|
|
cf49ebf238 | ||
|
|
879f0f6941 | ||
|
|
af481fc730 | ||
|
|
1b67d6a86a | ||
|
|
31d975acd5 | ||
|
|
54c68f8e6c | ||
|
|
aedfcdc576 | ||
|
|
bfc4e939d1 | ||
|
|
67df99aa57 | ||
|
|
d88c816ca1 | ||
|
|
5b1c9e7233 | ||
|
|
8d6c809c3c | ||
|
|
52e417c313 | ||
|
|
5592a1ebfe | ||
|
|
42fbdda567 | ||
|
|
ae3fda37a9 | ||
|
|
ffd89ead86 | ||
|
|
937e9fbb3b | ||
|
|
9ecf71e5ed | ||
|
|
ff83b14b49 | ||
|
|
263eb6fbde | ||
|
|
e7d61b3856 | ||
|
|
682d54725a | ||
|
|
ba33c080bc | ||
|
|
2da448f4ee | ||
|
|
376c82325e | ||
|
|
95f65e1599 | ||
|
|
060af6f7bb | ||
|
|
999c01d71d | ||
|
|
a54f76238b | ||
|
|
f8f6b7788a | ||
|
|
e54195c47f | ||
|
|
e300d4c5c1 | ||
|
|
b91addb261 | ||
|
|
0f221ba3cd | ||
|
|
0070de4aaf | ||
|
|
11b4becdde | ||
|
|
8b8a512cbb | ||
|
|
141f2d3334 | ||
|
|
6dca8ab0f3 | ||
|
|
fc7a6708c5 | ||
|
|
11e5437eba | ||
|
|
c4e94bcdc3 | ||
|
|
51a7122dbe | ||
|
|
d13f594d9c | ||
|
|
85cc6fe3c7 | ||
|
|
50a0961f4e | ||
|
|
a406c37750 | ||
|
|
1cb7f3fb87 | ||
|
|
ab99719a78 | ||
|
|
e66ea7b42b | ||
|
|
46edd15121 | ||
|
|
e7bea0ec03 | ||
|
|
e3b7e9378d | ||
|
|
6fe5e6375f | ||
|
|
92b9cc89e0 | ||
|
|
53025bf059 | ||
|
|
e51d161407 | ||
|
|
3a3a4ed745 | ||
|
|
d6704ca2ed | ||
|
|
8c5c4f63bf | ||
|
|
98635ae33d | ||
|
|
70cbe52fcf | ||
|
|
e6e6630d54 | ||
|
|
34fec972dc | ||
|
|
67604a0fb0 | ||
|
|
731d73b798 | ||
|
|
70c3d5d97f | ||
|
|
23b0b37493 | ||
|
|
c7f49134eb | ||
|
|
549fc2a592 | ||
|
|
7005a8aa2a | ||
|
|
2065688116 | ||
|
|
89e3e10d89 | ||
|
|
437ed09335 | ||
|
|
59d220c54f | ||
|
|
2acd8f82b5 | ||
|
|
724e068194 | ||
|
|
e30e6937fa | ||
|
|
9406b15746 | ||
|
|
67ca39514a | ||
|
|
5fd0448924 | ||
|
|
413be8e824 | ||
|
|
dcedd8bb6b | ||
|
|
e4edee33eb | ||
|
|
128d3b0d0a | ||
|
|
ff61266430 | ||
|
|
f928cb6787 | ||
|
|
3a9ae201a7 | ||
|
|
34af17de59 | ||
|
|
95e6a9f039 | ||
|
|
b5eef4b86a | ||
|
|
40ab33031b | ||
|
|
0e908206d0 | ||
|
|
6b9f7de782 | ||
|
|
22fede9335 | ||
|
|
22917cc1c3 | ||
|
|
98bf3fb184 | ||
|
|
8d301afe6c | ||
|
|
e3ceb8a572 | ||
|
|
f12cc83fc2 | ||
|
|
4a6a765cd1 | ||
|
|
a4761ad397 | ||
|
|
aa380de2a7 | ||
|
|
467dc738c7 | ||
|
|
64cb7fb6fe | ||
|
|
8a8c360f89 | ||
|
|
83693ed1b9 | ||
|
|
860c14e0ec | ||
|
|
85bc1ee27f | ||
|
|
05676d1577 | ||
|
|
6d713c2ccb | ||
|
|
16e3314e64 | ||
|
|
d59a306ae3 | ||
|
|
bdfab4e0be | ||
|
|
c9d50ef445 | ||
|
|
2889cf8048 | ||
|
|
def876983d | ||
|
|
69214b927a | ||
|
|
67b2cbe5ca | ||
|
|
86f66cc8b8 | ||
|
|
d70924a3a4 | ||
|
|
1297714271 | ||
|
|
8e30c1c812 | ||
|
|
df888962f4 | ||
|
|
a8cdf1f940 | ||
|
|
769ace86ce | ||
|
|
97a150b180 | ||
|
|
6e8f43916c | ||
|
|
5b0047efad | ||
|
|
fdb78d33b0 | ||
|
|
2cbd43dfb6 | ||
|
|
1f06386f37 | ||
|
|
1e9b090624 | ||
|
|
7e3e5ec50b | ||
|
|
8d23f19f6c | ||
|
|
9afbcf2d06 | ||
|
|
30bf5895ca | ||
|
|
e0a2adcb45 | ||
|
|
87faea7a85 | ||
|
|
74c6e9cfec | ||
|
|
675dad5f76 | ||
|
|
55546132a0 | ||
|
|
fa31affea0 | ||
|
|
95a76cb696 | ||
|
|
737675c6f1 | ||
|
|
4d6bc78e3d | ||
|
|
adfb250d4e | ||
|
|
a14b39b953 | ||
|
|
3dd0965a15 | ||
|
|
e059ead7f5 | ||
|
|
749cd096ff | ||
|
|
37b920396c | ||
|
|
0dc5fbdd70 | ||
|
|
f1c987a0ce | ||
|
|
69b0caed6f | ||
|
|
8826f136a9 | ||
|
|
8cd4a6feff | ||
|
|
33e54430a1 | ||
|
|
9797918d52 | ||
|
|
aa3b71dbf6 | ||
|
|
34ed9d79c7 | ||
|
|
5943a8b065 | ||
|
|
71a28bb570 | ||
|
|
89f56642b7 | ||
|
|
fb6770d70f | ||
|
|
a10eb062e5 | ||
|
|
4d502c9e0d | ||
|
|
83c1adfd1e | ||
|
|
bc42bc3520 | ||
|
|
8f8256c1dd | ||
|
|
744c737da1 | ||
|
|
4cfd3ba496 | ||
|
|
2da333895c | ||
|
|
601e4015fb | ||
|
|
47c94a4474 | ||
|
|
cf64b20e1f | ||
|
|
5d200a0799 | ||
|
|
dab7aa6e58 | ||
|
|
b646c5e1db | ||
|
|
190071678f | ||
|
|
dc58266eda | ||
|
|
e92dfd50e1 | ||
|
|
1857111d7d | ||
|
|
3e630e0250 | ||
|
|
d35193721b | ||
|
|
e46af2c3cd | ||
|
|
6cefc6d00a | ||
|
|
ff739a98a5 | ||
|
|
4321c3040a | ||
|
|
1e82fd3110 | ||
|
|
b9c7182a08 | ||
|
|
656da152b3 | ||
|
|
f140e99881 | ||
|
|
53e0099dd8 | ||
|
|
51f779628f | ||
|
|
e7ee025127 | ||
|
|
e6a5fe9c26 | ||
|
|
e297320dd5 | ||
|
|
4d895785a6 | ||
|
|
c2c68c0caf | ||
|
|
9bd758a62c | ||
|
|
578c19cc38 | ||
|
|
4776de7931 | ||
|
|
191e165a28 | ||
|
|
f584f42ea4 | ||
|
|
b44b212218 | ||
|
|
9ad6b626e4 | ||
|
|
32ad92e2d2 | ||
|
|
6f8f6d4d8e | ||
|
|
c99203bbed | ||
|
|
20d873c29e | ||
|
|
4d8c1d8b90 | ||
|
|
315350dbfc | ||
|
|
02140f92db | ||
|
|
402afc07ed | ||
|
|
a8e5bbf415 | ||
|
|
5b3a7d5674 | ||
|
|
d56692640e | ||
|
|
2dc7b59b05 | ||
|
|
bbe10bca39 | ||
|
|
e2dc3ac67e | ||
|
|
83d1e27b81 | ||
|
|
3c215b9b4d | ||
|
|
bdaed2f362 | ||
|
|
e048d8ae72 | ||
|
|
5b868d665f | ||
|
|
a56373f66d | ||
|
|
5ec73bee8d | ||
|
|
b1dd44526d | ||
|
|
de62bbb9b7 | ||
|
|
7a5c50cb0e | ||
|
|
9622fe8393 | ||
|
|
5f55f63443 | ||
|
|
aa0e6ef692 | ||
|
|
03a106ea36 | ||
|
|
29a2b64a0c | ||
|
|
51f6b32f47 | ||
|
|
9e0173f4cb | ||
|
|
12c2dd707c | ||
|
|
fcec98105d | ||
|
|
a4ec95963e | ||
|
|
49353b134c | ||
|
|
f69085304e | ||
|
|
3f797e02e3 | ||
|
|
ab50ba0b6c | ||
|
|
528b640a18 | ||
|
|
4d8a7b4659 | ||
|
|
ba6575fcb9 | ||
|
|
1173f06bc8 | ||
|
|
a08fce2068 | ||
|
|
d8324a11d5 | ||
|
|
a6c9b3babe | ||
|
|
145430cafd | ||
|
|
5194f40794 | ||
|
|
129bbf8f98 | ||
|
|
a9d4a16ba4 | ||
|
|
b2f13c2772 | ||
|
|
f3ace6c86a | ||
|
|
3147b4ab56 | ||
|
|
fcde52c6bf | ||
|
|
5b31a4725d | ||
|
|
e4955ee386 | ||
|
|
e5b4973ddc | ||
|
|
f3095a2e0a | ||
|
|
044145926f | ||
|
|
a3823594a4 | ||
|
|
3071da42f3 | ||
|
|
93ee8f9b30 | ||
|
|
7ca881453e | ||
|
|
8662eb0dd7 | ||
|
|
33130890fd | ||
|
|
bca8b30832 | ||
|
|
6eb81cbb72 | ||
|
|
0e62050824 | ||
|
|
cf5e90238b | ||
|
|
8cf12c6135 | ||
|
|
4ab0090ecd | ||
|
|
580e35afb1 | ||
|
|
12906f4490 | ||
|
|
baae713471 | ||
|
|
67710ef94c | ||
|
|
090ae0c444 | ||
|
|
6684bafe34 | ||
|
|
5fcbe2ed70 | ||
|
|
459c7b2bd7 | ||
|
|
9ae2c46546 | ||
|
|
7af2a27e89 | ||
|
|
dbecaac809 | ||
|
|
6c07a670ee | ||
|
|
4ba805b5b3 | ||
|
|
b002e85e0f | ||
|
|
ec2aa5c952 | ||
|
|
06150c697f | ||
|
|
38bcb0060c | ||
|
|
ddd5eb5a41 | ||
|
|
20bc281db7 | ||
|
|
7c5acd8970 | ||
|
|
1886f99cbf | ||
|
|
2ad334df90 | ||
|
|
0ab5a8f43e | ||
|
|
8682026396 | ||
|
|
6cb741667d | ||
|
|
56c5622d20 | ||
|
|
e245782c6c | ||
|
|
9895e4c162 | ||
|
|
f67087075a | ||
|
|
d0242b14cf | ||
|
|
d16e24a1a3 | ||
|
|
ab5fd5018b | ||
|
|
44810a14e0 | ||
|
|
697fe5ebb3 | ||
|
|
54c0ee4244 | ||
|
|
d284cd11cf | ||
|
|
467ea42981 | ||
|
|
77d947d4fb | ||
|
|
533d78d570 | ||
|
|
aee034c5ed | ||
|
|
0092e15cd7 | ||
|
|
23d9e0e4bb | ||
|
|
8c56b5b1ce | ||
|
|
bccc5b13af | ||
|
|
5f65618d40 | ||
|
|
cff0d15460 | ||
|
|
b6671f4d8c | ||
|
|
9db66600b3 | ||
|
|
67cd4b69c1 | ||
|
|
cffb7981b6 | ||
|
|
71ffd922ed | ||
|
|
870467393b | ||
|
|
79f203a2c4 | ||
|
|
baa5b638ae | ||
|
|
8f12463f71 | ||
|
|
14b56813d3 | ||
|
|
44b057b0d7 | ||
|
|
a901f20d06 | ||
|
|
3ba02d2ef6 | ||
|
|
263e0170f1 | ||
|
|
e017a0fcf4 | ||
|
|
103db3181b | ||
|
|
bc253df24a | ||
|
|
544ea9dff2 | ||
|
|
09c2c4bbcb | ||
|
|
c209cf1c9b | ||
|
|
202d59b408 | ||
|
|
9671daf9c3 | ||
|
|
b5518ff618 | ||
|
|
2111b6497b | ||
|
|
b51b2525a5 | ||
|
|
45d51808e3 | ||
|
|
bc39b19517 | ||
|
|
7baedf4c72 | ||
|
|
20361400e1 | ||
|
|
c43118cde8 | ||
|
|
371a3ef851 | ||
|
|
daefc5ff54 | ||
|
|
b932da6dcf | ||
|
|
f88ce1618b | ||
|
|
c5e4d67f80 | ||
|
|
ed68fe777b | ||
|
|
6fb553a5e7 | ||
|
|
db00e04cc1 | ||
|
|
eeecb21793 | ||
|
|
a5685c3e31 | ||
|
|
138d4aa1be | ||
|
|
79d2b3fade | ||
|
|
32bf0f9d61 | ||
|
|
22a771e29c | ||
|
|
17d8a92614 | ||
|
|
a91cd0c659 | ||
|
|
ae92ec40d7 | ||
|
|
7338cb8a85 | ||
|
|
456560b9e4 | ||
|
|
f9257beeb8 | ||
|
|
485bf806bd | ||
|
|
68ae3b76af | ||
|
|
05d45872f3 | ||
|
|
3da4bb9faa | ||
|
|
a921d615c5 | ||
|
|
2b9ae3a2ad | ||
|
|
1a64e05e2f | ||
|
|
350f995ee9 | ||
|
|
eabf3e3d57 | ||
|
|
be24203840 | ||
|
|
48ebf969bd | ||
|
|
656618ccb7 | ||
|
|
f5ab422c42 | ||
|
|
5a676e9032 | ||
|
|
11e9837b82 | ||
|
|
dddf6378ae | ||
|
|
5167927d01 | ||
|
|
f475f2d21c | ||
|
|
9fccb8703a | ||
|
|
62b5f13dd8 | ||
|
|
b8c22e1c99 | ||
|
|
d75cc04ad2 | ||
|
|
8d2dbe32c4 | ||
|
|
a9d4fc9291 | ||
|
|
696216b35b | ||
|
|
6342658ec5 | ||
|
|
3f633081cb | ||
|
|
a6f3a81999 | ||
|
|
3e3d4142fc | ||
|
|
0a37d01d1d | ||
|
|
ba38d9f321 | ||
|
|
d7b5fa5d17 | ||
|
|
766301b175 | ||
|
|
289d4afd76 | ||
|
|
630cb6a59f | ||
|
|
12c46286f6 | ||
|
|
c9dbe6205d | ||
|
|
f94f9cbb9b | ||
|
|
b7c2f6801b | ||
|
|
8b1b874bf3 | ||
|
|
127a41a53e | ||
|
|
c1492533c3 | ||
|
|
ada3e75005 | ||
|
|
21dbeed4b7 | ||
|
|
fe896260c5 | ||
|
|
56bc15d7cd | ||
|
|
e9d7fcd7ae | ||
|
|
8c336e1e39 | ||
|
|
4390cb6428 | ||
|
|
20c2e8b5be | ||
|
|
ad8b2301d8 | ||
|
|
d75f9524f3 | ||
|
|
aedc70218b | ||
|
|
a11492943a | ||
|
|
854a52c6a5 | ||
|
|
b4f11e18f3 | ||
|
|
6449302318 | ||
|
|
3623ede989 | ||
|
|
0e051a16a0 | ||
|
|
c88e3d0a8b | ||
|
|
ff956a725e | ||
|
|
40ab98a814 | ||
|
|
f02efb5836 | ||
|
|
0764999f22 | ||
|
|
7515556444 | ||
|
|
3b7c6cd1f4 | ||
|
|
93bfad626e | ||
|
|
2fcef88016 | ||
|
|
f4207979ad | ||
|
|
b92f55be43 | ||
|
|
a8f0abf892 | ||
|
|
54267b1b33 | ||
|
|
4c1e72d82e | ||
|
|
a58ec494d1 | ||
|
|
69735b6271 | ||
|
|
d002711f21 | ||
|
|
06e85e140c | ||
|
|
c4d127cae4 | ||
|
|
21737f9937 | ||
|
|
ccc519ec58 | ||
|
|
1e4b172a7d | ||
|
|
752509fb15 | ||
|
|
f6e17be2b4 | ||
|
|
da2e2f810c | ||
|
|
5b44c557b3 | ||
|
|
600d68932d | ||
|
|
800d087b07 | ||
|
|
db43479e44 | ||
|
|
736c8aceae | ||
|
|
351c659beb | ||
|
|
ab8f0e2b34 | ||
|
|
4f46d8e904 | ||
|
|
98c69c4578 | ||
|
|
4e4207a6dd | ||
|
|
ea4cc7cb6c | ||
|
|
f7bc47572b | ||
|
|
d119487dd7 | ||
|
|
967c57d165 | ||
|
|
862eb0a90a | ||
|
|
cad184e82b | ||
|
|
d61e463595 | ||
|
|
5cdb346a35 | ||
|
|
8696a38343 | ||
|
|
e59aad03ed | ||
|
|
9bf12742b1 | ||
|
|
bb7e9edb9b | ||
|
|
f871e4359d | ||
|
|
03cfaf2063 | ||
|
|
089441a496 | ||
|
|
481a140f84 | ||
|
|
c42a4e3d7e | ||
|
|
c1a22609f3 | ||
|
|
b759b1b4d1 | ||
|
|
6b119c1f90 | ||
|
|
7e298e1999 | ||
|
|
c9472962d7 | ||
|
|
4d75361fe0 | ||
|
|
e99c658276 | ||
|
|
57326214f1 | ||
|
|
47e40ef34d | ||
|
|
aa31a900fb | ||
|
|
28e624e6b2 | ||
|
|
731b073ed8 | ||
|
|
5d777469ff | ||
|
|
70e9dff7da | ||
|
|
814a243693 | ||
|
|
c49785061f | ||
|
|
0bc483b6d3 | ||
|
|
eae5f2b428 | ||
|
|
94cf1dfd32 | ||
|
|
1a967127d9 | ||
|
|
792c967d46 | ||
|
|
a67dbc26f2 | ||
|
|
f1993d9cd7 | ||
|
|
da99d7e4a0 | ||
|
|
e896ffb5c0 | ||
|
|
04cbf56cc0 | ||
|
|
c5051bf82a | ||
|
|
7a9f01b9a3 | ||
|
|
70094edb75 | ||
|
|
eb2af19a89 | ||
|
|
af227bad51 | ||
|
|
ee63ce338a | ||
|
|
1b3a6abb82 | ||
|
|
4a8a20c7d1 | ||
|
|
a125797e50 | ||
|
|
a6f0877045 | ||
|
|
b5cae38eb9 | ||
|
|
d8ebbc2645 | ||
|
|
d700d09339 | ||
|
|
3104dff006 | ||
|
|
839045a538 | ||
|
|
a824945816 | ||
|
|
1acf8ff193 | ||
|
|
51826c9a97 | ||
|
|
7a5d04062d | ||
|
|
049238dd59 | ||
|
|
3271723034 | ||
|
|
da8e76ffed | ||
|
|
3131474102 | ||
|
|
3ffc8ce73f | ||
|
|
ee44adeb1f | ||
|
|
96c1c81e22 | ||
|
|
0022b6b993 | ||
|
|
721e046f5d | ||
|
|
d733029565 | ||
|
|
7859313beb | ||
|
|
80199f23b5 | ||
|
|
bce7ae6acd | ||
|
|
f88845e138 | ||
|
|
bdc7be40b4 | ||
|
|
e4cb59b74d | ||
|
|
dab407e5b9 | ||
|
|
98a499b603 | ||
|
|
f5d7dc2814 | ||
|
|
ab1aa5578a | ||
|
|
ccbdb586da | ||
|
|
f467f2af7f | ||
|
|
7c4d2bbdf4 | ||
|
|
fb206b4f1e | ||
|
|
ddecefbb9c | ||
|
|
ad44b65a28 | ||
|
|
fdaaa6ccfa | ||
|
|
34e1af7e22 | ||
|
|
54e2688a1d | ||
|
|
f9abcf9e35 | ||
|
|
01eb57f293 | ||
|
|
7be22d1b67 | ||
|
|
4b527f9c36 | ||
|
|
4d965c2089 | ||
|
|
47cbd633c3 | ||
|
|
b95537a680 | ||
|
|
e102243f0e | ||
|
|
e7a2f206a0 | ||
|
|
d04b1a13be | ||
|
|
92b1dabf1c | ||
|
|
e269067d4c | ||
|
|
596cd10b69 | ||
|
|
6a730b51c7 | ||
|
|
4ecf37a3ab | ||
|
|
99275fba1d | ||
|
|
25c2a51ee3 | ||
|
|
600484e12c | ||
|
|
8878d9fcdf | ||
|
|
72e1649cdd | ||
|
|
afbc0edbd6 | ||
|
|
fbc30042c4 | ||
|
|
a4da1e14b4 | ||
|
|
3047b7da6b | ||
|
|
bbb3c56008 | ||
|
|
f71f00277c | ||
|
|
0e5ec91280 | ||
|
|
3aae79270f | ||
|
|
1b4a992b55 | ||
|
|
384b120d2e | ||
|
|
304c365ae6 | ||
|
|
d5572d03ad | ||
|
|
6d552b7873 | ||
|
|
32eb266c79 | ||
|
|
2cb509c825 | ||
|
|
168c87b5ba | ||
|
|
a80e062bef | ||
|
|
9e321971ef | ||
|
|
8260733b11 | ||
|
|
bbccbd63e4 | ||
|
|
bedc771fa4 | ||
|
|
933ac736f1 | ||
|
|
c5158cade5 | ||
|
|
eef0a23b1b | ||
|
|
3d33370e4c | ||
|
|
4e6e404951 | ||
|
|
29368ebdb3 | ||
|
|
a24211583d | ||
|
|
d50b33a7b8 | ||
|
|
a689d8a23f | ||
|
|
bd80811ea1 | ||
|
|
cabf03af44 | ||
|
|
f93cdc31a6 | ||
|
|
e0973fea92 | ||
|
|
49cb470b8d | ||
|
|
d2784095a3 | ||
|
|
1db17dd118 | ||
|
|
23d8353540 | ||
|
|
96a628877c | ||
|
|
24052a6ebe | ||
|
|
775c9318d3 | ||
|
|
f263d560b4 | ||
|
|
729f96f467 | ||
|
|
8d63e9eae1 | ||
|
|
39f68c44c6 | ||
|
|
0a9d237ac2 | ||
|
|
07d21e6b03 | ||
|
|
53a759e2da | ||
|
|
6741355842 | ||
|
|
1460c56254 | ||
|
|
dec135a3fb | ||
|
|
9edd9b741d | ||
|
|
43eba76a20 | ||
|
|
bf45a0cba2 | ||
|
|
4be07fc3e9 | ||
|
|
4e32e8846c | ||
|
|
6468245317 | ||
|
|
169b79215d | ||
|
|
4a09c4bdcf | ||
|
|
3505611fb5 | ||
|
|
55228aa574 | ||
|
|
e800662bac | ||
|
|
33e9abdfad | ||
|
|
cd10cafd0e | ||
|
|
736cf0efc7 | ||
|
|
4f6d8b1fbe | ||
|
|
8fa216bd9d | ||
|
|
661a05b0da | ||
|
|
0809946c66 | ||
|
|
4857d43146 | ||
|
|
b7ada1992e | ||
|
|
2ee3445728 | ||
|
|
4142ff003c | ||
|
|
542f06ec24 | ||
|
|
dacf724ea6 | ||
|
|
274903dd63 | ||
|
|
c19f81ac12 | ||
|
|
846bd59d0b | ||
|
|
6e1f07e097 | ||
|
|
1ca2c25a10 | ||
|
|
c5ec4f337b | ||
|
|
554b08256b | ||
|
|
a2b0de2a4d | ||
|
|
fb6659e29d | ||
|
|
db00f55981 | ||
|
|
ffdb2eb855 | ||
|
|
13679cc52a | ||
|
|
4769fc235f | ||
|
|
ff5695878c | ||
|
|
6029b6283d | ||
|
|
86ac63ab19 | ||
|
|
de5610bd08 | ||
|
|
7a9a5d2ef9 | ||
|
|
b6d4c6f024 | ||
|
|
ff3c6c8e06 | ||
|
|
e2007a8f82 | ||
|
|
bda18bc517 | ||
|
|
d00717b068 | ||
|
|
c7be9a23ee | ||
|
|
caffb56246 | ||
|
|
d5cfd8013d | ||
|
|
415a2778f1 | ||
|
|
6e55525a7b | ||
|
|
7eae992d6f | ||
|
|
2509b6ee09 | ||
|
|
45ddce938a | ||
|
|
6e0081e248 | ||
|
|
bf39c5295b | ||
|
|
8842d0c0e3 | ||
|
|
511be5f663 | ||
|
|
ae5ce029d6 | ||
|
|
798466bb05 | ||
|
|
0902ccc340 | ||
|
|
208f1e5b7c | ||
|
|
b40d9610ed | ||
|
|
35385e299d | ||
|
|
6acfc62196 | ||
|
|
eb9999d7b1 | ||
|
|
69a2aacc8e | ||
|
|
013bd0c72a | ||
|
|
89ece8cd4e | ||
|
|
360a153565 | ||
|
|
63d40b2240 | ||
|
|
cb60443a33 | ||
|
|
609d45ac9b | ||
|
|
b542d6a0db | ||
|
|
c7b84c60bc | ||
|
|
55509c6c27 | ||
|
|
00695731fe | ||
|
|
09d2f7d232 | ||
|
|
e906b40e50 | ||
|
|
1b675c3dcb | ||
|
|
d2673ed2fa | ||
|
|
cc9fd439fe | ||
|
|
fbdc3780c7 | ||
|
|
c44837a4cb | ||
|
|
91285e5e97 | ||
|
|
abc3ebee8c | ||
|
|
1af139134e | ||
|
|
7d377d26df | ||
|
|
7041d5fd34 | ||
|
|
c19da22ca4 | ||
|
|
50c3bb7ce9 | ||
|
|
0a4d0038cb | ||
|
|
d14efea4ac | ||
|
|
45223b306a | ||
|
|
3e9cff4053 | ||
|
|
46886f2637 | ||
|
|
40804d9120 | ||
|
|
803c99cee2 | ||
|
|
5d16ae8cfe | ||
|
|
ace93b0356 | ||
|
|
14ec619b1e | ||
|
|
b3eee0d7bf | ||
|
|
37e0860b0c | ||
|
|
be57c2752d | ||
|
|
1a3c90e898 | ||
|
|
06482d2378 | ||
|
|
3abdd22031 | ||
|
|
66fca15cc6 | ||
|
|
0c04b77cd7 | ||
|
|
6bb6178ae5 | ||
|
|
4ad92f0261 | ||
|
|
bc8d811f69 | ||
|
|
e8be3f21fa | ||
|
|
31e5f7804e | ||
|
|
9b54aeee22 | ||
|
|
00d8375a2e | ||
|
|
046e0b7888 | ||
|
|
35074f6d9f | ||
|
|
94360e19e0 | ||
|
|
012439aa0b | ||
|
|
931d525874 | ||
|
|
7cfc51315d | ||
|
|
de4b17332d | ||
|
|
6074e84653 | ||
|
|
f575652456 | ||
|
|
2ff582f06f | ||
|
|
de354b901d | ||
|
|
607dc67135 | ||
|
|
d6269bb5d6 | ||
|
|
43df2a05da | ||
|
|
1b4b1c2832 | ||
|
|
18ff5bb410 | ||
|
|
c0313a6d09 | ||
|
|
82a19a2ff1 | ||
|
|
7e8e80db2c | ||
|
|
cdff33b1c2 | ||
|
|
e83838f744 | ||
|
|
b3f7d1881f | ||
|
|
9c62a11316 | ||
|
|
034adb9f1f | ||
|
|
fd1fa0320a | ||
|
|
b95195d8bb | ||
|
|
dcc15f7555 | ||
|
|
0eb978cb0b | ||
|
|
451211cfb1 | ||
|
|
06caa328a4 | ||
|
|
5122d9ac02 | ||
|
|
d201e25006 | ||
|
|
b7bed0d1a5 | ||
|
|
9993c4f2f7 | ||
|
|
5371f94c8f | ||
|
|
39724e239c | ||
|
|
bfc64c451a | ||
|
|
6133399b2e | ||
|
|
c2dde973a6 | ||
|
|
3ea64fbfc3 | ||
|
|
cb80d85dd6 | ||
|
|
dceec711e0 | ||
|
|
67f1ce600f | ||
|
|
d0f84f9460 | ||
|
|
5daf4e5b2b | ||
|
|
80bee99bfc | ||
|
|
882f2010ce | ||
|
|
352507cb1c | ||
|
|
e7a7ab8031 | ||
|
|
bd979cca34 | ||
|
|
ab9f05fb0f | ||
|
|
5c197f176e | ||
|
|
5fef44ec2b | ||
|
|
79b480da4b | ||
|
|
e1ecf55d03 | ||
|
|
c9f21e7ebf | ||
|
|
f7deefb31d | ||
|
|
e2e2227895 | ||
|
|
8810c9e694 | ||
|
|
f7540196d4 | ||
|
|
ccc5a5be5a | ||
|
|
f9e818c900 | ||
|
|
356094fac4 | ||
|
|
7d1a97696b | ||
|
|
af2b221958 | ||
|
|
af9e113112 | ||
|
|
62a2af193c | ||
|
|
4479a6f7e8 | ||
|
|
2d7ab7bdef | ||
|
|
57a27a5d17 | ||
|
|
1d7dee8976 | ||
|
|
9582ea4b55 | ||
|
|
edee5acdbf | ||
|
|
85e7c9cf04 | ||
|
|
b39fd0321e | ||
|
|
5f12459437 | ||
|
|
070b308595 | ||
|
|
e7be12e0ff | ||
|
|
d4cb623d9c | ||
|
|
486b32a7d6 | ||
|
|
179f17d267 | ||
|
|
5d789f75a9 | ||
|
|
2afa76c07c | ||
|
|
260192bcc4 | ||
|
|
c16b22de57 | ||
|
|
79ad8dc4be | ||
|
|
6435c74bfe | ||
|
|
dd8e21e05d | ||
|
|
8924f9c5dc | ||
|
|
981ac69c2c | ||
|
|
1e298dcfa2 | ||
|
|
9cb1e4bbc5 | ||
|
|
3ab5ec218b | ||
|
|
d360420204 | ||
|
|
3fd5cdfb75 | ||
|
|
547da3f3ce | ||
|
|
aeb2804da8 | ||
|
|
cf1997804f | ||
|
|
ae374f134b | ||
|
|
c437375f08 | ||
|
|
955660ba2a | ||
|
|
b2b1977f8b | ||
|
|
350d3cd85f | ||
|
|
bdc8d839ff | ||
|
|
5b6eddabde | ||
|
|
e968fd3ef4 | ||
|
|
380fffb1d9 | ||
|
|
536f001479 | ||
|
|
38044040a6 | ||
|
|
2a1b737470 | ||
|
|
4b118ae660 | ||
|
|
d5b4b25287 | ||
|
|
262d74d1e3 | ||
|
|
6767c2ade2 | ||
|
|
487caab349 | ||
|
|
283274e056 | ||
|
|
1a5220182c | ||
|
|
cd5e4f3055 | ||
|
|
7ea08b87d5 | ||
|
|
a90356f0c9 | ||
|
|
6713fe8bd2 | ||
|
|
62d8a892c6 | ||
|
|
3558640407 | ||
|
|
5222506578 | ||
|
|
89f1e809e6 | ||
|
|
0973f48b2c | ||
|
|
3c7719f6d8 | ||
|
|
63be7c85fc | ||
|
|
78d0d60b9f | ||
|
|
bb94adc846 | ||
|
|
abbf7e4476 | ||
|
|
72e613fe28 | ||
|
|
49977b5475 | ||
|
|
9d8fd364e3 | ||
|
|
50fdc210c9 | ||
|
|
d205683eb5 | ||
|
|
85edc57ba5 | ||
|
|
b5f5623af4 | ||
|
|
e09a872fa2 | ||
|
|
cdbdc36c94 | ||
|
|
8cb923b332 | ||
|
|
ec943198f0 | ||
|
|
4c8af6d6e9 | ||
|
|
d5d00fbd7d | ||
|
|
e887d462ce | ||
|
|
cd6e51a968 | ||
|
|
71f7515775 | ||
|
|
f8a8e55e7e | ||
|
|
cbca362cc4 | ||
|
|
750ad5bd44 | ||
|
|
e03a9b3003 | ||
|
|
d4b4379829 | ||
|
|
5b5b594f4a | ||
|
|
e6f471d88e | ||
|
|
0fd69f22d4 | ||
|
|
cc95ca1cf6 | ||
|
|
4675240d6e | ||
|
|
630b565cd4 | ||
|
|
125d532e95 | ||
|
|
195f6147ad | ||
|
|
cd2c261e2b | ||
|
|
38a83c0cd9 | ||
|
|
a5350c4891 | ||
|
|
f9b7b54454 | ||
|
|
1a71406f84 | ||
|
|
f1ae4002aa | ||
|
|
d4585960fc | ||
|
|
191de5baea | ||
|
|
ef2c68d768 | ||
|
|
a0f74eaee2 | ||
|
|
8a6c0dad00 | ||
|
|
bc2f89e66f | ||
|
|
23602935e1 | ||
|
|
aaefdae794 | ||
|
|
38cdc76790 | ||
|
|
a668ec35ab | ||
|
|
7acaac7a6d | ||
|
|
428d5be129 | ||
|
|
2de553ba02 | ||
|
|
77ae8e108a | ||
|
|
e7b3a7735d | ||
|
|
9b63297a6b | ||
|
|
ae12caff04 | ||
|
|
61098be315 | ||
|
|
727e4fe672 | ||
|
|
fc9c762516 | ||
|
|
35933cafba | ||
|
|
09ced82c9f | ||
|
|
81313c32ee | ||
|
|
8c92ed25e5 | ||
|
|
80ef0e1a75 | ||
|
|
73e15ee93d | ||
|
|
7cd7ce3b41 | ||
|
|
6f4dce52fc | ||
|
|
ae3d651e83 | ||
|
|
0f552b4b65 | ||
|
|
7a52f316f9 | ||
|
|
3cafdf911b | ||
|
|
24a4d91ee8 | ||
|
|
b2fe138dbf | ||
|
|
e8e3649f24 | ||
|
|
c0a7c3a344 | ||
|
|
9c1c88d35e | ||
|
|
c44349511d | ||
|
|
0c8194373f | ||
|
|
c8db45b2a4 | ||
|
|
a0a566140c | ||
|
|
977f8eb262 | ||
|
|
8edd85a9df | ||
|
|
f1f0c39be8 | ||
|
|
cf4db63226 | ||
|
|
d85c1c3bcf | ||
|
|
884d1d7684 | ||
|
|
45fa968076 | ||
|
|
530da08145 | ||
|
|
c272f9538a | ||
|
|
0ee4d6084b | ||
|
|
ebf74e3c98 | ||
|
|
e1290524af | ||
|
|
06ba3cfd73 | ||
|
|
222db70cf6 | ||
|
|
eef47e1681 | ||
|
|
17521e8efb | ||
|
|
d089e95e5a | ||
|
|
e635f35cf1 | ||
|
|
5f54bd13bb | ||
|
|
f27da7c8a5 | ||
|
|
49a41d7e46 | ||
|
|
2863060ded | ||
|
|
75025895b8 | ||
|
|
d6ca37a9e7 | ||
|
|
08f3e6c08e | ||
|
|
dd5e09be37 | ||
|
|
caf165a635 | ||
|
|
15ca0da89e | ||
|
|
3e71b3fe69 | ||
|
|
5839ccbeb5 | ||
|
|
38b8746507 | ||
|
|
99944b1d49 | ||
|
|
1752b55678 | ||
|
|
6fc884b575 | ||
|
|
c8cd745f81 | ||
|
|
c85ff90477 | ||
|
|
0c24786912 | ||
|
|
d647fd7743 | ||
|
|
5eb9bbe283 | ||
|
|
f8b7421b59 | ||
|
|
76ef2c4b0e | ||
|
|
0192cac18a | ||
|
|
ccaf15fc41 | ||
|
|
f50018776f | ||
|
|
c13267599e | ||
|
|
d45b77c0b7 | ||
|
|
479fb6cbca | ||
|
|
95f48b694e | ||
|
|
9da2c1918f | ||
|
|
42c8ed0c0f | ||
|
|
d63f9e736e | ||
|
|
2a8e5be361 | ||
|
|
bf5d2b7f04 | ||
|
|
18c35954f0 | ||
|
|
36d7e58ff2 | ||
|
|
0f8c70bcdf | ||
|
|
248d6f1167 | ||
|
|
35974d55bd | ||
|
|
5548f33e06 | ||
|
|
a909461535 | ||
|
|
698293e2d8 | ||
|
|
22d631d7aa | ||
|
|
be75c7591c | ||
|
|
c21f466573 | ||
|
|
308b1484e0 | ||
|
|
8beea1984e | ||
|
|
cebecc3fc3 | ||
|
|
81c4382349 | ||
|
|
b7f2eb8df9 | ||
|
|
97f956f138 | ||
|
|
6bd9dd55b7 | ||
|
|
6e8913091d | ||
|
|
85f0ab829a | ||
|
|
73004c643c | ||
|
|
ccbc802fe6 | ||
|
|
73378c4d56 | ||
|
|
986db04cb9 | ||
|
|
de32e53868 | ||
|
|
200ec8e5db | ||
|
|
b771aa00e0 | ||
|
|
26b33b12af | ||
|
|
f0ea8ab076 | ||
|
|
abbcc4f8a9 | ||
|
|
8a8f46c325 | ||
|
|
d2813ed70b | ||
|
|
0167687c6b | ||
|
|
ca27dbd2fe | ||
|
|
b862d6bc48 | ||
|
|
5ae2f487b4 | ||
|
|
283c1df00c | ||
|
|
bf2a9db5e4 | ||
|
|
963aea5c0d | ||
|
|
9efd7c14fc | ||
|
|
227f8c4f86 | ||
|
|
be498b4cb7 | ||
|
|
015c442f1c | ||
|
|
be1532b809 | ||
|
|
8333677dc6 | ||
|
|
3bb874825f | ||
|
|
c43bd6cd3f | ||
|
|
5159171bf3 | ||
|
|
c5057eb6b3 | ||
|
|
433e20869c | ||
|
|
0c4a91df8a | ||
|
|
71ae076b44 | ||
|
|
1784a0877f | ||
|
|
09a63bbc5b | ||
|
|
4f1deef971 | ||
|
|
c2b1a9fbd7 | ||
|
|
9d62d04459 | ||
|
|
d02bb9af5d | ||
|
|
f670f71d47 | ||
|
|
b96bc2a240 | ||
|
|
8eda6cbdf0 | ||
|
|
f05eefd80c | ||
|
|
4bfa1c2752 | ||
|
|
961549d375 | ||
|
|
4e3e5872fc | ||
|
|
de7ceb91dd | ||
|
|
d62dcdd29a | ||
|
|
8087774961 | ||
|
|
fad1993a01 | ||
|
|
53513b6632 | ||
|
|
bb4164a05d | ||
|
|
69f3116158 | ||
|
|
e57b722ce2 | ||
|
|
a43eccdac8 | ||
|
|
12a7349165 | ||
|
|
1ef61db73b | ||
|
|
c14e20330f | ||
|
|
299bec15ff | ||
|
|
8e99291e13 | ||
|
|
8701ae6de0 | ||
|
|
d2c406f019 | ||
|
|
d2abc3a237 | ||
|
|
3bc8fc4c11 | ||
|
|
93a3a667c8 | ||
|
|
39e1d45369 | ||
|
|
cc91208057 | ||
|
|
5d54c0e26c | ||
|
|
5fc9f859ce | ||
|
|
4c7b565391 | ||
|
|
f1546c1fca | ||
|
|
b2c012d8bc | ||
|
|
42c60c7154 | ||
|
|
444b511548 | ||
|
|
527cbddb4b | ||
|
|
7fdd212462 | ||
|
|
9f31830f03 | ||
|
|
e4098cb54b | ||
|
|
aa13ea1a80 | ||
|
|
b717910db8 | ||
|
|
16309e6d18 | ||
|
|
a1079761e7 | ||
|
|
6b5990aa04 | ||
|
|
ae08adb8bd | ||
|
|
711184c465 | ||
|
|
b5dec56eaf | ||
|
|
0059a4bc1b | ||
|
|
eb38b9cfab | ||
|
|
459f0b7fa0 | ||
|
|
db3b901063 | ||
|
|
8b055752aa | ||
|
|
dbb9cfa77a | ||
|
|
95e87fed14 | ||
|
|
02fdd677cf | ||
|
|
3b74534567 | ||
|
|
790b0e5cf7 | ||
|
|
5e08da51aa | ||
|
|
0c2287df77 | ||
|
|
b581a62c89 | ||
|
|
c341648a44 | ||
|
|
f903ffb927 | ||
|
|
124543c57d | ||
|
|
829f05e2fb | ||
|
|
d936b2d35a | ||
|
|
84a8e5830e | ||
|
|
eedc68c360 | ||
|
|
0cf37fbbf1 | ||
|
|
5f6dd0846d | ||
|
|
3c15563569 | ||
|
|
1f985ddef0 | ||
|
|
43e144e7b6 | ||
|
|
9c70b7116b | ||
|
|
3c1095be65 | ||
|
|
89f27e84d0 | ||
|
|
f64a5e75d5 | ||
|
|
94178c8cde | ||
|
|
30290c36d7 | ||
|
|
956f07785b | ||
|
|
3e6f14f3bd | ||
|
|
7cb39f02f2 | ||
|
|
c105804572 | ||
|
|
f498cf1b1a | ||
|
|
c0a2efe7e2 | ||
|
|
080d044c99 | ||
|
|
cbf14bfa08 | ||
|
|
110f4a99ee | ||
|
|
63af05ef88 | ||
|
|
0c790005b2 | ||
|
|
3ce6de573d | ||
|
|
67aa4cd28e | ||
|
|
c18f3cd539 | ||
|
|
9e13d5600a | ||
|
|
35d5200a3b | ||
|
|
e0858a9c2a | ||
|
|
b8847fd006 | ||
|
|
714d95cc34 | ||
|
|
5e60a2596c | ||
|
|
f281db8dd0 | ||
|
|
7f09a9e0cb | ||
|
|
fe52060de7 | ||
|
|
d5128ddc18 | ||
|
|
f938e8ce29 | ||
|
|
a0342671ac | ||
|
|
e03da92a90 | ||
|
|
4d5b42ab79 | ||
|
|
b63590bf1d | ||
|
|
cfdee23d33 | ||
|
|
60499e895f | ||
|
|
ddacee6d8b | ||
|
|
ae226cb1a2 | ||
|
|
a7e70ab80b | ||
|
|
e95cabb1fc | ||
|
|
173bd49a26 | ||
|
|
9ae47b79f9 | ||
|
|
15e09cd0a8 | ||
|
|
89a0eb506b | ||
|
|
4632c7650f | ||
|
|
281452434c | ||
|
|
ccdde45323 | ||
|
|
a3e13b8e72 | ||
|
|
35bc2d06a6 | ||
|
|
ee00f81b5b | ||
|
|
974db316ce | ||
|
|
d41c15dbc7 | ||
|
|
41d5e11511 | ||
|
|
c8100e1464 | ||
|
|
b783df397a | ||
|
|
62a64cd156 | ||
|
|
675da6201a | ||
|
|
d447329bf1 | ||
|
|
10b452197d | ||
|
|
973bf93c77 | ||
|
|
c91431410e | ||
|
|
a3bdb027e7 | ||
|
|
502d5e75e8 | ||
|
|
eb4de8e724 | ||
|
|
2060e0b1da | ||
|
|
dfcd7ae1a8 | ||
|
|
c6d893bc98 | ||
|
|
f638add755 | ||
|
|
9f22a2b1f8 | ||
|
|
432b0dc6f6 | ||
|
|
7424a1f463 | ||
|
|
0bf83c0cd6 | ||
|
|
230e6a311d | ||
|
|
26c004eee0 | ||
|
|
1914275fa8 | ||
|
|
055cccd151 | ||
|
|
b6b0b9a984 | ||
|
|
0fc97c28c6 | ||
|
|
11c34d383d | ||
|
|
c68dde70ec | ||
|
|
124d78fefd | ||
|
|
d34a529116 | ||
|
|
4df9ac995a | ||
|
|
4149be47e0 | ||
|
|
b7da3f7a97 | ||
|
|
206c4fe09c | ||
|
|
df7539a48e | ||
|
|
9c91fb8cd8 | ||
|
|
5cdede1482 | ||
|
|
fa174be741 | ||
|
|
5e93803eef | ||
|
|
bb0b12be27 | ||
|
|
41e93ac6f0 | ||
|
|
1df99efa14 | ||
|
|
911b8158a4 | ||
|
|
e875c7d6d1 | ||
|
|
0ddbb28fd2 | ||
|
|
e54234ec50 | ||
|
|
6dd0cd27e1 | ||
|
|
ec50b0c366 | ||
|
|
97b61f885d | ||
|
|
0d7b8f13d8 | ||
|
|
2bf7d87b29 | ||
|
|
8d5d50a198 | ||
|
|
aa743fc397 | ||
|
|
29d16633f5 | ||
|
|
d92debe356 | ||
|
|
52aed1041c | ||
|
|
8fec570c13 | ||
|
|
a39d0840ce | ||
|
|
63cc86bdcd | ||
|
|
637514d00d | ||
|
|
b2db31ff18 | ||
|
|
b044bae304 | ||
|
|
f13e384a1b | ||
|
|
bfce5cceb5 | ||
|
|
344dc165bc | ||
|
|
79c4bd7850 | ||
|
|
a82261a4df | ||
|
|
57a62dbbfd | ||
|
|
cd125ae274 | ||
|
|
d9716590b1 | ||
|
|
2b00b2c1c5 | ||
|
|
b3b0caa038 | ||
|
|
db0e833ce9 | ||
|
|
592b7c66c5 | ||
|
|
34b32f53f6 | ||
|
|
9ade28ee00 | ||
|
|
99acc9a6e7 | ||
|
|
d886c788e7 | ||
|
|
d2f7d8a9c4 | ||
|
|
7143f693d2 | ||
|
|
9cfdc00d64 | ||
|
|
4f6ab68318 | ||
|
|
7c6439e075 | ||
|
|
420fecad51 | ||
|
|
ef017c9e9d | ||
|
|
00412749e7 | ||
|
|
4188da2ef2 | ||
|
|
8d93c275ab | ||
|
|
b0b3b491a0 | ||
|
|
dd59d3c713 | ||
|
|
548f0b6130 | ||
|
|
f7e007018f | ||
|
|
436e82653c | ||
|
|
ecf598e412 | ||
|
|
257fe20c4f | ||
|
|
ba011169b8 | ||
|
|
ffe50dad22 | ||
|
|
dc289ba635 | ||
|
|
10724fac3b | ||
|
|
4969ece356 | ||
|
|
2fad881202 | ||
|
|
39b363d0b5 | ||
|
|
215eff3212 | ||
|
|
e1a0fc42ea | ||
|
|
69d28db660 | ||
|
|
c3ab04b436 | ||
|
|
918281a804 | ||
|
|
297cf3f51e | ||
|
|
93e1d732c9 | ||
|
|
1bfde1f9f0 | ||
|
|
489ab86ac7 | ||
|
|
e8f7746c87 | ||
|
|
db1139e89e | ||
|
|
5c04ce257b | ||
|
|
6cdb2a48fd | ||
|
|
37cbf79b4c | ||
|
|
00559ce8d6 | ||
|
|
07244a8a73 | ||
|
|
d181bedbfc | ||
|
|
077b3ab59e | ||
|
|
edbed67afe | ||
|
|
a947f8c783 | ||
|
|
6e131dcd7e | ||
|
|
d24097f73d | ||
|
|
bfb3a58c01 | ||
|
|
02a64a7fa3 | ||
|
|
3dfe1ccb1a | ||
|
|
c6e5f1c9f8 | ||
|
|
4c0a612ab5 | ||
|
|
09cae9cbd3 | ||
|
|
1595405871 | ||
|
|
1c8c233ebf | ||
|
|
c2d0628da1 | ||
|
|
2e58fa3c2f | ||
|
|
fced2c521c | ||
|
|
e7ceacc215 | ||
|
|
a320eb5d8e | ||
|
|
42199eefd2 | ||
|
|
56df87e60c | ||
|
|
90ed9cd15c | ||
|
|
8ca3bca810 | ||
|
|
5d2912baa1 | ||
|
|
129ec29af5 | ||
|
|
70991cf173 | ||
|
|
61199eff9c | ||
|
|
4991d3dbab | ||
|
|
3405e8b8e1 | ||
|
|
977d21eed5 | ||
|
|
09e0d0b9d8 | ||
|
|
79c38d66cb | ||
|
|
d7871fec2b | ||
|
|
9f80f4ac42 | ||
|
|
d6058768fc | ||
|
|
6a50b3f149 | ||
|
|
35045aa9d7 | ||
|
|
398ca1f8e4 | ||
|
|
7091406abc | ||
|
|
c21d478f5d | ||
|
|
f973fc3743 | ||
|
|
d776092b35 | ||
|
|
775b80eff5 | ||
|
|
ff135322f6 | ||
|
|
dafaac412f | ||
|
|
4452e637ad | ||
|
|
821c1c938e | ||
|
|
1df95702a3 | ||
|
|
274e7c579e | ||
|
|
b820e98bdc | ||
|
|
10c5cb3721 | ||
|
|
cc7db6190f | ||
|
|
9a9d81ca18 | ||
|
|
71d9816f4b | ||
|
|
8cdd138143 | ||
|
|
7dabfdc207 | ||
|
|
65e82eb37e | ||
|
|
8a14e6ccb4 | ||
|
|
5dadcf3862 | ||
|
|
c001ff763a | ||
|
|
3c59b601b5 | ||
|
|
4cb0d23136 | ||
|
|
2fd29c4b78 | ||
|
|
c0344a56ff | ||
|
|
16692d47b2 | ||
|
|
204b3e1159 | ||
|
|
41d4ee20b0 | ||
|
|
4d17f3c2ff | ||
|
|
353fe177f4 | ||
|
|
4dc4239963 | ||
|
|
0a72cab089 | ||
|
|
57202b3ea0 | ||
|
|
69e7006cc8 | ||
|
|
7ee8652cc3 | ||
|
|
8f1331dab3 | ||
|
|
2998a54713 | ||
|
|
ccba8e155e | ||
|
|
e9317dc2c7 | ||
|
|
77f88e5cac | ||
|
|
43649328cb | ||
|
|
3629c8c493 | ||
|
|
426a2f983c | ||
|
|
85273b9ed7 | ||
|
|
461dba87db | ||
|
|
d4982a8f24 | ||
|
|
de5f3657ab | ||
|
|
7a2ddd3905 | ||
|
|
d5200f859d | ||
|
|
6cee1d9ee6 | ||
|
|
6b9d4fe7c5 | ||
|
|
303f315b3e | ||
|
|
b6f41eecfd | ||
|
|
c880366aaf | ||
|
|
e40a7d6681 | ||
|
|
b3149a2b55 | ||
|
|
37a9712532 | ||
|
|
bcf65d4cae | ||
|
|
521126c982 | ||
|
|
e2aea92e3b | ||
|
|
e595f564b1 | ||
|
|
bfbabc62c4 | ||
|
|
d4248385f0 | ||
|
|
ab0aad87ec | ||
|
|
5ac5ff638e | ||
|
|
ed80acd87f | ||
|
|
fa27757719 | ||
|
|
c02cc6d193 | ||
|
|
312f6515ff | ||
|
|
f6315e48d0 | ||
|
|
8b3cff9f4c | ||
|
|
400952b327 | ||
|
|
007d23308a | ||
|
|
66e79e23cb | ||
|
|
4de2ed767b | ||
|
|
49f9a1e8d7 | ||
|
|
9a09db9212 | ||
|
|
1aad6d0517 | ||
|
|
d927f1886c | ||
|
|
0b8ff7cc01 | ||
|
|
c4ae4919a5 | ||
|
|
83e7f06500 | ||
|
|
9abd925ab7 | ||
|
|
7e0c17c5aa | ||
|
|
6da7788f61 | ||
|
|
b187409e59 | ||
|
|
079be0e072 | ||
|
|
81c8e1b192 | ||
|
|
1220eab47a | ||
|
|
44d1877892 | ||
|
|
11f8fda585 | ||
|
|
81fe104f1b | ||
|
|
feab6211d4 | ||
|
|
9691a4f361 | ||
|
|
8759fda632 | ||
|
|
74ee322312 | ||
|
|
ef4aff7d34 | ||
|
|
bfc393a090 | ||
|
|
114490f01e | ||
|
|
ad38632fc1 | ||
|
|
b737df9c40 | ||
|
|
fd18c0b2e9 | ||
|
|
cf6478b633 | ||
|
|
a70996f079 | ||
|
|
2aa56c8d49 | ||
|
|
b2fb7d5d5b | ||
|
|
16ffcc7684 | ||
|
|
16c428e360 | ||
|
|
77bdff1e4b | ||
|
|
1ae15911fc | ||
|
|
aca005c287 | ||
|
|
68fb5d7252 | ||
|
|
380fc2cbde | ||
|
|
39283a5526 | ||
|
|
3e38e467a2 | ||
|
|
4f55b56d6b | ||
|
|
54c0b3e196 | ||
|
|
9eac47f7e8 | ||
|
|
7ec58c63e9 | ||
|
|
b70ffb6331 | ||
|
|
423b47a5ff | ||
|
|
52a4e8964f | ||
|
|
964a052be1 | ||
|
|
15a14e86ba | ||
|
|
eca0c72063 | ||
|
|
2353c98919 | ||
|
|
30e5a1a7aa | ||
|
|
d94db237a9 | ||
|
|
317aa3b6ed | ||
|
|
268c92a1af | ||
|
|
bc2c998b7c | ||
|
|
73c05d2d9d | ||
|
|
f7872d346b | ||
|
|
d0d387a42f | ||
|
|
84af88ee40 | ||
|
|
aa4f7571b9 | ||
|
|
b5b96a3edb | ||
|
|
1e335e53ba | ||
|
|
75854fc026 | ||
|
|
d8a6ed4ba6 | ||
|
|
459bbda60c | ||
|
|
2a9508b4e3 | ||
|
|
c0c288e0d9 | ||
|
|
82fd5b36a8 | ||
|
|
dd3c7d8fa4 | ||
|
|
b63f073d90 | ||
|
|
0491125e92 | ||
|
|
3443c3b8ea | ||
|
|
be720be74a | ||
|
|
f3e491f15b | ||
|
|
5855198b5f | ||
|
|
62de6fcdae | ||
|
|
57dc0cd53e | ||
|
|
0a1694dd78 | ||
|
|
edc690973a | ||
|
|
48148a9e26 | ||
|
|
62b9911176 | ||
|
|
fb69a37445 | ||
|
|
81ae1eae51 | ||
|
|
517c70d855 | ||
|
|
85f7c1e73c | ||
|
|
b4cfa0e844 | ||
|
|
3c758ab2f6 | ||
|
|
1ed01b8d3d | ||
|
|
19abbe0dbd | ||
|
|
c833af1ae6 | ||
|
|
78bdd4a087 | ||
|
|
dc77bb4332 | ||
|
|
9e011d6ad9 | ||
|
|
f9ed36ed54 | ||
|
|
495681770e | ||
|
|
eb1f0e0a8a | ||
|
|
23ae5caa3c | ||
|
|
4b7d558026 | ||
|
|
44969a7fdf | ||
|
|
5f5c74f260 | ||
|
|
5646751f88 | ||
|
|
b6d3e785df | ||
|
|
ebada30984 | ||
|
|
64fc9f203e | ||
|
|
653d4fef4b | ||
|
|
5cc04b58a4 | ||
|
|
f628da7a91 | ||
|
|
a8853bdee6 | ||
|
|
5f8ffa7afc | ||
|
|
d74f4f64f7 | ||
|
|
3e7929bed6 | ||
|
|
7a2d1c29f0 | ||
|
|
0a841f17a4 | ||
|
|
ee8d48a915 | ||
|
|
539d500528 | ||
|
|
3d1de43ff1 | ||
|
|
e7998acf66 | ||
|
|
e0640418e4 | ||
|
|
52a6cc5bad | ||
|
|
8787ecceb8 | ||
|
|
a1f2f95d1b | ||
|
|
c3aeae5ed7 | ||
|
|
29ff2c5d0a | ||
|
|
a7880dc3b0 | ||
|
|
ba4437edee | ||
|
|
811afa1171 | ||
|
|
29a48aba66 | ||
|
|
c00119989e | ||
|
|
bbaac8b2b1 | ||
|
|
9554597948 | ||
|
|
774afe9fdd | ||
|
|
fa2199c3ea | ||
|
|
e321e1bb2c | ||
|
|
dfc425a7c5 | ||
|
|
4ac422314d | ||
|
|
ff6e42fa6d | ||
|
|
7a0a82bcb4 | ||
|
|
fa95ede3e9 | ||
|
|
26147c97cf | ||
|
|
c4ca6a0bac | ||
|
|
8de694b2d7 | ||
|
|
de797b644e | ||
|
|
c8357be4d0 | ||
|
|
657f0314e4 | ||
|
|
4f26e34717 | ||
|
|
133ed68152 | ||
|
|
e2c5b87a7e | ||
|
|
21e716b08a | ||
|
|
f6e21bd6c8 | ||
|
|
4ffbc0fb58 | ||
|
|
6d6c5e2e17 | ||
|
|
d795bea543 | ||
|
|
10c23e60b7 | ||
|
|
6f9ac4b88b | ||
|
|
f92025e120 | ||
|
|
392ae832b8 | ||
|
|
87a5f69335 | ||
|
|
c8e1060ea4 | ||
|
|
e361abcecd | ||
|
|
e8af8f7792 | ||
|
|
2e906f9b8a | ||
|
|
385b7e3389 | ||
|
|
48ba55d02c | ||
|
|
5223629ab1 | ||
|
|
a2a8638f28 | ||
|
|
58e6424bf7 | ||
|
|
d2255adc4e | ||
|
|
7f8ca64f64 | ||
|
|
104c1e6945 | ||
|
|
414e3555a5 | ||
|
|
c63b45dbf3 | ||
|
|
197bb2179f | ||
|
|
62fdb8d0af | ||
|
|
98184c31de | ||
|
|
ee04ad500a | ||
|
|
df40b0b8d3 | ||
|
|
8eab31c469 | ||
|
|
474011033b | ||
|
|
5893e42a8d | ||
|
|
9d18f7b15f | ||
|
|
b0c22e7a3a | ||
|
|
9ab78acf09 | ||
|
|
aa6499e7e4 | ||
|
|
fffd3592d3 | ||
|
|
842da98e61 | ||
|
|
eadeb3841b | ||
|
|
b25379c243 | ||
|
|
4d025568dc | ||
|
|
c3ec7fbbe4 | ||
|
|
14baca125d | ||
|
|
1ea94c0356 | ||
|
|
57dbece417 | ||
|
|
f023adff4b | ||
|
|
6a2fe47b22 | ||
|
|
461d167547 | ||
|
|
13425e1ad4 | ||
|
|
c7deb5ed33 | ||
|
|
27313bc3d6 | ||
|
|
6e1dbbcf4f | ||
|
|
4e3216a75d | ||
|
|
51c353e504 | ||
|
|
1b71a96a3d | ||
|
|
a0a7237c01 | ||
|
|
af576ea0c4 | ||
|
|
183c6abc98 | ||
|
|
559e65a4e1 | ||
|
|
b93ca148a8 | ||
|
|
07d6763e69 | ||
|
|
bc2da10713 | ||
|
|
2e515f5fc7 | ||
|
|
a274f3cf01 | ||
|
|
c068c3c33a | ||
|
|
e258a7cf64 | ||
|
|
5814724600 | ||
|
|
220a454859 | ||
|
|
42fb02c36f | ||
|
|
732223e832 | ||
|
|
286ab7a600 | ||
|
|
b402ce1564 | ||
|
|
0ccba3281e | ||
|
|
6f148c47e2 | ||
|
|
98a96a897b | ||
|
|
f1d96a30a4 | ||
|
|
2509a842f0 | ||
|
|
b7dbf27931 | ||
|
|
6bfce63060 | ||
|
|
6ca3b8246a | ||
|
|
1d8952867d | ||
|
|
e415dd8504 | ||
|
|
aa37ac6038 | ||
|
|
d68eeada0e | ||
|
|
accbe5a423 | ||
|
|
f33b838204 | ||
|
|
767b29d5a3 | ||
|
|
a928a0b404 | ||
|
|
2574f3a8ee | ||
|
|
622352b411 | ||
|
|
900de0a5c9 | ||
|
|
def90355a9 | ||
|
|
a3f1e04a4d | ||
|
|
39286deb19 | ||
|
|
504bffa57a | ||
|
|
d89c43befa | ||
|
|
d95818f1b2 | ||
|
|
9b0faaac34 | ||
|
|
eaafe91ade | ||
|
|
f84bfd8384 | ||
|
|
79709f3f06 | ||
|
|
ce6edf893a | ||
|
|
5d5d602f1d | ||
|
|
ad3aa30471 | ||
|
|
69d174309d | ||
|
|
5b08a69607 | ||
|
|
1bd9d41164 | ||
|
|
ef7bf87187 | ||
|
|
d21ae76fff | ||
|
|
c12980ee91 | ||
|
|
719416741f | ||
|
|
1b14263bb8 | ||
|
|
5c8da20eea | ||
|
|
560fcdc541 | ||
|
|
d1e9525052 | ||
|
|
9f65ef199b | ||
|
|
fed9d4ef3b | ||
|
|
867e8727c1 | ||
|
|
d927b82020 | ||
|
|
e003fb8d35 | ||
|
|
4db957f437 | ||
|
|
46ec0b8f70 | ||
|
|
d1aa8bf5ae | ||
|
|
3cf8ea63d8 | ||
|
|
fd55828c42 | ||
|
|
1ce4db5604 | ||
|
|
300e37124c | ||
|
|
9b3b7b09a0 | ||
|
|
17121d5861 | ||
|
|
c9f6dabfc6 | ||
|
|
b76952f016 | ||
|
|
6c9572714f | ||
|
|
2565239a1b | ||
|
|
8ab609471a | ||
|
|
3cf21a7e7f | ||
|
|
b0170d1f6f | ||
|
|
45ca3500c6 | ||
|
|
526fdb495b | ||
|
|
8de6cb1ca0 | ||
|
|
a1c036a7e2 | ||
|
|
a9b03bb39e | ||
|
|
595ac49552 | ||
|
|
af1cdadabd | ||
|
|
1be0d52051 | ||
|
|
0d0577a886 | ||
|
|
e4629cc740 | ||
|
|
1c555f321b | ||
|
|
5e9c4fde95 | ||
|
|
6aecebcf2c | ||
|
|
9a2c9f607f | ||
|
|
3a9b725c0c | ||
|
|
f7616f6e94 | ||
|
|
ce8bd9ac40 | ||
|
|
5c44082c42 | ||
|
|
585f0c54bf | ||
|
|
31453d187d | ||
|
|
53ff5b56e6 | ||
|
|
a1ceff8ce8 | ||
|
|
bfb9feaf07 | ||
|
|
8e0e04eae9 | ||
|
|
0f96bf7709 | ||
|
|
f61569622a | ||
|
|
31d8ae08c8 | ||
|
|
4e324e34d8 | ||
|
|
7b5761106d | ||
|
|
819db9538f | ||
|
|
e3b3a08f5f | ||
|
|
e3d9ad005e | ||
|
|
bcacf2fe74 | ||
|
|
b3a6650a6f | ||
|
|
534efcb987 | ||
|
|
79a211ad02 | ||
|
|
b4a0fe54cd | ||
|
|
3a73414972 | ||
|
|
66ee792e8c | ||
|
|
496319a2b0 | ||
|
|
0a98df922e | ||
|
|
4c7d46c8a0 | ||
|
|
a011a6af64 | ||
|
|
2b8f40e505 | ||
|
|
8f797e81ae | ||
|
|
f8ec338fa3 | ||
|
|
ea5f0fadb8 | ||
|
|
bf01a1d138 | ||
|
|
32c051320c | ||
|
|
74ae1429a1 | ||
|
|
00c93abd1b | ||
|
|
7fa559247d | ||
|
|
8895173a2b | ||
|
|
f20cb6ff52 | ||
|
|
4b12fb3a9a | ||
|
|
716337b71a | ||
|
|
dfb965cfa9 | ||
|
|
91f78b54d8 | ||
|
|
ac1c5f81ae | ||
|
|
6abed48af6 | ||
|
|
6550a52cee | ||
|
|
cd62e67011 | ||
|
|
e5524ddc1d | ||
|
|
3c17049084 | ||
|
|
d2287ab9f4 | ||
|
|
a5f4468c54 | ||
|
|
f2dbfa9b33 | ||
|
|
d0dddaf7cc | ||
|
|
40d0be5828 | ||
|
|
d879491a58 | ||
|
|
4d585cbb11 | ||
|
|
2f6d7f81cc | ||
|
|
3363772ce5 | ||
|
|
1910cef3d1 | ||
|
|
121446d648 | ||
|
|
693f623e5e | ||
|
|
da1cac1e55 | ||
|
|
22089a9e45 | ||
|
|
e65db3cba5 | ||
|
|
5b183d9105 | ||
|
|
2a43a95ddd | ||
|
|
23bb5d5147 | ||
|
|
639896b309 | ||
|
|
3d5699ef4a | ||
|
|
1c41882bf0 | ||
|
|
14908e3a11 | ||
|
|
4c559a3191 | ||
|
|
0802f9158c | ||
|
|
ceb5c38ca3 | ||
|
|
f0d36e71a1 | ||
|
|
e809b30cb9 | ||
|
|
e5db40e4ae | ||
|
|
43ff7e4b3e | ||
|
|
a3afc249ef | ||
|
|
ed83d90603 | ||
|
|
daf0a9c6e8 | ||
|
|
4271fb37e9 | ||
|
|
8560baca87 | ||
|
|
d73394abd8 | ||
|
|
f6cca3313a | ||
|
|
76edd53e40 | ||
|
|
cb31a717cf | ||
|
|
b9b3dcb5e3 | ||
|
|
acf55e0c9b | ||
|
|
c40456a2ec | ||
|
|
6d9f1828c6 | ||
|
|
9276607920 | ||
|
|
9fbd02b06d | ||
|
|
4885a9e65a | ||
|
|
98851ed686 | ||
|
|
edcd92fbb7 | ||
|
|
fdcfb3eb7c | ||
|
|
55ff45064f | ||
|
|
f88eadd312 | ||
|
|
874e9dafc2 | ||
|
|
d6b334ab02 | ||
|
|
efbee6796f | ||
|
|
cdeba51ccd | ||
|
|
7fd3d9f331 | ||
|
|
c8d5a446ea | ||
|
|
fe19d277ac | ||
|
|
a7971373a6 | ||
|
|
70dbac10c7 | ||
|
|
82b352d519 | ||
|
|
421926f7ac | ||
|
|
53d555dceb | ||
|
|
043e288d70 | ||
|
|
8718bb4ff1 | ||
|
|
0a06648c02 | ||
|
|
276992d654 | ||
|
|
f07bb17442 | ||
|
|
2529952982 | ||
|
|
e3c290269b | ||
|
|
4bcb31e532 | ||
|
|
768c864766 | ||
|
|
20a5d80647 | ||
|
|
a09aebeca4 | ||
|
|
9e0b45e27a | ||
|
|
9123889876 | ||
|
|
d06abbbd91 | ||
|
|
8f90d25468 | ||
|
|
69219eb340 | ||
|
|
185f03985e | ||
|
|
d102c43f9a | ||
|
|
063e019653 | ||
|
|
49cb35175f | ||
|
|
5d1ea43b9e | ||
|
|
a1c3a60f87 | ||
|
|
60c406d6ec | ||
|
|
7b2bf9ac13 | ||
|
|
856b83ac53 | ||
|
|
4017db1d15 | ||
|
|
5a24bcfe51 | ||
|
|
73268c2af2 | ||
|
|
bcc6354c04 | ||
|
|
1853cfde9b | ||
|
|
07ff1a7717 | ||
|
|
0ce6ef8d8d | ||
|
|
e13454fe3f | ||
|
|
94c25e2017 | ||
|
|
b09c97169a | ||
|
|
37192422be | ||
|
|
9e7b905c0b | ||
|
|
33501fdb0f | ||
|
|
6f00cba872 | ||
|
|
29f4734ec6 | ||
|
|
b17e0dc26d | ||
|
|
403bfc2b44 | ||
|
|
4d6cfbba20 | ||
|
|
a1593a69a4 | ||
|
|
8c05ae332c | ||
|
|
7f0c49b14d | ||
|
|
b7fae1a65b | ||
|
|
a4dd47374e | ||
|
|
4062b960c7 | ||
|
|
44bf3d40ad | ||
|
|
5f85c2a7a0 | ||
|
|
3530da935b | ||
|
|
a0972158dc | ||
|
|
3434b95d68 | ||
|
|
861cc437f4 | ||
|
|
2b2dc2be39 | ||
|
|
acb700bd27 | ||
|
|
e5977d6157 | ||
|
|
44caa12fa5 | ||
|
|
26c7078923 | ||
|
|
94a4fb4579 | ||
|
|
d6f9f29835 | ||
|
|
2eb2362da8 | ||
|
|
53c3981651 | ||
|
|
d252b1fb13 | ||
|
|
d3173d8533 | ||
|
|
4a072b3dfc | ||
|
|
ce1acd9d44 | ||
|
|
ff4300d525 | ||
|
|
3b25fef852 | ||
|
|
91da92346d | ||
|
|
7f2c118f8d | ||
|
|
0848b03127 | ||
|
|
e5074afdeb | ||
|
|
4bd9e4f847 | ||
|
|
717e82c09e | ||
|
|
d069dedf34 | ||
|
|
dd2f89628e | ||
|
|
87b9f30dce | ||
|
|
76298e86be | ||
|
|
aaef1ac997 | ||
|
|
794ee2f562 | ||
|
|
546c66ea3c | ||
|
|
7a4de966d4 | ||
|
|
c404234635 | ||
|
|
6fe7d5a856 | ||
|
|
2fb71445da | ||
|
|
79b51311bc | ||
|
|
fe6eb01404 | ||
|
|
5542918b04 | ||
|
|
e93ef025a1 | ||
|
|
8d31b6140d | ||
|
|
4e027a6515 | ||
|
|
797f1f0f1c | ||
|
|
4d8200fef3 | ||
|
|
edee909324 | ||
|
|
48f54cf2f2 | ||
|
|
c8cb961108 | ||
|
|
013eba1d58 | ||
|
|
af02e02978 | ||
|
|
b947bde3db | ||
|
|
34b8fdfe6d | ||
|
|
47e7b621ad | ||
|
|
52c7395578 | ||
|
|
fb527e5df4 | ||
|
|
7161756cc9 | ||
|
|
f180beb3f9 | ||
|
|
a302a6334d | ||
|
|
18b1931e7c | ||
|
|
ae7436a41b | ||
|
|
a0d76eabe5 | ||
|
|
5557701f44 | ||
|
|
0ccb69bc06 | ||
|
|
0152941ecf | ||
|
|
28462bb2b5 | ||
|
|
a824b24058 | ||
|
|
6ef9034a67 | ||
|
|
93f1ae501c | ||
|
|
d9b3eafc39 | ||
|
|
5dd42cf925 | ||
|
|
e4c4c8c468 | ||
|
|
72a76f6c80 | ||
|
|
071670e24c | ||
|
|
c25c1db3da | ||
|
|
c0cc57d1d8 | ||
|
|
33dab87765 | ||
|
|
9d09c509ab | ||
|
|
dbb29c7661 | ||
|
|
1a1cf5f672 | ||
|
|
759c917498 | ||
|
|
d7b1d617ea | ||
|
|
1e47271c91 | ||
|
|
1dca6116be | ||
|
|
ff59274c95 | ||
|
|
ca6cd19fb1 | ||
|
|
be61eefdf9 | ||
|
|
cf2bb6b599 | ||
|
|
d739d04232 | ||
|
|
711ff2692c | ||
|
|
705f4337e4 | ||
|
|
237ab2be45 | ||
|
|
536136af77 | ||
|
|
d4e5cfb548 | ||
|
|
b5e5e9508c | ||
|
|
f161609a24 | ||
|
|
b4b7b6f455 | ||
|
|
c24079884d | ||
|
|
38c3e3600d | ||
|
|
09795678ef | ||
|
|
b3207d6402 | ||
|
|
c6439cb1b7 | ||
|
|
61f6e5ff79 | ||
|
|
4cd8705710 | ||
|
|
c8cd2545d3 | ||
|
|
6f310ff63a | ||
|
|
20862f07bc | ||
|
|
1365eaca3a | ||
|
|
9dfc7801a0 | ||
|
|
02d4ca5c8b | ||
|
|
c2a7b2f13a | ||
|
|
4115bc416e | ||
|
|
060a3fd47e | ||
|
|
84726fa45c | ||
|
|
3609c961ea | ||
|
|
756e176878 | ||
|
|
1398b71b60 | ||
|
|
f69ca56179 | ||
|
|
a310b5e864 | ||
|
|
517bfa5272 | ||
|
|
ca95c9de97 | ||
|
|
37c269bc0b | ||
|
|
e90c97f8a4 | ||
|
|
af6e17fce8 | ||
|
|
b86352bfc0 | ||
|
|
f03a1b50ef | ||
|
|
70da8d26c0 | ||
|
|
333c7433e8 | ||
|
|
f2d48cb894 | ||
|
|
22766e958f | ||
|
|
42c3186a53 | ||
|
|
530919c531 | ||
|
|
0ec39e3c77 | ||
|
|
cdddb1209e | ||
|
|
62db5370aa | ||
|
|
ab991c2a7d | ||
|
|
d03b54d95a | ||
|
|
62a982ef9f | ||
|
|
798c3cb373 | ||
|
|
7f55e2c9bb | ||
|
|
8e76de7d34 | ||
|
|
ac284ab067 | ||
|
|
95f9304f4f | ||
|
|
7b733686cb | ||
|
|
bdafb9a3f1 | ||
|
|
abd376a44c | ||
|
|
38a7993a9b | ||
|
|
3edb133727 | ||
|
|
84dd258777 | ||
|
|
543b8df045 | ||
|
|
cb7c76889d | ||
|
|
9f296c67b2 | ||
|
|
4a3f490814 | ||
|
|
cbf348fafa | ||
|
|
e205883de5 | ||
|
|
ce04336648 | ||
|
|
a8bf7e5d5f | ||
|
|
69e1973544 | ||
|
|
2f817568e2 | ||
|
|
d9611f784c | ||
|
|
9430bcbf2e | ||
|
|
a6f7062f92 | ||
|
|
e234717129 | ||
|
|
6f1f490370 | ||
|
|
b2bb421063 | ||
|
|
be13a9b967 | ||
|
|
0fa41d317a | ||
|
|
a4d36e0212 | ||
|
|
30fecd412c | ||
|
|
0d61c12dcd | ||
|
|
7f2a899c6f | ||
|
|
0bbb773e95 | ||
|
|
7aa9c92971 | ||
|
|
904f4bb4d8 | ||
|
|
09696195f4 | ||
|
|
971c96f566 | ||
|
|
4fdaa2b708 | ||
|
|
9f6af75f79 | ||
|
|
b29ce28877 | ||
|
|
ff7406a755 | ||
|
|
a8be08a19a | ||
|
|
1ecaae364c | ||
|
|
2637f74094 | ||
|
|
02d944aa67 | ||
|
|
a6bad6d2a5 | ||
|
|
0ae131108d | ||
|
|
2db6b2ceef | ||
|
|
f19c058634 | ||
|
|
ceb4acd749 | ||
|
|
dde0e26110 | ||
|
|
1fbcc2319a | ||
|
|
c7670c505d | ||
|
|
80c84a66fe | ||
|
|
5e4111d67e | ||
|
|
c8ed731809 | ||
|
|
22577bdf71 | ||
|
|
622dfb370d | ||
|
|
ad0afc58c0 | ||
|
|
7c8583f025 | ||
|
|
74d0bfa1bb | ||
|
|
e1866d38af | ||
|
|
b8c2cd9f94 | ||
|
|
d2882a88f3 | ||
|
|
7230474f98 | ||
|
|
b2c36742ee | ||
|
|
427f44dca3 | ||
|
|
fc7659888c | ||
|
|
f81734a8e5 | ||
|
|
d92c3d224c | ||
|
|
70fd054f67 | ||
|
|
5a3c7c7a24 | ||
|
|
1091960282 | ||
|
|
a78587e505 | ||
|
|
f408ef8922 | ||
|
|
8e1fc0df56 | ||
|
|
4cc1c66f09 | ||
|
|
8bb5f0d905 | ||
|
|
d5b385ec69 | ||
|
|
7c0db617cf | ||
|
|
809f5dd4df | ||
|
|
9339b86633 | ||
|
|
fc76e5b8f3 | ||
|
|
f511896c43 | ||
|
|
b53b861342 | ||
|
|
684e9fb8b9 | ||
|
|
f185a4d739 | ||
|
|
29dd529762 | ||
|
|
72fc714cb4 | ||
|
|
656431a03f | ||
|
|
cc9c9d552c | ||
|
|
ab35106359 | ||
|
|
dece54ca3e | ||
|
|
0b3da6b246 | ||
|
|
d5553db9eb | ||
|
|
748360aac7 | ||
|
|
0bb82af91c | ||
|
|
9270fc9ca9 | ||
|
|
d2ebdea96d | ||
|
|
000a2727ef | ||
|
|
e3a44bbb08 | ||
|
|
af405e69b1 | ||
|
|
ff32f54aa8 | ||
|
|
5d9522c901 | ||
|
|
30e52b785a | ||
|
|
d489cd48e9 | ||
|
|
30777b630a | ||
|
|
8030d89634 | ||
|
|
18759e7197 | ||
|
|
d74cb1b232 | ||
|
|
cee3a77a4c | ||
|
|
1120a74b13 | ||
|
|
6a787670a1 | ||
|
|
a01fb82f51 | ||
|
|
c43fd6a2a7 | ||
|
|
9385aa2332 | ||
|
|
bc78f789eb | ||
|
|
1b4539a0df | ||
|
|
3f48b39ccb | ||
|
|
36d199a2b3 | ||
|
|
bff0c1cb84 | ||
|
|
280cb28030 | ||
|
|
79b1d601e8 | ||
|
|
d6eb923bef | ||
|
|
5c92025742 | ||
|
|
04df6ba41c | ||
|
|
be559c181a | ||
|
|
e0860dd83c | ||
|
|
47da9014ae | ||
|
|
a2e6811645 | ||
|
|
6c15cb8b25 | ||
|
|
3cb3524aa2 | ||
|
|
152d47e62a | ||
|
|
48644a17f0 | ||
|
|
56bf2b788f | ||
|
|
0ae17ff17d | ||
|
|
33525b292f | ||
|
|
dcc98eebb5 | ||
|
|
5f7dfb943c | ||
|
|
cee9c65b06 | ||
|
|
609cc3dc59 | ||
|
|
0f477d6853 | ||
|
|
49b5514319 | ||
|
|
b634b34a65 | ||
|
|
2a83bc7f07 | ||
|
|
c4ee125f73 | ||
|
|
e5c500fad0 | ||
|
|
62c8be40b9 | ||
|
|
e0b25aac8f | ||
|
|
3ff4b4c439 | ||
|
|
7a1cf84b08 | ||
|
|
eefd557ab4 | ||
|
|
bcd96a97a3 | ||
|
|
6a84ed6bd1 | ||
|
|
264146d8b3 | ||
|
|
b6fb947310 | ||
|
|
a89b8cb4fe | ||
|
|
1f999c4d28 | ||
|
|
e6e9c61c38 | ||
|
|
6d06b66496 | ||
|
|
a8d1b91083 | ||
|
|
172e9857c7 | ||
|
|
061211b1b6 | ||
|
|
9e446aab7a | ||
|
|
af37b4b746 | ||
|
|
d7ef170d33 | ||
|
|
ccc4b4a6c2 | ||
|
|
0d68f74d80 | ||
|
|
081be68616 | ||
|
|
9b16d93481 | ||
|
|
d5538ee99d | ||
|
|
e999885f33 | ||
|
|
62c7be9f35 | ||
|
|
04d153df59 | ||
|
|
829b52db7c | ||
|
|
6b8ab84ba0 | ||
|
|
c1c62b0738 | ||
|
|
b09429c5d8 | ||
|
|
0a913a9cd4 | ||
|
|
c6a46a7238 | ||
|
|
8dc01c491b | ||
|
|
c20bebd3f0 | ||
|
|
874816b679 | ||
|
|
c367fe915e | ||
|
|
eb21280f04 | ||
|
|
d162fcf34e | ||
|
|
95d21a55f1 | ||
|
|
7bfd76e747 | ||
|
|
72e66605e4 | ||
|
|
89ee7c9664 | ||
|
|
35b722ba08 | ||
|
|
2d6965aa4b | ||
|
|
444879ffc6 | ||
|
|
1010f6acff | ||
|
|
2ae1b84f85 | ||
|
|
6cc511cb80 | ||
|
|
dc2746a365 | ||
|
|
f68203f529 | ||
|
|
2429910188 | ||
|
|
78f47ac619 | ||
|
|
3293906677 | ||
|
|
136867253d | ||
|
|
f6924ba48b | ||
|
|
90525b75a9 | ||
|
|
6928f09c87 | ||
|
|
b505b4519a | ||
|
|
9a0a1fbcbe | ||
|
|
f10c415e48 | ||
|
|
a7387d51de | ||
|
|
c1a5fecbc2 | ||
|
|
f39646567a | ||
|
|
5136b38111 | ||
|
|
42e1590abe | ||
|
|
94adc6fa1b | ||
|
|
182fe5f1d2 | ||
|
|
75f85f6b2a | ||
|
|
e7565db5d0 | ||
|
|
b8c9f32fd8 | ||
|
|
78b37a4b0d | ||
|
|
6d399b6fb9 | ||
|
|
923ba78bfa | ||
|
|
28d9bbb85d | ||
|
|
1c66ad1db2 | ||
|
|
c064e373e9 | ||
|
|
703b7181d9 | ||
|
|
389d29ebf5 | ||
|
|
2108f449b3 | ||
|
|
1b2f1baf3d | ||
|
|
97dd9bb7d5 | ||
|
|
bf2bd3fe50 | ||
|
|
a403a5b7d8 | ||
|
|
72101a6d46 | ||
|
|
9b6d662aaf | ||
|
|
b578fc732e | ||
|
|
51300dde06 | ||
|
|
2e9634cf65 | ||
|
|
3292fb1146 | ||
|
|
f5c062448d | ||
|
|
82d76f3e99 | ||
|
|
9cc94ce1e6 | ||
|
|
c769f85523 | ||
|
|
21bd206af7 | ||
|
|
8b2080df44 | ||
|
|
6c452137b2 | ||
|
|
f5451ac13f | ||
|
|
3c45f2ba7d | ||
|
|
818eda005f | ||
|
|
676cd8cbd9 | ||
|
|
60f34fe994 | ||
|
|
4d97ba80d6 | ||
|
|
4e9ba66555 | ||
|
|
535cbbac5a | ||
|
|
fc47d07b85 | ||
|
|
e58f907440 | ||
|
|
d9c9db934a | ||
|
|
38fd459c7b | ||
|
|
a16899a829 | ||
|
|
f2d6ff6748 | ||
|
|
2945abde9c | ||
|
|
69a04121a3 | ||
|
|
096684ed94 | ||
|
|
7d35906398 | ||
|
|
93326ab1fe | ||
|
|
148504dabd | ||
|
|
991a603648 | ||
|
|
ba6733411a | ||
|
|
7d521819f0 | ||
|
|
ee81bfc1d7 | ||
|
|
63c96f39a3 | ||
|
|
3e5e4dfe32 | ||
|
|
cd39a8c027 | ||
|
|
da1129cf79 | ||
|
|
56383d4cfb | ||
|
|
ae9f21acd7 | ||
|
|
10d683a38e | ||
|
|
1e5bcfded8 | ||
|
|
d1eec16222 | ||
|
|
0dedc62ce8 | ||
|
|
798eb2330b | ||
|
|
e8bea5cba3 | ||
|
|
58190d5422 | ||
|
|
2ee9183c17 | ||
|
|
620ce51f70 | ||
|
|
dc20327a18 | ||
|
|
47d98b2912 | ||
|
|
f561a59a09 | ||
|
|
f97dd2b05b | ||
|
|
c884781741 | ||
|
|
8fa7b73aea | ||
|
|
02ebb3c7e8 | ||
|
|
463a5d973c | ||
|
|
957498b5a3 | ||
|
|
c15d9f3fe9 | ||
|
|
b0629d626e | ||
|
|
ec09d69145 | ||
|
|
8ddbc6bf96 | ||
|
|
b608e50296 | ||
|
|
7fa791992c | ||
|
|
fae21132ee |
152
.appveyor.yml
Normal file
152
.appveyor.yml
Normal file
@@ -0,0 +1,152 @@
|
||||
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- devel
|
||||
|
||||
os: Visual Studio 2015
|
||||
|
||||
clone_folder: c:\projects\rtabmap
|
||||
|
||||
platform: x64
|
||||
configuration: Release
|
||||
|
||||
init:
|
||||
- cmake --version
|
||||
- call "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x64
|
||||
- call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86_amd64
|
||||
|
||||
install:
|
||||
# To download from google drive
|
||||
- set PATH=C:\Python38-x64;C:\Python38-x64\Scripts;%PATH%
|
||||
- ps: py -m pip --disable-pip-version-check install gdown==4.6.0
|
||||
# Qt
|
||||
- set QTDIR=C:\Qt\5.10.1\msvc2015_64
|
||||
# make sure Qt bin path is before cmake bin path to avoid copying qt5 dlls from cmake before qt installation
|
||||
- set PATH=%QTDIR%\bin;%PATH%
|
||||
# Boost
|
||||
- set PATH=%PATH%;C:\Libraries\boost_1_62_0\lib64-msvc-14.0
|
||||
# Openni2
|
||||
- ps: wget 'https://dl.dropboxusercontent.com/s/d98jv79l6oy9fxz/OpenNI2.exe?dl=0' -outfile OpenNI2.exe
|
||||
- cmd: OpenNI2.exe -o"C:\Program Files" -y
|
||||
- ECHO "Installed OpenNI2:"
|
||||
- ps: "ls \"C:/Program Files/OpenNI2\""
|
||||
- set PATH=%PATH%;C:\Program Files\OpenNI2\Redist
|
||||
- set OPENNI2_INCLUDE64=C:\Program Files\OpenNI2\Include
|
||||
- set OPENNI2_LIB64=C:\Program Files\OpenNI2\Lib
|
||||
- set OPENNI2_REDIST64=C:\Program Files\OpenNI2\Redist
|
||||
# OpenCV
|
||||
#- appveyor-retry appveyor DownloadFile http://downloads.sourceforge.net/project/opencvlibrary/4.5.2/opencv-4.5.2-vc14_vc15.exe
|
||||
#- cmd: opencv-4.5.2-vc14_vc15.exe -o"C:\Program Files" -y
|
||||
#- ECHO "Installed OpenCV:"
|
||||
#- ps: "ls \"C:/Program Files/opencv/build\""
|
||||
#- set PATH=%PATH%;C:\Program Files\opencv\build\x64\vc14\bin
|
||||
- ps: wget 'https://dl.dropboxusercontent.com/s/o6ofn491bc0jso1/opencv450_vc14.exe?dl=0' -outfile opencv.exe
|
||||
- cmd: opencv.exe -o"C:\Program Files" -y
|
||||
- ECHO "Installed OpenCV:"
|
||||
- ps: "ls \"C:/Program Files/opencv\""
|
||||
- set PATH=%PATH%;C:\Program Files\opencv\x64\vc14\bin
|
||||
# VTK (including QVTK)
|
||||
- ps: wget 'https://dl.dropboxusercontent.com/s/1l33b5l3f3y52gf/VTK-6_3-msvc140.exe?dl=0' -outfile VTK-6_3.exe
|
||||
- cmd: VTK-6_3.exe -o"C:\Program Files" -y
|
||||
- ECHO "Installed VTK:"
|
||||
- ps: "ls \"C:/Program Files/VTK\""
|
||||
- set PATH=%PATH%;C:\Program Files\VTK\bin
|
||||
# QHull
|
||||
- ps: wget 'https://dl.dropboxusercontent.com/s/9widnk9msdsh2b8/Qhull-msvc140.exe?dl=0' -outfile Qhull.exe
|
||||
- cmd: Qhull.exe -o"C:\Program Files" -y
|
||||
- ECHO "Installed QHull:"
|
||||
- ps: "ls \"C:/Program Files/Qhull\""
|
||||
- set PATH=%PATH%;C:\Program Files\Qhull\bin
|
||||
# FLANN
|
||||
- ps: wget 'https://dl.dropboxusercontent.com/s/7k58jbmqa51sxmh/FLANN-msvc140.exe?dl=0' -outfile FLANN.exe
|
||||
- cmd: FLANN.exe -o"C:\Program Files" -y
|
||||
- ECHO "Installed FLANN:"
|
||||
- ps: "ls \"C:/Program Files/FLANN\""
|
||||
- set PATH=%PATH%;C:\Program Files\FLANN\bin
|
||||
# Eigen
|
||||
- ps: wget 'https://dl.dropboxusercontent.com/s/3v6i9i8dxj4o8ji/Eigen.exe?dl=0' -outfile Eigen.exe
|
||||
- cmd: Eigen.exe -o"C:\Program Files" -y
|
||||
- ECHO "Installed Eigen:"
|
||||
- ps: "ls \"C:/Program Files/Eigen\""
|
||||
# PCL
|
||||
- ps: wget 'https://dl.dropboxusercontent.com/s/2iayr4lyqa50i9j/PCL_181_August2018_x64_vc14.exe?dl=0' -outfile PCL_1.8.1.exe
|
||||
- cmd: PCL_1.8.1.exe -o"C:\Program Files" -y
|
||||
- ECHO "Installed PCL:"
|
||||
- ps: "ls \"C:/Program Files/PCL\""
|
||||
- set PATH=%PATH%;C:\Program Files\PCL\bin
|
||||
# zlib
|
||||
- ps: gdown -q 0B46akLGdg-uaYm9MTTI4MUtUcmc
|
||||
- ps: Expand-Archive zlib-1.2.8-vc2010-x64.zip -DestinationPath 'C:\Program Files'
|
||||
- ECHO "Installed zlib:"
|
||||
- ps: "ls \"C:/Program Files/zlib\""
|
||||
- set PATH=%PATH%;C:\Program Files\zlib\bin
|
||||
# g2o
|
||||
- ps: wget 'https://dl.dropboxusercontent.com/s/ht74s5pa21wokzw/g2o.exe?dl=0' -outfile g2o.exe
|
||||
- cmd: g2o.exe -o"C:\Program Files" -y
|
||||
- ECHO "Installed g2o:"
|
||||
- ps: "ls \"C:/Program Files/g2o\""
|
||||
- set PATH=%PATH%;C:\Program Files\g2o\bin
|
||||
# GTSAM
|
||||
- ps: wget 'https://dl.dropboxusercontent.com/s/0fpr6r4cgsqmvhf/GTSAM-4_0_0_alpha2-msvc140.exe?dl=0' -outfile GTSAM.exe
|
||||
- cmd: GTSAM.exe -o"C:\Program Files" -y
|
||||
- ECHO "Installed GTSAM:"
|
||||
- ps: "ls \"C:/Program Files/GTSAM\""
|
||||
- set PATH=%PATH%;C:\Program Files\GTSAM\bin
|
||||
# OctoMap
|
||||
- ps: wget 'https://dl.dropboxusercontent.com/s/6jpxu0nm8ne6e54/octomap_x64_vc14.exe?dl=0' -outfile octomap.exe
|
||||
- cmd: octomap.exe -o"C:\Program Files" -y
|
||||
- ECHO "Installed OctoMap:"
|
||||
- ps: "ls \"C:/Program Files/octomap-distribution\""
|
||||
- set PATH=%PATH%;C:\Program Files\octomap-distribution\bin
|
||||
# CPU-TSDF
|
||||
- ps: wget 'https://dl.dropboxusercontent.com/s/mgges9va1uzxr0q/cpu_tsdf_sept2015_x64_vc14.exe?dl=0' -outfile cpu_tsdf.exe
|
||||
- cmd: cpu_tsdf.exe -o"C:\Program Files" -y
|
||||
- ECHO "Installed CPU-TSDF:"
|
||||
- ps: "ls \"C:/Program Files/cpu_tsdf\""
|
||||
- set PATH=%PATH%;C:\Program Files\cpu_tsdf\bin
|
||||
# Open Chisel
|
||||
- ps: wget 'https://dl.dropboxusercontent.com/s/0aaphcde4acrinm/open_chisel_x64_vc14.exe?dl=0' -outfile open_chisel.exe
|
||||
- cmd: open_chisel.exe -o"C:\Program Files" -y
|
||||
- ECHO "Installed Open Chisel:"
|
||||
- ps: "ls \"C:/Program Files/open_chisel\""
|
||||
- set PATH=%PATH%;C:\Program Files\open_chisel\bin
|
||||
# yaml-cpp
|
||||
- ps: wget 'https://dl.dropboxusercontent.com/s/22qfvftwj6zq8tj/yaml-cpp_x64_vc14.exe?dl=0' -outfile yaml-cpp.exe
|
||||
- cmd: yaml-cpp.exe -o"C:\Program Files" -y
|
||||
- ECHO "Installed yaml-cpp:"
|
||||
- ps: "ls \"C:/Program Files/yaml-cpp\""
|
||||
# RealSense2
|
||||
- ps: wget 'https://github.com/IntelRealSense/librealsense/releases/download/v2.40.0/Intel.RealSense.SDK-WIN10-2.40.0.2482.exe' -outfile realsense2.exe
|
||||
- cmd: realsense2.exe /VERYSILENT
|
||||
- ECHO "Installed RealSense2:"
|
||||
- ps: "ls \"C:/Program Files (x86)/Intel RealSense SDK 2.0\""
|
||||
- set PATH=%PATH%;C:\Program Files (x86)\Intel RealSense SDK 2.0\bin\x64
|
||||
- set RealSense2_ROOT_DIR=C:\Program Files (x86)\Intel RealSense SDK 2.0
|
||||
# Kinect 4 Azure
|
||||
- ps: wget 'https://download.microsoft.com/download/3/d/6/3d6d9e99-a251-4cf3-8c6a-8e108e960b4b/Azure%20Kinect%20SDK%201.4.1.exe' -outfile azure.exe
|
||||
- cmd: azure.exe /quiet
|
||||
- ECHO "Installed Kinect For Azure:"
|
||||
- ps: "ls \"C:/Program Files/Azure Kinect SDK v1.4.1\""
|
||||
- set PATH=%PATH%;C:\Program Files\Azure Kinect SDK v1.4.1\tools
|
||||
- set K4A_ROOT_DIR=C:\Program Files\Azure Kinect SDK v1.4.1
|
||||
|
||||
before_build:
|
||||
- cd c:\projects\rtabmap\build
|
||||
- ECHO %PROGRAMFILES%
|
||||
- ECHO %PATH%
|
||||
- cmake -G "Visual Studio 14 2015 Win64" -DOpenCV_DIR="C:\Program Files\opencv\build" -DPCL_DIR="C:\Program Files\PCL\cmake" -DCPUTSDF_DIR="C:\Program Files\cpu_tsdf\share\cpu_tsdf" -Dyaml-cpp_DIR="C:\Program Files\yaml-cpp\CMake" -DBUILD_AS_BUNDLE=ON ..
|
||||
|
||||
after_build :
|
||||
- cmake --build . --config Release --target package
|
||||
|
||||
artifacts:
|
||||
- path: build\RTABMap-*
|
||||
|
||||
notifications:
|
||||
- provider: Email
|
||||
to:
|
||||
- matlabbe@gmail.com
|
||||
on_build_success: false
|
||||
on_build_failure: false
|
||||
on_build_status_changed: true
|
||||
8
.devcontainer/devcontainer.json
Normal file
8
.devcontainer/devcontainer.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"image": "introlab3it/rtabmap:20.04",
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": ["ms-vscode.cpptools-themes", "ms-vscode.cmake-tools", "vscjava.vscode-java-pack"]
|
||||
}
|
||||
}
|
||||
}
|
||||
1
.dockerignore
Normal file
1
.dockerignore
Normal file
@@ -0,0 +1 @@
|
||||
build/*
|
||||
61
.github/workflows/cmake-ros.yml
vendored
Normal file
61
.github/workflows/cmake-ros.yml
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
name: CMake-ROS
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- '**'
|
||||
|
||||
env:
|
||||
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
|
||||
BUILD_TYPE: Release
|
||||
|
||||
jobs:
|
||||
build:
|
||||
# The CMake configure and build commands are platform agnostic and should work equally
|
||||
# well on Windows or Mac. You can convert this to a matrix build if you need
|
||||
# cross-platform coverage.
|
||||
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
|
||||
name: Build on ros ${{ matrix.ros_distribution }} and ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
ros_distribution: [ noetic, humble, iron]
|
||||
include:
|
||||
- ros_distribution: 'noetic'
|
||||
os: ubuntu-20.04
|
||||
- ros_distribution: 'humble'
|
||||
os: ubuntu-22.04
|
||||
- ros_distribution: 'iron'
|
||||
os: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- uses: ros-tooling/setup-ros@v0.6
|
||||
with:
|
||||
required-ros-distributions: ${{ matrix.ros_distribution }}
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
source /opt/ros/${{ matrix.ros_distribution }}/setup.bash
|
||||
rosdep update
|
||||
rosdep install --from-paths ${{github.workspace}} -y
|
||||
|
||||
- name: Configure CMake
|
||||
run: |
|
||||
source /opt/ros/${{ matrix.ros_distribution }}/setup.bash
|
||||
cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
|
||||
|
||||
- name: Build
|
||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
|
||||
|
||||
- name: Info
|
||||
working-directory: ${{github.workspace}}/build/bin
|
||||
run: |
|
||||
source /opt/ros/${{ matrix.ros_distribution }}/setup.bash
|
||||
./rtabmap-console --version
|
||||
|
||||
49
.github/workflows/cmake.yml
vendored
Normal file
49
.github/workflows/cmake.yml
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
name: CMake
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- '**'
|
||||
|
||||
env:
|
||||
BUILD_TYPE: Release
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-22.04, ubuntu-20.04]
|
||||
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
DEBIAN_FRONTEND=noninteractive
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install libopencv-dev libpcl-dev git cmake software-properties-common libyaml-cpp-dev
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Configure CMake
|
||||
run: |
|
||||
cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
|
||||
|
||||
- name: Build
|
||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
|
||||
|
||||
- name: Info
|
||||
working-directory: ${{github.workspace}}/build/bin
|
||||
run: |
|
||||
./rtabmap-console --version
|
||||
|
||||
# - name: Test
|
||||
# working-directory: ${{github.workspace}}/build
|
||||
# # Execute tests defined by the CMake configuration.
|
||||
# # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
|
||||
# run: ctest -C ${{env.BUILD_TYPE}}
|
||||
|
||||
181
.github/workflows/docker.yml
vendored
Normal file
181
.github/workflows/docker.yml
vendored
Normal file
@@ -0,0 +1,181 @@
|
||||
name: docker
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
|
||||
jobs:
|
||||
docker_deps:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
docker_tag: [focal-deps, jammy-deps, jammy-iron-deps]
|
||||
include:
|
||||
- docker_tag: focal-deps
|
||||
docker_tags: |
|
||||
introlab3it/rtabmap:focal-deps
|
||||
docker_platforms: |
|
||||
linux/amd64
|
||||
linux/arm64
|
||||
docker_path: 'focal/deps'
|
||||
- docker_tag: jammy-deps
|
||||
docker_tags: |
|
||||
introlab3it/rtabmap:jammy-deps
|
||||
docker_platforms: |
|
||||
linux/amd64
|
||||
linux/arm64
|
||||
docker_path: 'jammy/deps'
|
||||
- docker_tag: jammy-iron-deps
|
||||
docker_tags: |
|
||||
introlab3it/rtabmap:jammy-iron-deps
|
||||
docker_platforms: |
|
||||
linux/amd64
|
||||
docker_path: 'jammy-iron/deps'
|
||||
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
with:
|
||||
platforms: all
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
-
|
||||
name: Login to DockerHub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
-
|
||||
name: Build and push
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
platforms: ${{ matrix.docker_platforms }}
|
||||
file: ./docker/${{ matrix.docker_path }}/Dockerfile
|
||||
tags: ${{ matrix.docker_tags }}
|
||||
cache-from: type=registry,ref=introlab3it/rtabmap:${{ matrix.docker_tag }}
|
||||
cache-to: type=inline
|
||||
|
||||
docker:
|
||||
needs: docker_deps
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
docker_tag: [bionic, focal, jammy, jammy-iron, android23, android24, android26, android30]
|
||||
include:
|
||||
- docker_tag: bionic
|
||||
docker_tags: |
|
||||
introlab3it/rtabmap:bionic
|
||||
introlab3it/rtabmap:18.04
|
||||
docker_args: |
|
||||
NOT_USED=0
|
||||
docker_platforms: |
|
||||
linux/amd64
|
||||
linux/arm64
|
||||
docker_path: 'bionic'
|
||||
- docker_tag: focal
|
||||
docker_tags: |
|
||||
introlab3it/rtabmap:focal
|
||||
introlab3it/rtabmap:20.04
|
||||
introlab3it/rtabmap:latest
|
||||
docker_args: |
|
||||
NOT_USED=0
|
||||
docker_platforms: |
|
||||
linux/amd64
|
||||
linux/arm64
|
||||
docker_path: 'focal'
|
||||
- docker_tag: jammy
|
||||
docker_tags: |
|
||||
introlab3it/rtabmap:jammy
|
||||
introlab3it/rtabmap:22.04
|
||||
docker_args: |
|
||||
NOT_USED=0
|
||||
docker_platforms: |
|
||||
linux/amd64
|
||||
linux/arm64
|
||||
docker_path: 'jammy'
|
||||
- docker_tag: jammy-iron
|
||||
docker_tags: |
|
||||
introlab3it/rtabmap:jammy-iron
|
||||
docker_args: |
|
||||
NOT_USED=0
|
||||
docker_platforms: |
|
||||
linux/amd64
|
||||
docker_path: 'jammy-iron'
|
||||
- docker_tag: android23
|
||||
docker_tags: |
|
||||
introlab3it/rtabmap:android23
|
||||
introlab3it/rtabmap:tango
|
||||
docker_args: |
|
||||
API_VERSION=23
|
||||
docker_platforms: |
|
||||
linux/amd64
|
||||
docker_path: 'bionic/android/rtabmap_apiXX'
|
||||
- docker_tag: android24
|
||||
docker_tags: |
|
||||
introlab3it/rtabmap:android24
|
||||
docker_args: |
|
||||
API_VERSION=24
|
||||
docker_platforms: |
|
||||
linux/amd64
|
||||
docker_path: 'bionic/android/rtabmap_apiXX'
|
||||
- docker_tag: android26
|
||||
docker_tags: |
|
||||
introlab3it/rtabmap:android26
|
||||
docker_args: |
|
||||
API_VERSION=26
|
||||
docker_platforms: |
|
||||
linux/amd64
|
||||
docker_path: 'bionic/android/rtabmap_apiXX'
|
||||
- docker_tag: android30
|
||||
docker_tags: |
|
||||
introlab3it/rtabmap:android30
|
||||
docker_args: |
|
||||
API_VERSION=30
|
||||
docker_platforms: |
|
||||
linux/amd64
|
||||
docker_path: 'bionic/android/rtabmap_apiXX'
|
||||
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
with:
|
||||
platforms: all
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
-
|
||||
name: Login to DockerHub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
-
|
||||
name: Build and push
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
platforms: ${{ matrix.docker_platforms }}
|
||||
file: ./docker/${{ matrix.docker_path }}/Dockerfile
|
||||
build-args: |
|
||||
${{ matrix.docker_args }}
|
||||
tags: ${{ matrix.docker_tags }}
|
||||
cache-from: type=registry,ref=introlab3it/rtabmap:${{ matrix.docker_tag }}
|
||||
cache-to: type=inline
|
||||
|
||||
14
.gitignore
vendored
Normal file
14
.gitignore
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
/lib
|
||||
.DS_Store
|
||||
.settings/language.settings.xml
|
||||
.idea/
|
||||
.vscode
|
||||
cmake-build-debug/
|
||||
app/android/.classpath
|
||||
app/android/.project
|
||||
app/android/AndroidManifest.xml
|
||||
app/android/res/raw/
|
||||
compile_flags.txt
|
||||
tags
|
||||
build_*
|
||||
*.bak
|
||||
1454
CMakeLists.txt
1454
CMakeLists.txt
File diff suppressed because it is too large
Load Diff
7
LICENSE
7
LICENSE
@@ -1,5 +1,6 @@
|
||||
Copyright (c) 2010-2015, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
|
||||
All rights reserved.
|
||||
RTAB-Map - https://github.com/introlab/rtabmap
|
||||
Copyright (c) 2010-2021, Mathieu Labbe - IntRoLab - Universite de Sherbrooke, all rights reserved.
|
||||
Copyright (c) XXX, contributors, all rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
@@ -11,7 +12,7 @@ modification, are permitted provided that the following conditions are met:
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the Universite de Sherbrooke nor the names of its
|
||||
* Neither the name of the copyright holders nor the names of the
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
|
||||
function filtered = pf_filter(x, nParticles, noise, lambda)
|
||||
|
||||
particles = zeros(nParticles,1) ;
|
||||
weights = zeros(nParticles,1);
|
||||
filtered=zeros(1,length(x));
|
||||
for i = 1:length(x);
|
||||
for j = 1:nParticles
|
||||
rn = sqrt(-2.0*log(rand))*cos(2*pi*rand); % randn c++
|
||||
bruit= noise*rn;
|
||||
particles(j) = particles(j) + bruit ;
|
||||
dist = abs(particles(j) - x(i));
|
||||
weights(j) = exp(-lambda*dist);
|
||||
end
|
||||
weights = weights ./(sum(weights(:)));
|
||||
filtered(i) = weights'*particles;
|
||||
particles = Rresample2(particles,weights);
|
||||
end
|
||||
74
README.md
74
README.md
@@ -1,10 +1,82 @@
|
||||
rtabmap
|
||||
=======
|
||||
|
||||
[](http://introlab.github.io/rtabmap)
|
||||
|
||||
[![Release][release-image]][releases]
|
||||
[![Downloads][downloads-image]][downloads]
|
||||
[![License][license-image]][license]
|
||||
|
||||
[release-image]: https://img.shields.io/badge/release-0.21.4-green.svg?style=flat
|
||||
[releases]: https://github.com/introlab/rtabmap/releases
|
||||
|
||||
[downloads-image]: https://img.shields.io/github/downloads/introlab/rtabmap/total?label=downloads
|
||||
[downloads]: https://github.com/introlab/rtabmap/releases
|
||||
|
||||
[license-image]: https://img.shields.io/badge/license-BSD-green.svg?style=flat
|
||||
[license]: https://github.com/introlab/rtabmap/blob/master/LICENSE
|
||||
|
||||
RTAB-Map library and standalone application.
|
||||
|
||||
For more information, visit the [RTAB-Map's home page](http://introlab.github.io/rtabmap) or the [RTAB-Map's wiki](https://github.com/introlab/rtabmap/wiki).
|
||||
* For more information (e.g., papers, major updates), visit [RTAB-Map's home page](http://introlab.github.io/rtabmap).
|
||||
* For installation instructions and examples, visit [RTAB-Map's wiki](https://github.com/introlab/rtabmap/wiki).
|
||||
|
||||
To use RTAB-Map under ROS, visit the [rtabmap](http://wiki.ros.org/rtabmap) page on the ROS wiki.
|
||||
|
||||
### Acknowledgements
|
||||
This project is supported by [IntRoLab - Intelligent / Interactive / Integrated / Interdisciplinary Robot Lab](https://introlab.3it.usherbrooke.ca/), Sherbrooke, Québec, Canada.
|
||||
|
||||
<a href="https://introlab.3it.usherbrooke.ca/">
|
||||
<img src="https://github.com/introlab/16SoundsUSB/blob/master/images/IntRoLab.png" alt="IntRoLab" height="100">
|
||||
</a>
|
||||
|
||||
#### CI Latest
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Linux</td>
|
||||
<td><a href="https://github.com/introlab/rtabmap/actions/workflows/cmake.yml"><img src="https://github.com/introlab/rtabmap/actions/workflows/cmake.yml/badge.svg" alt="Build Status"/> <br> <a href="https://github.com/introlab/rtabmap/actions/workflows/cmake-ros.yml"><img src="https://github.com/introlab/rtabmap/actions/workflows/cmake-ros.yml/badge.svg" alt="Build Status"/> <br> <a href="https://github.com/introlab/rtabmap/actions/workflows/docker.yml"><img src="https://github.com/introlab/rtabmap/actions/workflows/docker.yml/badge.svg" alt="Build Status"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Windows</td>
|
||||
<td><a href="https://ci.appveyor.com/project/matlabbe/rtabmap/branch/master"><img src="https://ci.appveyor.com/api/projects/status/hr73xspix9oqa26h/branch/master?svg=true" alt="Build Status"/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
#### ROS Binaries
|
||||
|
||||
`ros-$ROS_DISTRO-rtabmap`
|
||||
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td rowspan="1">ROS 1</td>
|
||||
<td>Noetic</td>
|
||||
<td><a href="http://build.ros.org/job/Nbin_ufv8_uFv8__rtabmap__ubuntu_focal_arm64__binary/"><img src="http://build.ros.org/buildStatus/icon?job=Nbin_ufv8_uFv8__rtabmap__ubuntu_focal_arm64__binary" alt="Build Status"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan="3">ROS 2</td>
|
||||
<td>Humble</td>
|
||||
<td><a href="http://build.ros2.org/job/Hbin_uJ64__rtabmap__ubuntu_jammy_amd64__binary/"><img src="http://build.ros2.org/buildStatus/icon?job=Hbin_uJ64__rtabmap__ubuntu_jammy_amd64__binary" alt="Build Status"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Iron</td>
|
||||
<td><a href="http://build.ros2.org/job/Ibin_uJ64__rtabmap__ubuntu_jammy_amd64__binary/"><img src="http://build.ros2.org/buildStatus/icon?job=Ibin_uJ64__rtabmap__ubuntu_jammy_amd64__binary" alt="Build Status"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Rolling</td>
|
||||
<td><a href="http://build.ros2.org/job/Rbin_uJ64__rtabmap__ubuntu_jammy_amd64__binary/"><img src="http://build.ros2.org/buildStatus/icon?job=Rbin_uJ64__rtabmap__ubuntu_jammy_amd64__binary" alt="Build Status"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Docker</td>
|
||||
<td>
|
||||
<a href="https://hub.docker.com/r/introlab3it/rtabmap">rtabmap</a>
|
||||
</td>
|
||||
<td><img src="https://img.shields.io/docker/pulls/introlab3it/rtabmap.svg?label=pulls" alt="Docker Pulls"/></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -1,73 +1,103 @@
|
||||
# - Config file for the RTABMap package
|
||||
# It defines the following variables
|
||||
# RTABMap_INCLUDE_DIRS - include directories for RTABMap
|
||||
# RTABMap_LIBRARIES - libraries to link against
|
||||
# RTABMap_CORE - core library
|
||||
# RTABMap_UTILITE - utilite library
|
||||
# RTABMap_GUI - gui library (set if RTABMap is built with Qt)
|
||||
include(CMakeFindDependencyMacro)
|
||||
|
||||
# Compute paths
|
||||
get_filename_component(RTABMap_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
||||
set(RTABMap_INCLUDE_DIRS "@CONF_INCLUDE_DIRS@")
|
||||
# Mandatory dependencies
|
||||
find_dependency(OpenCV COMPONENTS core calib3d imgproc highgui stitching photo video OPTIONAL_COMPONENTS aruco xfeatures2d nonfree gpu cudafeatures2d)
|
||||
|
||||
#core lib
|
||||
find_library(RTABMap_CORE_RELEASE NAMES rtabmap_core NO_DEFAULT_PATH HINTS "@CONF_LIB_DIR@")
|
||||
find_library(RTABMap_CORE_DEBUG NAMES rtabmap_cored NO_DEFAULT_PATH HINTS "@CONF_LIB_DIR@")
|
||||
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/RTABMap_guiTargets.cmake")
|
||||
find_dependency(PCL 1.7 COMPONENTS common io kdtree search surface filters registration sample_consensus segmentation visualization)
|
||||
|
||||
IF(RTABMap_CORE_DEBUG AND RTABMap_CORE_RELEASE)
|
||||
SET(RTABMap_CORE
|
||||
debug ${RTABMap_CORE_DEBUG}
|
||||
optimized ${RTABMap_CORE_RELEASE}
|
||||
)
|
||||
ELSEIF(RTABMap_CORE_RELEASE)
|
||||
SET(RTABMap_CORE ${RTABMap_CORE_RELEASE})
|
||||
ELSEIF(RTABMap_CORE_DEBUG)
|
||||
SET(RTABMap_CORE ${RTABMap_CORE_DEBUG})
|
||||
if(@CONF_QT_VERSION@ EQUAL 6)
|
||||
find_dependency(Qt6 COMPONENTS Widgets Core Gui OpenGL)
|
||||
elseif(@CONF_QT_VERSION@ EQUAL 5)
|
||||
find_dependency(Qt5 COMPONENTS Widgets Core Gui OpenGL)
|
||||
else() # Qt4
|
||||
find_dependency(Qt4 COMPONENTS QtCore QtGui)
|
||||
endif()
|
||||
set(RTABMap_QT_VERSION @CONF_QT_VERSION@)
|
||||
ELSE()
|
||||
find_dependency(PCL 1.7 COMPONENTS common io kdtree search surface filters registration sample_consensus segmentation)
|
||||
ENDIF()
|
||||
set(RTABMap_DEFINITIONS ${PCL_DEFINITIONS})
|
||||
add_definitions(${RTABMap_DEFINITIONS}) # To include -march=native if set
|
||||
|
||||
# Optional dependencies
|
||||
IF(EXISTS "${CMAKE_CURRENT_LIST_DIR}/@CONF_MODULES_DIR@")
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/@CONF_MODULES_DIR@")
|
||||
ENDIF()
|
||||
|
||||
#utilite lib
|
||||
find_library(RTABMap_UTILITE_RELEASE NAMES rtabmap_utilite NO_DEFAULT_PATH HINTS "@CONF_LIB_DIR@")
|
||||
find_library(RTABMap_UTILITE_DEBUG NAMES rtabmap_utilited NO_DEFAULT_PATH HINTS "@CONF_LIB_DIR@")
|
||||
|
||||
IF(RTABMap_UTILITE_DEBUG AND RTABMap_UTILITE_RELEASE)
|
||||
SET(RTABMap_UTILITE
|
||||
debug ${RTABMap_UTILITE_DEBUG}
|
||||
optimized ${RTABMap_UTILITE_RELEASE}
|
||||
)
|
||||
ELSEIF(RTABMap_UTILITE_RELEASE)
|
||||
SET(RTABMap_UTILITE ${RTABMap_UTILITE_RELEASE})
|
||||
ELSEIF(RTABMap_UTILITE_DEBUG)
|
||||
SET(RTABMap_UTILITE ${RTABMap_UTILITE_DEBUG})
|
||||
ENDIF()
|
||||
|
||||
set(RTABMap_LIBRARIES ${RTABMap_CORE} ${RTABMap_UTILITE})
|
||||
|
||||
#gui lib (OFF if RTAB-Map is not built with Qt)
|
||||
if(@CONF_WITH_GUI@)
|
||||
find_library(RTABMap_GUI_RELEASE NAMES rtabmap_gui NO_DEFAULT_PATH HINTS "@CONF_LIB_DIR@")
|
||||
find_library(RTABMap_GUI_DEBUG NAMES rtabmap_guid NO_DEFAULT_PATH HINTS "@CONF_LIB_DIR@")
|
||||
|
||||
IF(RTABMap_GUI_DEBUG AND RTABMap_GUI_RELEASE)
|
||||
SET(RTABMap_GUI
|
||||
debug ${RTABMap_GUI_DEBUG}
|
||||
optimized ${RTABMap_GUI_RELEASE}
|
||||
)
|
||||
ELSEIF(RTABMap_GUI_RELEASE)
|
||||
SET(RTABMap_GUI ${RTABMap_GUI_RELEASE})
|
||||
ELSEIF(RTABMap_GUI_DEBUG)
|
||||
SET(RTABMap_GUI ${RTABMap_GUI_DEBUG})
|
||||
IF(@CONF_WITH_REALSENSE2@)
|
||||
IF(WIN32)
|
||||
find_dependency(RealSense2)
|
||||
ELSE()
|
||||
find_dependency(realsense2)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
set(RTABMap_LIBRARIES ${RTABMap_LIBRARIES} ${RTABMap_GUI})
|
||||
endif(@CONF_WITH_GUI@)
|
||||
IF(@CONF_WITH_K4A@)
|
||||
IF(WIN32)
|
||||
find_dependency(K4A)
|
||||
ELSE()
|
||||
find_dependency(k4a)
|
||||
find_dependency(k4arecord)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
#backward compatibilities
|
||||
if(RTABMap_CORE)
|
||||
set(RTABMAP_CORE ${RTABMap_CORE})
|
||||
endif(RTABMap_CORE)
|
||||
if(RTABMap_UTILITE)
|
||||
set(RTABMAP_UTILITE ${RTABMap_UTILITE})
|
||||
endif(RTABMap_UTILITE)
|
||||
if(RTABMap_GUI)
|
||||
set(RTABMAP_GUI ${RTABMap_GUI})
|
||||
endif(RTABMap_GUI)
|
||||
IF(@CONF_WITH_DEPTH_AI@)
|
||||
find_dependency(depthai 2)
|
||||
ENDIF()
|
||||
|
||||
IF(@CONF_WITH_OCTOMAP@)
|
||||
find_dependency(octomap)
|
||||
ENDIF()
|
||||
|
||||
IF(@CONF_WITH_GRIDMAP@)
|
||||
find_dependency(grid_map_core)
|
||||
ENDIF()
|
||||
|
||||
IF(@CONF_WITH_PYTHON@)
|
||||
find_dependency(Python3 COMPONENTS Interpreter Development NumPy)
|
||||
ENDIF()
|
||||
|
||||
# Provide those for backward compatibilities (e.g., catkin requires them to propagate dependencies)
|
||||
set(RTABMap_INCLUDE_DIRS "")
|
||||
set(RTABMap_LIBRARIES "")
|
||||
set(RTABMap_TARGETS "")
|
||||
|
||||
set(_RTABMap_supported_components utilite core gui)
|
||||
|
||||
foreach(_comp ${_RTABMap_supported_components})
|
||||
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/RTABMap_${_comp}Targets.cmake")
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/RTABMap_${_comp}Targets.cmake")
|
||||
set(RTABMap_${_comp}_FOUND True)
|
||||
set(RTABMap_TARGETS
|
||||
${RTABMap_TARGETS}
|
||||
rtabmap::${_comp})
|
||||
get_target_property(RTABMap_${_comp}_INCLUDE_DIRS rtabmap::${_comp} INTERFACE_INCLUDE_DIRECTORIES)
|
||||
get_target_property(RTABMap_${_comp}_LIBRARIES rtabmap::${_comp} INTERFACE_LINK_LIBRARIES)
|
||||
set(RTABMap_INCLUDE_DIRS
|
||||
${RTABMap_INCLUDE_DIRS}
|
||||
${RTABMap_${_comp}_INCLUDE_DIRS})
|
||||
set(RTABMap_LIBRARIES
|
||||
${RTABMap_LIBRARIES}
|
||||
rtabmap::${_comp})
|
||||
if(RTABMap_${_comp}_LIBRARIES)
|
||||
set(RTABMap_LIBRARIES
|
||||
${RTABMap_LIBRARIES}
|
||||
${RTABMap_${_comp}_LIBRARIES})
|
||||
endif()
|
||||
else()
|
||||
set(RTABMap_${_comp}_FOUND False)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/RTABMapTargets.cmake")
|
||||
|
||||
foreach(_comp ${RTABMap_FIND_COMPONENTS})
|
||||
if (NOT ";${_RTABMap_supported_components};" MATCHES ";${_comp};")
|
||||
set(RTABMap_${_comp}_FOUND False)
|
||||
if(${RTABMap_FIND_REQUIRED_${_comp}})
|
||||
set(RTABMap_FOUND False)
|
||||
set(RTABMap_NOT_FOUND_MESSAGE "Unsupported or not found required component: ${_comp}")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
set(PACKAGE_VERSION "@RTABMAP_VERSION@")
|
||||
|
||||
# Check whether the requested PACKAGE_FIND_VERSION is compatible
|
||||
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
|
||||
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
||||
else()
|
||||
set(PACKAGE_VERSION_COMPATIBLE TRUE)
|
||||
if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
|
||||
set(PACKAGE_VERSION_EXACT TRUE)
|
||||
endif()
|
||||
endif()
|
||||
61
Version.h.in
61
Version.h.in
@@ -37,7 +37,66 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#define RTABMAP_VERSION_COMPARE(major, minor, patch) (major>=@PROJECT_VERSION_MAJOR@ || (major==@PROJECT_VERSION_MAJOR@ && minor>=@PROJECT_VERSION_MINOR@) || (major==@PROJECT_VERSION_MAJOR@ && minor==@PROJECT_VERSION_MINOR@ && patch >=@PROJECT_VERSION_PATCH@))
|
||||
|
||||
#define RTABMAP_NONFREE @NONFREE@
|
||||
@NONFREE@#define RTABMAP_NONFREE
|
||||
@TORO@#define RTABMAP_TORO
|
||||
@G2O@#define RTABMAP_G2O
|
||||
@G2O_CPP_CONF@#define RTABMAP_G2O_CPP11 @G2O_CPP11@
|
||||
@GTSAM@#define RTABMAP_GTSAM
|
||||
@CERES@#define RTABMAP_CERES
|
||||
@MRPT@#define RTABMAP_MRPT
|
||||
@VERTIGO@#define RTABMAP_VERTIGO
|
||||
@OPENNI2@#define RTABMAP_OPENNI2
|
||||
@FREENECT@#define RTABMAP_FREENECT
|
||||
@FREENECT2@#define RTABMAP_FREENECT2
|
||||
@K4W2@#define RTABMAP_K4W2
|
||||
@K4A@#define RTABMAP_K4A
|
||||
@CVSBA@#define RTABMAP_CVSBA
|
||||
@POINTMATCHER@#define RTABMAP_POINTMATCHER
|
||||
@CCCORELIB@#define RTABMAP_CCCORELIB
|
||||
@OPEN3D@#define RTABMAP_OPEN3D
|
||||
@FASTCV@#define RTABMAP_FASTCV
|
||||
@OPENGV@#define RTABMAP_OPENGV
|
||||
@PDAL@#define RTABMAP_PDAL
|
||||
@LOAM@#define RTABMAP_LOAM
|
||||
@FLOAM@#define RTABMAP_FLOAM
|
||||
@DC1394@#define RTABMAP_DC1394
|
||||
@FLYCAPTURE2@#define RTABMAP_FLYCAPTURE2
|
||||
@ZED@#define RTABMAP_ZED
|
||||
@ZEDOC@#define RTABMAP_ZEDOC
|
||||
@REALSENSE@#define RTABMAP_REALSENSE
|
||||
@REALSENSESLAM@#define RTABMAP_REALSENSE_SLAM
|
||||
@REALSENSE2@#define RTABMAP_REALSENSE2
|
||||
@MYNTEYE@#define RTABMAP_MYNTEYE
|
||||
@DEPTHAI@#define RTABMAP_DEPTHAI
|
||||
@OCTOMAP@#define RTABMAP_OCTOMAP
|
||||
@GRIDMAP@#define RTABMAP_GRIDMAP
|
||||
@CPUTSDF@#define RTABMAP_CPUTSDF
|
||||
@ALICE_VISION@#define RTABMAP_ALICE_VISION
|
||||
@OPENCHISEL@#define RTABMAP_OPENCHISEL
|
||||
@FOVIS@#define RTABMAP_FOVIS
|
||||
@VISO2@#define RTABMAP_VISO2
|
||||
@DVO@#define RTABMAP_DVO
|
||||
@OKVIS@#define RTABMAP_OKVIS
|
||||
@MSCKF_VIO@#define RTABMAP_MSCKF_VIO
|
||||
@VINS@#define RTABMAP_VINS
|
||||
@OPENVINS@#define RTABMAP_OPENVINS
|
||||
@ORB_SLAM@#define RTABMAP_ORB_SLAM @ORB_SLAM_VERSION@
|
||||
@ORB_OCTREE@#define RTABMAP_ORB_OCTREE
|
||||
@TORCH@#define RTABMAP_TORCH
|
||||
@PYTHON@#define RTABMAP_PYTHON
|
||||
@MADGWICK@#define RTABMAP_MADGWICK
|
||||
|
||||
#include <pcl/pcl_config.h>
|
||||
|
||||
#if PCL_VERSION_COMPARE(>, 1, 11, 1)
|
||||
#include <pcl/types.h>
|
||||
#define RTABMAP_PCL_INDEX pcl::index_t
|
||||
#elif PCL_VERSION_COMPARE(>=, 1, 10, 0)
|
||||
#define RTABMAP_PCL_INDEX std::uint32_t
|
||||
#else
|
||||
#include <pcl/pcl_macros.h>
|
||||
#define RTABMAP_PCL_INDEX pcl::uint32_t
|
||||
#endif
|
||||
|
||||
#endif /* VERSION_H_ */
|
||||
|
||||
|
||||
@@ -1 +1,6 @@
|
||||
ADD_SUBDIRECTORY( src )
|
||||
|
||||
IF(ANDROID)
|
||||
ADD_SUBDIRECTORY( android )
|
||||
ELSE()
|
||||
ADD_SUBDIRECTORY( src )
|
||||
ENDIF()
|
||||
2
app/android/.gitignore
vendored
Normal file
2
app/android/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/bin/
|
||||
/gen/
|
||||
11
app/android/.settings/org.eclipse.jdt.core.prefs
Normal file
11
app/android/.settings/org.eclipse.jdt.core.prefs
Normal file
@@ -0,0 +1,11 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.6
|
||||
88
app/android/AndroidManifest.xml.in
Normal file
88
app/android/AndroidManifest.xml.in
Normal file
@@ -0,0 +1,88 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- BEGIN_INCLUDE(manifest) -->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.introlab.rtabmap"
|
||||
android:versionCode="72"
|
||||
android:versionName="@RTABMAP_VERSION@">
|
||||
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-feature android:name="android.hardware.location.gps" />
|
||||
<uses-feature android:glEsVersion="0x00020000" />
|
||||
|
||||
<!-- This is the platform API where depth16 support in android was introduced. -->
|
||||
<uses-sdk android:minSdkVersion="@ANDROID_NATIVE_API_LEVEL@" />
|
||||
|
||||
<queries>
|
||||
<package android:name="com.google.ar.core" />
|
||||
<package android:name="com.huawei.ar.engine" />
|
||||
</queries>
|
||||
|
||||
<!-- This .apk has no Java code itself, so set hasCode to false. -->
|
||||
<application
|
||||
android:label="@string/app_name"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:debuggable="@ANDROID_DEBUGGABLE@">
|
||||
|
||||
<uses-library android:name="com.projecttango.libtango_device2" android:required="false" />
|
||||
<meta-data android:name="com.google.ar.core" android:value="optional" />
|
||||
<meta-data android:name="com.huawei.ar.engine" android:value="optional" />
|
||||
|
||||
<!-- Our activity is the built-in NativeActivity framework class.
|
||||
This will take care of integrating with our NDK code. -->
|
||||
<activity android:name="RTABMapActivity"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTask"
|
||||
android:screenOrientation="fullSensor"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
android:theme="@style/ThemeApp">
|
||||
<!-- Tell NativeActivity the name of our .so -->
|
||||
<meta-data android:name="android.app.lib_name"
|
||||
android:value="NativeRTABMap" />
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<action android:name="android.intent.action.SEND_MULTIPLE" />
|
||||
<action android:name="android.intent.action.OPEN_DOCUMENT" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="application/octet-stream" />
|
||||
<data android:pathPattern=".*\.db" />
|
||||
</intent-filter>
|
||||
|
||||
</activity>
|
||||
|
||||
<activity android:name="SettingsActivity" android:label="@string/settings" android:screenOrientation="fullSensor"/>
|
||||
<activity android:name="SketchfabActivity" android:label="@string/sketchfab" android:screenOrientation="fullSensor"/>
|
||||
|
||||
<meta-data
|
||||
android:name="com.google.ar.core.min_apk_version"
|
||||
android:value="191106000" /> <!-- This activity is critical for installing ARCore when it is not already present. -->
|
||||
<activity
|
||||
android:name="com.google.ar.core.InstallActivity"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize"
|
||||
android:excludeFromRecents="true"
|
||||
android:exported="false"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@android:style/Theme.Material.Light.Dialog.Alert" />
|
||||
|
||||
<provider
|
||||
android:name="android.support.v4.content.FileProvider"
|
||||
android:authorities="com.introlab.rtabmap.provider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/provider_paths"/>
|
||||
</provider>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
<!-- END_INCLUDE(manifest) -->
|
||||
191
app/android/CMakeLists.txt
Normal file
191
app/android/CMakeLists.txt
Normal file
@@ -0,0 +1,191 @@
|
||||
|
||||
option(WITH_TANGO "Include Tango support" ON)
|
||||
option(WITH_ARCORE "Include ARCore support" ON)
|
||||
option(WITH_ARENGINE "Include AREngine support" ON)
|
||||
option(DISABLE_LOG "Disable Android logging (should be true in release)" ON)
|
||||
option(DEPTH_TEST "Enable depth test on ARCore" OFF)
|
||||
|
||||
# Google Tango needs access to system shared
|
||||
# libraries (e.g. libbinder.so) that are not accessible
|
||||
# with android >=24
|
||||
IF(WITH_TANGO AND ${ANDROID_NATIVE_API_LEVEL} LESS 24)
|
||||
FIND_PACKAGE(Tango QUIET)
|
||||
IF(Tango_FOUND)
|
||||
MESSAGE(STATUS "Found Tango: ${Tango_INCLUDE_DIRS}")
|
||||
ENDIF(Tango_FOUND)
|
||||
ENDIF(WITH_TANGO AND ${ANDROID_NATIVE_API_LEVEL} LESS 24)
|
||||
|
||||
IF(WITH_ARCORE AND ${ANDROID_NATIVE_API_LEVEL} GREATER 22)
|
||||
FIND_PACKAGE(ARCore QUIET)
|
||||
IF(ARCore_FOUND)
|
||||
MESSAGE(STATUS "Found ARCore: ${ARCore_INCLUDE_DIRS}")
|
||||
ENDIF(ARCore_FOUND)
|
||||
ENDIF(WITH_ARCORE AND ${ANDROID_NATIVE_API_LEVEL} GREATER 22)
|
||||
|
||||
IF(WITH_ARENGINE AND ${ANDROID_NATIVE_API_LEVEL} GREATER 23)
|
||||
FIND_PACKAGE(AREngine QUIET)
|
||||
IF(AREngine_FOUND)
|
||||
MESSAGE(STATUS "Found AREngine: ${AREngine_INCLUDE_DIRS}")
|
||||
ENDIF(AREngine_FOUND)
|
||||
ENDIF(WITH_ARENGINE AND ${ANDROID_NATIVE_API_LEVEL} GREATER 23)
|
||||
|
||||
IF(NOT Tango_FOUND)
|
||||
SET(TANGO "//")
|
||||
ENDIF(NOT Tango_FOUND)
|
||||
IF(NOT ARCore_FOUND)
|
||||
SET(ARCORE "//")
|
||||
ENDIF(NOT ARCore_FOUND)
|
||||
IF(NOT AREngine_FOUND)
|
||||
SET(ARENGINE "//")
|
||||
ENDIF(NOT AREngine_FOUND)
|
||||
|
||||
CONFIGURE_FILE(CameraAvailability.h.in ${CMAKE_CURRENT_SOURCE_DIR}/jni/CameraAvailability.h)
|
||||
|
||||
|
||||
IF(DISABLE_LOG)
|
||||
ADD_DEFINITIONS(-DDISABLE_LOG)
|
||||
ENDIF(DISABLE_LOG)
|
||||
IF(DEPTH_TEST)
|
||||
ADD_DEFINITIONS(-DDEPTH_TEST)
|
||||
ENDIF(DEPTH_TEST)
|
||||
|
||||
MESSAGE(STATUS "--------------------------------------------")
|
||||
MESSAGE(STATUS "Android build info:")
|
||||
MESSAGE(STATUS " DISABLE_LOG = ${DISABLE_LOG}")
|
||||
MESSAGE(STATUS " DEPTH_TEST = ${DEPTH_TEST}")
|
||||
IF(Tango_FOUND)
|
||||
MESSAGE(STATUS " With Tango = YES")
|
||||
ELSEIF(NOT WITH_TANGO)
|
||||
MESSAGE(STATUS " With Tango = NO (WITH_TANGO=OFF)")
|
||||
ELSE()
|
||||
IF(${ANDROID_NATIVE_API_LEVEL} GREATER 23)
|
||||
MESSAGE(STATUS " With Tango = NO (ANDROID_NATIVE_API_LEVEL should be <= 23)")
|
||||
ELSE()
|
||||
MESSAGE(STATUS " With Tango = NO (tango not found)")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
IF(ARCore_FOUND)
|
||||
MESSAGE(STATUS " With ARCore = YES")
|
||||
ELSEIF(NOT WITH_ARCORE)
|
||||
MESSAGE(STATUS " With ARCore = NO (WITH_ARCORE=OFF)")
|
||||
ELSE()
|
||||
IF(${ANDROID_NATIVE_API_LEVEL} LESS 23)
|
||||
MESSAGE(STATUS " With ARCore = NO (ANDROID_NATIVE_API_LEVEL should be >= 23)")
|
||||
ELSE()
|
||||
MESSAGE(STATUS " With ARCore = NO (ARCore not found)")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
IF(AREngine_FOUND)
|
||||
MESSAGE(STATUS " With AREngine = YES")
|
||||
ELSEIF(NOT WITH_ARENGINE)
|
||||
MESSAGE(STATUS " With AREngine = NO (WITH_ARENGINE=OFF)")
|
||||
ELSE()
|
||||
IF(${ANDROID_NATIVE_API_LEVEL} LESS 24)
|
||||
MESSAGE(STATUS " With AREngine = NO (ANDROID_NATIVE_API_LEVEL should be >= 24)")
|
||||
ELSE()
|
||||
MESSAGE(STATUS " With AREngine = NO (AREngine not found)")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
MESSAGE(STATUS " ANDROID_NATIVE_API_LEVEL = ${ANDROID_NATIVE_API_LEVEL}")
|
||||
MESSAGE(STATUS " ANDROID_COMPILER_FLAGS_RELEASE = ${ANDROID_COMPILER_FLAGS_RELEASE}")
|
||||
MESSAGE(STATUS " ANDROID_TOOLCHAIN_PREFIX = ${ANDROID_TOOLCHAIN_PREFIX}")
|
||||
|
||||
|
||||
IF(DISABLE_LOG)
|
||||
SET(ANDROID_DEBUGGABLE false)
|
||||
ELSE()
|
||||
SET(ANDROID_DEBUGGABLE true)
|
||||
ENDIF()
|
||||
|
||||
add_subdirectory(jni)
|
||||
|
||||
|
||||
######
|
||||
# Packaging
|
||||
######
|
||||
|
||||
# find android
|
||||
find_host_program(ANDROID_EXECUTABLE
|
||||
NAMES android
|
||||
DOC "The android command-line tool")
|
||||
if(NOT ANDROID_EXECUTABLE)
|
||||
message(FATAL_ERROR "Can not find android command line tool: android")
|
||||
endif()
|
||||
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/AndroidManifest.xml.in"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/AndroidManifest.xml"
|
||||
@ONLY)
|
||||
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/AndroidManifest.xml"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/AndroidManifest.xml"
|
||||
COPYONLY)
|
||||
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/info.txt.in"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/res/raw/info.txt")
|
||||
|
||||
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/ant.properties.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/ant.properties"
|
||||
@ONLY)
|
||||
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/custom_rules.xml"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/custom_rules.xml"
|
||||
COPYONLY)
|
||||
|
||||
add_custom_target(NativeRTABMap-ant-configure ALL
|
||||
COMMAND "${ANDROID_EXECUTABLE}"
|
||||
update project
|
||||
--name RTABMap
|
||||
--path "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
--target "android-${ANDROID_NATIVE_API_LEVEL}"
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/build.xml"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/build.xml"
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/local.properties"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/local.properties"
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/project.properties"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/project.properties"
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/proguard-project.txt"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/proguard-project.txt"
|
||||
COMMAND "${CMAKE_COMMAND}" -E remove
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/build.xml"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/local.properties"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/project.properties"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/proguard-project.txt"
|
||||
WORKING_DIRECTORY
|
||||
"${CMAKE_CURRENT_BINARY_DIR}")
|
||||
|
||||
add_dependencies(NativeRTABMap-ant-configure NativeRTABMap)
|
||||
|
||||
#find ant
|
||||
find_host_program(ANT_EXECUTABLE
|
||||
NAMES ant
|
||||
DOC "The ant build tool")
|
||||
if(NOT ANT_EXECUTABLE)
|
||||
message(FATAL_ERROR "Can not find ant build tool: ant")
|
||||
endif()
|
||||
|
||||
add_custom_target(NativeRTABMap-apk-release ALL
|
||||
COMMAND ${ANT_EXECUTABLE}
|
||||
-file "${CMAKE_CURRENT_BINARY_DIR}/build.xml"
|
||||
release)
|
||||
add_dependencies(NativeRTABMap-apk-release
|
||||
NativeRTABMap-ant-configure
|
||||
NativeRTABMap)
|
||||
|
||||
add_custom_target(NativeRTABMap-apk-debug ALL
|
||||
COMMAND ${ANT_EXECUTABLE}
|
||||
-file "${CMAKE_CURRENT_BINARY_DIR}/build.xml"
|
||||
debug)
|
||||
add_dependencies(NativeRTABMap-apk-debug
|
||||
# NativeRTABMap-apk-release
|
||||
NativeRTABMap-ant-configure
|
||||
NativeRTABMap)
|
||||
39
app/android/CameraAvailability.h.in
Normal file
39
app/android/CameraAvailability.h.in
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the Universite de Sherbrooke nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL UNIVERTY DE SHERBROOKE BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CAMERAAVAILABILITY_H_
|
||||
#define CAMERAAVAILABILITY_H_
|
||||
|
||||
// This is auto-generated!
|
||||
|
||||
@TANGO@#define RTABMAP_TANGO
|
||||
@ARCORE@#define RTABMAP_ARCORE
|
||||
@ARENGINE@#define RTABMAP_ARENGINE
|
||||
|
||||
|
||||
#endif /* CAMERAAVAILABILITY_H_ */
|
||||
|
||||
13
app/android/ant.properties.in
Normal file
13
app/android/ant.properties.in
Normal file
@@ -0,0 +1,13 @@
|
||||
builddir=@CMAKE_CURRENT_BINARY_DIR@
|
||||
srcdir=@CMAKE_CURRENT_SOURCE_DIR@
|
||||
android.abi=@ANDROID_ABI@
|
||||
|
||||
source.dir=${srcdir}/src
|
||||
gen.dir=${builddir}/gen
|
||||
out.dir=${builddir}/bin
|
||||
asset.dir=${builddir}/assets
|
||||
resource.absolute.dir=${srcdir}/res
|
||||
|
||||
jar.libs.dir=${builddir}/libs
|
||||
external.libs.dir=${builddir}/libs
|
||||
native.libs.dir=${builddir}/libs
|
||||
13
app/android/custom_rules.xml
Normal file
13
app/android/custom_rules.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<project>
|
||||
<target name="-pre-build">
|
||||
<copy todir="${jar.libs.dir}">
|
||||
<fileset dir="${srcdir}/libs" includes="**/*.jar" excludes="**/*sources.jar, **/*javadoc.jar" />
|
||||
</copy>
|
||||
<copy todir="${native.libs.dir}/${android.abi}">
|
||||
<fileset dir="${srcdir}/jni/third-party/lib" includes="*.so"/>
|
||||
</copy>
|
||||
<copy todir="${native.libs.dir}">
|
||||
<fileset dir="${srcdir}/jni/third-party/lib" includes="${android.abi}/*.so"/>
|
||||
</copy>
|
||||
</target>
|
||||
</project>
|
||||
BIN
app/android/ic_launcher-web.png
Normal file
BIN
app/android/ic_launcher-web.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 64 KiB |
7
app/android/info.txt.in
Normal file
7
app/android/info.txt.in
Normal file
@@ -0,0 +1,7 @@
|
||||
<h3>Real-Time Appearance-Based Mapping</h3>
|
||||
Version @RTABMAP_VERSION@<br>
|
||||
Author: Mathieu Labbé<br>
|
||||
Copyright 2016-2020<br>
|
||||
IntRoLab - Université de Sherbrooke<br>
|
||||
<b>http://introlab.github.io/rtabmap</b><br><br>
|
||||
|
||||
1
app/android/jni/.gitignore
vendored
Normal file
1
app/android/jni/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
CameraAvailability.h
|
||||
137
app/android/jni/CMakeLists.txt
Normal file
137
app/android/jni/CMakeLists.txt
Normal file
@@ -0,0 +1,137 @@
|
||||
|
||||
SET(INCLUDE_DIRS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tango-gl/include
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/third-party/include
|
||||
${PROJECT_BINARY_DIR}/corelib/include
|
||||
${PROJECT_SOURCE_DIR}/corelib/include
|
||||
${PROJECT_SOURCE_DIR}/utilite/include
|
||||
${OpenCV_INCLUDE_DIRS}
|
||||
${PCL_INCLUDE_DIRS}
|
||||
"${ANDROID_NDK}/platforms/android-${ANDROID_NATIVE_API_LEVEL}/arch-${ANDROID_ARCH_NAME}/usr/include"
|
||||
)
|
||||
|
||||
SET(LIBRARIES
|
||||
${OpenCV_LIBRARIES}
|
||||
${PCL_LIBRARIES}
|
||||
)
|
||||
|
||||
set(sources
|
||||
jni_interface.cpp
|
||||
CameraMobile.cpp
|
||||
RTABMapApp.cpp
|
||||
scene.cpp
|
||||
point_cloud_drawable.cpp
|
||||
graph_drawable.cpp
|
||||
background_renderer.cc
|
||||
tango-gl/axis.cpp
|
||||
tango-gl/camera.cpp
|
||||
tango-gl/conversions.cpp
|
||||
tango-gl/drawable_object.cpp
|
||||
tango-gl/frustum.cpp
|
||||
tango-gl/gesture_camera.cpp
|
||||
tango-gl/grid.cpp
|
||||
tango-gl/line.cpp
|
||||
tango-gl/shaders.cpp
|
||||
tango-gl/trace.cpp
|
||||
tango-gl/transform.cpp
|
||||
tango-gl/util.cpp
|
||||
)
|
||||
|
||||
IF(OPENMP_FOUND)
|
||||
file(COPY ${OpenMP_CXX_LIBRARIES}
|
||||
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/../libs/${ANDROID_NDK_ABI_NAME})
|
||||
ENDIF(OPENMP_FOUND)
|
||||
|
||||
IF(Tango_FOUND)
|
||||
|
||||
SET(sources
|
||||
${sources}
|
||||
CameraTango.cpp
|
||||
)
|
||||
SET(INCLUDE_DIRS
|
||||
${INCLUDE_DIRS}
|
||||
${Tango_INCLUDE_DIRS}
|
||||
)
|
||||
SET(LIBRARIES
|
||||
${LIBRARIES}
|
||||
${Tango_LIBRARIES}
|
||||
)
|
||||
|
||||
file(COPY ${Tango_support_LIBRARY}
|
||||
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/../libs/${ANDROID_NDK_ABI_NAME})
|
||||
ENDIF(Tango_FOUND)
|
||||
|
||||
IF(ARCore_FOUND)
|
||||
|
||||
SET(sources
|
||||
${sources}
|
||||
CameraARCore.cpp
|
||||
)
|
||||
SET(INCLUDE_DIRS
|
||||
${INCLUDE_DIRS}
|
||||
${ARCore_INCLUDE_DIRS}
|
||||
)
|
||||
SET(LIBRARIES
|
||||
${LIBRARIES}
|
||||
${ARCore_LIBRARIES}
|
||||
)
|
||||
|
||||
file(COPY ${ARCore_c_LIBRARY}
|
||||
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/../libs/${ANDROID_NDK_ABI_NAME})
|
||||
file(COPY ${ARCore_jni_LIBRARY}
|
||||
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/../libs/${ANDROID_NDK_ABI_NAME})
|
||||
|
||||
ENDIF(ARCore_FOUND)
|
||||
|
||||
IF(AREngine_FOUND)
|
||||
|
||||
SET(sources
|
||||
${sources}
|
||||
CameraAREngine.cpp
|
||||
)
|
||||
SET(INCLUDE_DIRS
|
||||
${INCLUDE_DIRS}
|
||||
${AREngine_INCLUDE_DIRS}
|
||||
)
|
||||
SET(LIBRARIES
|
||||
${LIBRARIES}
|
||||
${AREngine_LIBRARIES}
|
||||
camera2ndk
|
||||
mediandk
|
||||
)
|
||||
|
||||
file(COPY ${AREngine_impl_LIBRARY}
|
||||
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/../libs/${ANDROID_NDK_ABI_NAME})
|
||||
file(COPY ${AREngine_jni_LIBRARY}
|
||||
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/../libs/${ANDROID_NDK_ABI_NAME})
|
||||
file(COPY ${AREngine_ndk_LIBRARY}
|
||||
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/../libs/${ANDROID_NDK_ABI_NAME})
|
||||
|
||||
ENDIF(AREngine_FOUND)
|
||||
|
||||
add_definitions(${PCL_DEFINITIONS})
|
||||
|
||||
INCLUDE_DIRECTORIES(${INCLUDE_DIRS})
|
||||
|
||||
add_library(NativeRTABMap SHARED ${sources})
|
||||
target_link_libraries(NativeRTABMap ${LIBRARIES}
|
||||
android
|
||||
log
|
||||
GLESv2
|
||||
rtabmap_core
|
||||
rtabmap_utilite
|
||||
)
|
||||
|
||||
# see ant.properties.in
|
||||
set_target_properties(NativeRTABMap PROPERTIES
|
||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../libs/${ANDROID_NDK_ABI_NAME}"
|
||||
LIBRARY_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_BINARY_DIR}/../libs/${ANDROID_NDK_ABI_NAME}"
|
||||
LIBRARY_OUTPUT_DIRECTORY_RELEASE "${CMAKE_CURRENT_BINARY_DIR}/../libs/${ANDROID_NDK_ABI_NAME}")
|
||||
|
||||
IF(ANDROID_NATIVE_API_LEVEL GREATER 22)
|
||||
add_custom_command(TARGET NativeRTABMap POST_BUILD
|
||||
COMMAND "${ANDROID_TOOLCHAIN_PREFIX}strip" -g -S -d --strip-debug --verbose
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/../libs/${ANDROID_NDK_ABI_NAME}/libNativeRTABMap.so"
|
||||
COMMENT "Strip debug symbols done on final binary.")
|
||||
ENDIF(ANDROID_NATIVE_API_LEVEL GREATER 22)
|
||||
704
app/android/jni/CameraARCore.cpp
Normal file
704
app/android/jni/CameraARCore.cpp
Normal file
@@ -0,0 +1,704 @@
|
||||
/*
|
||||
Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the Universite de Sherbrooke nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "CameraARCore.h"
|
||||
#include "util.h"
|
||||
#include "rtabmap/utilite/ULogger.h"
|
||||
#include "rtabmap/core/util3d_transforms.h"
|
||||
#include "rtabmap/core/OdometryEvent.h"
|
||||
#include "rtabmap/core/util2d.h"
|
||||
|
||||
namespace rtabmap {
|
||||
|
||||
//////////////////////////////
|
||||
// CameraARCore
|
||||
//////////////////////////////
|
||||
CameraARCore::CameraARCore(void* env, void* context, void* activity, bool depthFromMotion, bool smoothing):
|
||||
CameraMobile(smoothing),
|
||||
env_(env),
|
||||
context_(context),
|
||||
activity_(activity),
|
||||
arInstallRequested_(false),
|
||||
depthFromMotion_(depthFromMotion)
|
||||
{
|
||||
}
|
||||
|
||||
CameraARCore::~CameraARCore() {
|
||||
// Disconnect ARCore service
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
struct CameraConfig {
|
||||
int32_t width = 0;
|
||||
int32_t height = 0;
|
||||
std::string config_label;
|
||||
ArCameraConfig* config = nullptr;
|
||||
};
|
||||
|
||||
void getCameraConfigLowestAndHighestResolutions(
|
||||
std::vector<CameraConfig> & camera_configs,
|
||||
CameraConfig** lowest_resolution_config,
|
||||
CameraConfig** highest_resolution_config) {
|
||||
if (camera_configs.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int low_resolution_config_idx = 0;
|
||||
int high_resolution_config_idx = 0;
|
||||
int32_t smallest_height = camera_configs[0].height;
|
||||
int32_t largest_height = camera_configs[0].height;
|
||||
|
||||
for (int i = 1; i < camera_configs.size(); ++i) {
|
||||
int32_t image_height = camera_configs[i].height;
|
||||
if (image_height < smallest_height) {
|
||||
smallest_height = image_height;
|
||||
low_resolution_config_idx = i;
|
||||
} else if (image_height > largest_height) {
|
||||
largest_height = image_height;
|
||||
high_resolution_config_idx = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (low_resolution_config_idx == high_resolution_config_idx) {
|
||||
*lowest_resolution_config = &camera_configs[low_resolution_config_idx];
|
||||
} else {
|
||||
*lowest_resolution_config = &camera_configs[low_resolution_config_idx];
|
||||
*highest_resolution_config = &camera_configs[high_resolution_config_idx];
|
||||
}
|
||||
}
|
||||
|
||||
void copyCameraConfig(
|
||||
const ArSession* ar_session, const ArCameraConfigList* all_configs,
|
||||
int index, int num_configs, CameraConfig* camera_config) {
|
||||
if (camera_config != nullptr && index >= 0 && index < num_configs) {
|
||||
ArCameraConfig_create(ar_session, &camera_config->config);
|
||||
ArCameraConfigList_getItem(ar_session, all_configs, index,
|
||||
camera_config->config);
|
||||
ArCameraConfig_getImageDimensions(ar_session, camera_config->config,
|
||||
&camera_config->width,
|
||||
&camera_config->height);
|
||||
camera_config->config_label = "(" + std::to_string(camera_config->width) +
|
||||
"x" + std::to_string(camera_config->height) +
|
||||
")";
|
||||
}
|
||||
}
|
||||
|
||||
void destroyCameraConfigs(std::vector<CameraConfig> & camera_configs) {
|
||||
for (int i = 0; i < camera_configs.size(); ++i) {
|
||||
if (camera_configs[i].config != nullptr) {
|
||||
ArCameraConfig_destroy(camera_configs[i].config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string CameraARCore::getSerial() const
|
||||
{
|
||||
return "ARCore";
|
||||
}
|
||||
|
||||
bool CameraARCore::init(const std::string & calibrationFolder, const std::string & cameraName)
|
||||
{
|
||||
close();
|
||||
|
||||
UScopeMutex lock(arSessionMutex_);
|
||||
|
||||
ArInstallStatus install_status;
|
||||
// If install was not yet requested, that means that we are resuming the
|
||||
// activity first time because of explicit user interaction (such as
|
||||
// launching the application)
|
||||
bool user_requested_install = !arInstallRequested_;
|
||||
|
||||
// === ATTENTION! ATTENTION! ATTENTION! ===
|
||||
// This method can and will fail in user-facing situations. Your
|
||||
// application must handle these cases at least somewhat gracefully. See
|
||||
// HelloAR Java sample code for reasonable behavior.
|
||||
ArCoreApk_requestInstall(env_, activity_, user_requested_install, &install_status);
|
||||
|
||||
switch (install_status)
|
||||
{
|
||||
case AR_INSTALL_STATUS_INSTALLED:
|
||||
break;
|
||||
case AR_INSTALL_STATUS_INSTALL_REQUESTED:
|
||||
arInstallRequested_ = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// === ATTENTION! ATTENTION! ATTENTION! ===
|
||||
// This method can and will fail in user-facing situations. Your
|
||||
// application must handle these cases at least somewhat gracefully. See
|
||||
// HelloAR Java sample code for reasonable behavior.
|
||||
UASSERT(ArSession_create(env_, context_, &arSession_) == AR_SUCCESS);
|
||||
UASSERT(arSession_);
|
||||
|
||||
int32_t is_depth_supported = 0;
|
||||
ArSession_isDepthModeSupported(arSession_, AR_DEPTH_MODE_AUTOMATIC, &is_depth_supported);
|
||||
|
||||
ArConfig_create(arSession_, &arConfig_);
|
||||
UASSERT(arConfig_);
|
||||
|
||||
if (is_depth_supported!=0) {
|
||||
ArConfig_setDepthMode(arSession_, arConfig_, AR_DEPTH_MODE_AUTOMATIC);
|
||||
} else {
|
||||
ArConfig_setDepthMode(arSession_, arConfig_, AR_DEPTH_MODE_DISABLED);
|
||||
}
|
||||
|
||||
ArConfig_setFocusMode(arSession_, arConfig_, AR_FOCUS_MODE_FIXED);
|
||||
UASSERT(ArSession_configure(arSession_, arConfig_) == AR_SUCCESS);
|
||||
|
||||
ArFrame_create(arSession_, &arFrame_);
|
||||
UASSERT(arFrame_);
|
||||
|
||||
ArCameraIntrinsics_create(arSession_, &arCameraIntrinsics_);
|
||||
UASSERT(arCameraIntrinsics_);
|
||||
|
||||
ArPose_create(arSession_, nullptr, &arPose_);
|
||||
UASSERT(arPose_);
|
||||
|
||||
ArCameraConfigList* all_camera_configs = nullptr;
|
||||
int32_t num_configs = 0;
|
||||
ArCameraConfigList_create(arSession_, &all_camera_configs);
|
||||
// Create filter first to get both 30 and 60 fps.
|
||||
ArCameraConfigFilter* camera_config_filter = nullptr;
|
||||
ArCameraConfigFilter_create(arSession_, &camera_config_filter);
|
||||
ArCameraConfigFilter_setTargetFps(arSession_, camera_config_filter, AR_CAMERA_CONFIG_TARGET_FPS_30 | AR_CAMERA_CONFIG_TARGET_FPS_60);
|
||||
ArSession_getSupportedCameraConfigsWithFilter(arSession_, camera_config_filter, all_camera_configs);
|
||||
ArCameraConfigList_getSize(arSession_, all_camera_configs, &num_configs);
|
||||
|
||||
if (num_configs < 1) {
|
||||
UERROR("No camera config found");
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<CameraConfig> camera_configs;
|
||||
CameraConfig* cpu_low_resolution_camera_config_ptr = nullptr;
|
||||
CameraConfig* cpu_high_resolution_camera_config_ptr = nullptr;
|
||||
camera_configs.resize(num_configs);
|
||||
for (int i = 0; i < num_configs; ++i) {
|
||||
copyCameraConfig(arSession_, all_camera_configs, i, num_configs,
|
||||
&camera_configs[i]);
|
||||
}
|
||||
// Determine the highest and lowest CPU resolutions.
|
||||
cpu_low_resolution_camera_config_ptr = nullptr;
|
||||
cpu_high_resolution_camera_config_ptr = nullptr;
|
||||
getCameraConfigLowestAndHighestResolutions(
|
||||
camera_configs,
|
||||
&cpu_low_resolution_camera_config_ptr,
|
||||
&cpu_high_resolution_camera_config_ptr);
|
||||
|
||||
// Cleanup the list obtained as it is safe to destroy the list as camera
|
||||
// config instances were explicitly created and copied. Refer to the
|
||||
// previous comment.
|
||||
ArCameraConfigList_destroy(all_camera_configs);
|
||||
ArSession_setCameraConfig(arSession_, cpu_low_resolution_camera_config_ptr->config);
|
||||
|
||||
/// Sets the behavior of @ref ArSession_update(). See
|
||||
/// ::ArUpdateMode for available options.
|
||||
ArConfig_setUpdateMode(arSession_, arConfig_, AR_UPDATE_MODE_BLOCKING);
|
||||
|
||||
deviceTColorCamera_ = opticalRotation;
|
||||
|
||||
if (ArSession_resume(arSession_) != ArStatus::AR_SUCCESS)
|
||||
{
|
||||
UERROR("Cannot resume camera!");
|
||||
// In a rare case (such as another camera app launching) the camera may be
|
||||
// given to a different app and so may not be available to this app. Handle
|
||||
// this properly and recreate the session at the next iteration.
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CameraARCore::close()
|
||||
{
|
||||
UScopeMutex lock(arSessionMutex_);
|
||||
if(arSession_!= nullptr)
|
||||
{
|
||||
ArSession_destroy(arSession_);
|
||||
}
|
||||
arSession_ = nullptr;
|
||||
|
||||
if(arConfig_!= nullptr)
|
||||
{
|
||||
ArConfig_destroy(arConfig_);
|
||||
}
|
||||
arConfig_ = nullptr;
|
||||
|
||||
if (arFrame_ != nullptr)
|
||||
{
|
||||
ArFrame_destroy(arFrame_);
|
||||
}
|
||||
arFrame_ = nullptr;
|
||||
|
||||
if (arCameraIntrinsics_ != nullptr)
|
||||
{
|
||||
ArCameraIntrinsics_destroy(arCameraIntrinsics_);
|
||||
}
|
||||
arCameraIntrinsics_ = nullptr;
|
||||
|
||||
if (arPose_ != nullptr)
|
||||
{
|
||||
ArPose_destroy(arPose_);
|
||||
}
|
||||
arPose_ = nullptr;
|
||||
|
||||
CameraMobile::close();
|
||||
}
|
||||
|
||||
LaserScan CameraARCore::scanFromPointCloudData(
|
||||
const float * pointCloudData,
|
||||
int points,
|
||||
const Transform & pose,
|
||||
const CameraModel & model,
|
||||
const cv::Mat & rgb,
|
||||
std::vector<cv::KeyPoint> * kpts,
|
||||
std::vector<cv::Point3f> * kpts3D)
|
||||
{
|
||||
if(pointCloudData && points>0)
|
||||
{
|
||||
cv::Mat scanData(1, points, CV_32FC4);
|
||||
float * ptr = scanData.ptr<float>();
|
||||
for(unsigned int i=0;i<points; ++i)
|
||||
{
|
||||
cv::Point3f pt(pointCloudData[i*4], pointCloudData[i*4 + 1], pointCloudData[i*4 + 2]);
|
||||
pt = util3d::transformPoint(pt, pose.inverse()*rtabmap_world_T_opengl_world);
|
||||
ptr[i*4] = pt.x;
|
||||
ptr[i*4 + 1] = pt.y;
|
||||
ptr[i*4 + 2] = pt.z;
|
||||
|
||||
//get color from rgb image
|
||||
cv::Point3f org= pt;
|
||||
pt = util3d::transformPoint(pt, opticalRotationInv);
|
||||
int u,v;
|
||||
model.reproject(pt.x, pt.y, pt.z, u, v);
|
||||
unsigned char r=255,g=255,b=255;
|
||||
if(model.inFrame(u, v))
|
||||
{
|
||||
b=rgb.at<cv::Vec3b>(v,u).val[0];
|
||||
g=rgb.at<cv::Vec3b>(v,u).val[1];
|
||||
r=rgb.at<cv::Vec3b>(v,u).val[2];
|
||||
if(kpts)
|
||||
kpts->push_back(cv::KeyPoint(u,v,3));
|
||||
if(kpts3D)
|
||||
kpts3D->push_back(org);
|
||||
}
|
||||
*(int*)&ptr[i*4 + 3] = int(b) | (int(g) << 8) | (int(r) << 16);
|
||||
|
||||
//confidence
|
||||
//*(int*)&ptr[i*4 + 3] = (int(pointCloudData[i*4 + 3] * 255.0f) << 8) | (int(255) << 16);
|
||||
|
||||
}
|
||||
return LaserScan::backwardCompatibility(scanData, 0, 10, rtabmap::Transform::getIdentity());
|
||||
}
|
||||
return LaserScan();
|
||||
}
|
||||
|
||||
void CameraARCore::setScreenRotationAndSize(ScreenRotation colorCameraToDisplayRotation, int width, int height)
|
||||
{
|
||||
CameraMobile::setScreenRotationAndSize(colorCameraToDisplayRotation, width, height);
|
||||
if(arSession_)
|
||||
{
|
||||
int ret = static_cast<int>(colorCameraToDisplayRotation) + 1; // remove 90deg camera rotation
|
||||
if (ret > 3) {
|
||||
ret -= 4;
|
||||
}
|
||||
|
||||
ArSession_setDisplayGeometry(arSession_, ret, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
SensorData CameraARCore::captureImage(CameraInfo * info)
|
||||
{
|
||||
UScopeMutex lock(arSessionMutex_);
|
||||
//LOGI("Capturing image...");
|
||||
|
||||
SensorData data;
|
||||
if(!arSession_)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
if(textureId_ == 0)
|
||||
{
|
||||
glGenTextures(1, &textureId_);
|
||||
glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureId_);
|
||||
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
}
|
||||
if(textureId_!=0)
|
||||
ArSession_setCameraTextureName(arSession_, textureId_);
|
||||
|
||||
// Update session to get current frame and render camera background.
|
||||
if (ArSession_update(arSession_, arFrame_) != AR_SUCCESS) {
|
||||
LOGE("CameraARCore::captureImage() ArSession_update error");
|
||||
return data;
|
||||
}
|
||||
|
||||
// If display rotation changed (also includes view size change), we need to
|
||||
// re-query the uv coordinates for the on-screen portion of the camera image.
|
||||
int32_t geometry_changed = 0;
|
||||
ArFrame_getDisplayGeometryChanged(arSession_, arFrame_, &geometry_changed);
|
||||
if (geometry_changed != 0 || !uvs_initialized_) {
|
||||
ArFrame_transformCoordinates2d(
|
||||
arSession_, arFrame_, AR_COORDINATES_2D_OPENGL_NORMALIZED_DEVICE_COORDINATES,
|
||||
BackgroundRenderer::kNumVertices, BackgroundRenderer_kVertices, AR_COORDINATES_2D_TEXTURE_NORMALIZED,
|
||||
transformed_uvs_);
|
||||
UASSERT(transformed_uvs_);
|
||||
uvs_initialized_ = true;
|
||||
}
|
||||
|
||||
ArCamera* ar_camera;
|
||||
ArFrame_acquireCamera(arSession_, arFrame_, &ar_camera);
|
||||
|
||||
ArCamera_getViewMatrix(arSession_, ar_camera, glm::value_ptr(viewMatrix_));
|
||||
ArCamera_getProjectionMatrix(arSession_, ar_camera,
|
||||
/*near=*/0.1f, /*far=*/100.f,
|
||||
glm::value_ptr(projectionMatrix_));
|
||||
|
||||
// adjust origin
|
||||
if(!getOriginOffset().isNull())
|
||||
{
|
||||
viewMatrix_ = glm::inverse(rtabmap::glmFromTransform(rtabmap::opengl_world_T_rtabmap_world * getOriginOffset() *rtabmap::rtabmap_world_T_opengl_world)*glm::inverse(viewMatrix_));
|
||||
}
|
||||
|
||||
ArTrackingState camera_tracking_state;
|
||||
ArCamera_getTrackingState(arSession_, ar_camera, &camera_tracking_state);
|
||||
|
||||
Transform pose;
|
||||
CameraModel model;
|
||||
if(camera_tracking_state == AR_TRACKING_STATE_TRACKING)
|
||||
{
|
||||
// pose in OpenGL coordinates
|
||||
float pose_raw[7];
|
||||
ArCamera_getPose(arSession_, ar_camera, arPose_);
|
||||
ArPose_getPoseRaw(arSession_, arPose_, pose_raw);
|
||||
pose = Transform(pose_raw[4], pose_raw[5], pose_raw[6], pose_raw[0], pose_raw[1], pose_raw[2], pose_raw[3]);
|
||||
pose = rtabmap::rtabmap_world_T_opengl_world * pose * rtabmap::opengl_world_T_rtabmap_world;
|
||||
|
||||
Transform poseArCore = pose;
|
||||
if(pose.isNull())
|
||||
{
|
||||
LOGE("CameraARCore: Pose is null");
|
||||
}
|
||||
else
|
||||
{
|
||||
this->poseReceived(pose);
|
||||
// adjust origin
|
||||
if(!getOriginOffset().isNull())
|
||||
{
|
||||
pose = getOriginOffset() * pose;
|
||||
}
|
||||
info->odomPose = pose;
|
||||
}
|
||||
|
||||
// Get calibration parameters
|
||||
float fx,fy, cx, cy;
|
||||
int32_t width, height;
|
||||
ArCamera_getImageIntrinsics(arSession_, ar_camera, arCameraIntrinsics_);
|
||||
ArCameraIntrinsics_getFocalLength(arSession_, arCameraIntrinsics_, &fx, &fy);
|
||||
ArCameraIntrinsics_getPrincipalPoint(arSession_, arCameraIntrinsics_, &cx, &cy);
|
||||
ArCameraIntrinsics_getImageDimensions(arSession_, arCameraIntrinsics_, &width, &height);
|
||||
#ifndef DISABLE_LOG
|
||||
LOGI("%f %f %f %f %d %d", fx, fy, cx, cy, width, height);
|
||||
#endif
|
||||
|
||||
if(fx > 0 && fy > 0 && width > 0 && height > 0 && cx > 0 && cy > 0)
|
||||
{
|
||||
model = CameraModel(fx, fy, cx, cy, deviceTColorCamera_, 0, cv::Size(width, height));
|
||||
|
||||
ArPointCloud * pointCloud = nullptr;
|
||||
ArFrame_acquirePointCloud(arSession_, arFrame_, &pointCloud);
|
||||
|
||||
int32_t is_depth_supported = 0;
|
||||
ArSession_isDepthModeSupported(arSession_, AR_DEPTH_MODE_AUTOMATIC, &is_depth_supported);
|
||||
|
||||
ArImage * image = nullptr;
|
||||
ArStatus status = ArFrame_acquireCameraImage(arSession_, arFrame_, &image);
|
||||
if(status == AR_SUCCESS)
|
||||
{
|
||||
if(is_depth_supported)
|
||||
{
|
||||
LOGD("Acquire depth image!");
|
||||
ArImage * depthImage = nullptr;
|
||||
ArFrame_acquireDepthImage(arSession_, arFrame_, &depthImage);
|
||||
|
||||
ArImageFormat format;
|
||||
ArImage_getFormat(arSession_, depthImage, &format);
|
||||
if(format == AR_IMAGE_FORMAT_DEPTH16)
|
||||
{
|
||||
LOGD("Depth format detected!");
|
||||
int planeCount;
|
||||
ArImage_getNumberOfPlanes(arSession_, depthImage, &planeCount);
|
||||
LOGD("planeCount=%d", planeCount);
|
||||
UASSERT_MSG(planeCount == 1, uFormat("Error: getNumberOfPlanes() planceCount = %d", planeCount).c_str());
|
||||
const uint8_t *data = nullptr;
|
||||
int len = 0;
|
||||
int stride;
|
||||
int depth_width;
|
||||
int depth_height;
|
||||
ArImage_getWidth(arSession_, depthImage, &depth_width);
|
||||
ArImage_getHeight(arSession_, depthImage, &depth_height);
|
||||
ArImage_getPlaneRowStride(arSession_, depthImage, 0, &stride);
|
||||
ArImage_getPlaneData(arSession_, depthImage, 0, &data, &len);
|
||||
|
||||
LOGD("width=%d, height=%d, bytes=%d stride=%d", depth_width, depth_height, len, stride);
|
||||
|
||||
cv::Mat occlusionImage = cv::Mat(depth_height, depth_width, CV_16UC1, (void*)data).clone();
|
||||
|
||||
float scaleX = (float)depth_width / (float)width;
|
||||
float scaleY = (float)depth_height / (float)height;
|
||||
CameraModel occlusionModel(fx*scaleX, fy*scaleY, cx*scaleX, cy*scaleY, pose*deviceTColorCamera_, 0, cv::Size(depth_width, depth_height));
|
||||
this->setOcclusionImage(occlusionImage, occlusionModel);
|
||||
}
|
||||
ArImage_release(depthImage);
|
||||
}
|
||||
|
||||
int64_t timestamp_ns;
|
||||
ArImageFormat format;
|
||||
ArImage_getTimestamp(arSession_, image, ×tamp_ns);
|
||||
ArImage_getFormat(arSession_, image, &format);
|
||||
if(format == AR_IMAGE_FORMAT_YUV_420_888)
|
||||
{
|
||||
#ifndef DISABLE_LOG
|
||||
int32_t num_planes;
|
||||
ArImage_getNumberOfPlanes(arSession_, image, &num_planes);
|
||||
for(int i=0;i<num_planes; ++i)
|
||||
{
|
||||
int32_t pixel_stride;
|
||||
int32_t row_stride;
|
||||
ArImage_getPlanePixelStride(arSession_, image, i, &pixel_stride);
|
||||
ArImage_getPlaneRowStride(arSession_, image, i, &row_stride);
|
||||
LOGI("Plane %d/%d: pixel stride=%d, row stride=%d", i+1, num_planes, pixel_stride, row_stride);
|
||||
}
|
||||
#endif
|
||||
const uint8_t * plane_data;
|
||||
const uint8_t * plane_uv_data;
|
||||
int32_t data_length;
|
||||
ArImage_getPlaneData(arSession_, image, 0, &plane_data, &data_length);
|
||||
int32_t uv_data_length;
|
||||
ArImage_getPlaneData(arSession_, image, 2, &plane_uv_data, &uv_data_length);
|
||||
|
||||
if(plane_data != nullptr && data_length == height*width)
|
||||
{
|
||||
double stamp = double(timestamp_ns)/10e8;
|
||||
#ifndef DISABLE_LOG
|
||||
LOGI("data_length=%d stamp=%f", data_length, stamp);
|
||||
#endif
|
||||
cv::Mat rgb;
|
||||
if((long)plane_uv_data-(long)plane_data != data_length)
|
||||
{
|
||||
// The uv-plane is not concatenated to y plane in memory, so concatenate them
|
||||
cv::Mat yuv(height+height/2, width, CV_8UC1);
|
||||
memcpy(yuv.data, plane_data, data_length);
|
||||
memcpy(yuv.data+data_length, plane_uv_data, height/2*width);
|
||||
cv::cvtColor(yuv, rgb, cv::COLOR_YUV2BGR_NV21);
|
||||
}
|
||||
else
|
||||
{
|
||||
cv::cvtColor(cv::Mat(height+height/2, width, CV_8UC1, (void*)plane_data), rgb, cv::COLOR_YUV2BGR_NV21);
|
||||
}
|
||||
|
||||
std::vector<cv::KeyPoint> kpts;
|
||||
std::vector<cv::Point3f> kpts3;
|
||||
LaserScan scan;
|
||||
if(pointCloud)
|
||||
{
|
||||
int32_t points = 0;
|
||||
ArPointCloud_getNumberOfPoints(arSession_, pointCloud, &points);
|
||||
const float * pointCloudData = 0;
|
||||
ArPointCloud_getData(arSession_, pointCloud, &pointCloudData);
|
||||
#ifndef DISABLE_LOG
|
||||
LOGI("pointCloudData=%d size=%d", pointCloudData?1:0, points);
|
||||
#endif
|
||||
if(pointCloudData && points>0)
|
||||
{
|
||||
scan = scanFromPointCloudData(pointCloudData, points, poseArCore, model, rgb, &kpts, &kpts3);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGI("pointCloud empty");
|
||||
}
|
||||
|
||||
data = SensorData(scan, rgb, depthFromMotion_?getOcclusionImage():cv::Mat(), model, 0, stamp);
|
||||
data.setFeatures(kpts, kpts3, cv::Mat());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGE("CameraARCore: cannot convert image format %d", format);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGE("CameraARCore: failed to get rgb image (status=%d)", (int)status);
|
||||
}
|
||||
|
||||
ArImage_release(image);
|
||||
ArPointCloud_release(pointCloud);
|
||||
}
|
||||
}
|
||||
|
||||
ArCamera_release(ar_camera);
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
void CameraARCore::capturePoseOnly()
|
||||
{
|
||||
UScopeMutex lock(arSessionMutex_);
|
||||
//LOGI("Capturing image...");
|
||||
|
||||
if(!arSession_)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(textureId_ != 0)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureId_);
|
||||
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
ArSession_setCameraTextureName(arSession_, textureId_);
|
||||
}
|
||||
|
||||
// Update session to get current frame and render camera background.
|
||||
if (ArSession_update(arSession_, arFrame_) != AR_SUCCESS) {
|
||||
LOGE("CameraARCore::capturePoseOnly() ArSession_update error");
|
||||
return;
|
||||
}
|
||||
|
||||
// If display rotation changed (also includes view size change), we need to
|
||||
// re-query the uv coordinates for the on-screen portion of the camera image.
|
||||
int32_t geometry_changed = 0;
|
||||
ArFrame_getDisplayGeometryChanged(arSession_, arFrame_, &geometry_changed);
|
||||
if (geometry_changed != 0 || !uvs_initialized_) {
|
||||
ArFrame_transformCoordinates2d(
|
||||
arSession_, arFrame_, AR_COORDINATES_2D_OPENGL_NORMALIZED_DEVICE_COORDINATES,
|
||||
BackgroundRenderer::kNumVertices, BackgroundRenderer_kVertices, AR_COORDINATES_2D_TEXTURE_NORMALIZED,
|
||||
transformed_uvs_);
|
||||
UASSERT(transformed_uvs_);
|
||||
uvs_initialized_ = true;
|
||||
}
|
||||
|
||||
ArCamera* ar_camera;
|
||||
ArFrame_acquireCamera(arSession_, arFrame_, &ar_camera);
|
||||
|
||||
ArCamera_getViewMatrix(arSession_, ar_camera, glm::value_ptr(viewMatrix_));
|
||||
ArCamera_getProjectionMatrix(arSession_, ar_camera,
|
||||
/*near=*/0.1f, /*far=*/100.f,
|
||||
glm::value_ptr(projectionMatrix_));
|
||||
|
||||
// adjust origin
|
||||
if(!getOriginOffset().isNull())
|
||||
{
|
||||
viewMatrix_ = glm::inverse(rtabmap::glmFromTransform(rtabmap::opengl_world_T_rtabmap_world * getOriginOffset() *rtabmap::rtabmap_world_T_opengl_world)*glm::inverse(viewMatrix_));
|
||||
}
|
||||
|
||||
ArTrackingState camera_tracking_state;
|
||||
ArCamera_getTrackingState(arSession_, ar_camera, &camera_tracking_state);
|
||||
|
||||
Transform pose;
|
||||
CameraModel model;
|
||||
if(camera_tracking_state == AR_TRACKING_STATE_TRACKING)
|
||||
{
|
||||
// pose in OpenGL coordinates
|
||||
float pose_raw[7];
|
||||
ArCamera_getPose(arSession_, ar_camera, arPose_);
|
||||
ArPose_getPoseRaw(arSession_, arPose_, pose_raw);
|
||||
pose = Transform(pose_raw[4], pose_raw[5], pose_raw[6], pose_raw[0], pose_raw[1], pose_raw[2], pose_raw[3]);
|
||||
if(!pose.isNull())
|
||||
{
|
||||
pose = rtabmap::rtabmap_world_T_opengl_world * pose * rtabmap::opengl_world_T_rtabmap_world;
|
||||
this->poseReceived(pose);
|
||||
|
||||
if(!getOriginOffset().isNull())
|
||||
{
|
||||
pose = getOriginOffset() * pose;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t is_depth_supported = 0;
|
||||
ArSession_isDepthModeSupported(arSession_, AR_DEPTH_MODE_AUTOMATIC, &is_depth_supported);
|
||||
|
||||
if(is_depth_supported)
|
||||
{
|
||||
LOGD("Acquire depth image!");
|
||||
ArImage * depthImage = nullptr;
|
||||
ArFrame_acquireDepthImage(arSession_, arFrame_, &depthImage);
|
||||
|
||||
ArImageFormat format;
|
||||
ArImage_getFormat(arSession_, depthImage, &format);
|
||||
if(format == AR_IMAGE_FORMAT_DEPTH16)
|
||||
{
|
||||
LOGD("Depth format detected!");
|
||||
int planeCount;
|
||||
ArImage_getNumberOfPlanes(arSession_, depthImage, &planeCount);
|
||||
LOGD("planeCount=%d", planeCount);
|
||||
UASSERT_MSG(planeCount == 1, uFormat("Error: getNumberOfPlanes() planceCount = %d", planeCount).c_str());
|
||||
const uint8_t *data = nullptr;
|
||||
int len = 0;
|
||||
int stride;
|
||||
int width;
|
||||
int height;
|
||||
ArImage_getWidth(arSession_, depthImage, &width);
|
||||
ArImage_getHeight(arSession_, depthImage, &height);
|
||||
ArImage_getPlaneRowStride(arSession_, depthImage, 0, &stride);
|
||||
ArImage_getPlaneData(arSession_, depthImage, 0, &data, &len);
|
||||
|
||||
LOGD("width=%d, height=%d, bytes=%d stride=%d", width, height, len, stride);
|
||||
|
||||
cv::Mat occlusionImage = cv::Mat(height, width, CV_16UC1, (void*)data).clone();
|
||||
|
||||
float fx,fy, cx, cy;
|
||||
int32_t rgb_width, rgb_height;
|
||||
ArCamera_getImageIntrinsics(arSession_, ar_camera, arCameraIntrinsics_);
|
||||
ArCameraIntrinsics_getFocalLength(arSession_, arCameraIntrinsics_, &fx, &fy);
|
||||
ArCameraIntrinsics_getPrincipalPoint(arSession_, arCameraIntrinsics_, &cx, &cy);
|
||||
ArCameraIntrinsics_getImageDimensions(arSession_, arCameraIntrinsics_, &rgb_width, &rgb_height);
|
||||
|
||||
float scaleX = (float)width / (float)rgb_width;
|
||||
float scaleY = (float)height / (float)rgb_height;
|
||||
CameraModel occlusionModel(fx*scaleX, fy*scaleY, cx*scaleX, cy*scaleY, pose*deviceTColorCamera_, 0, cv::Size(width, height));
|
||||
this->setOcclusionImage(occlusionImage, occlusionModel);
|
||||
}
|
||||
ArImage_release(depthImage);
|
||||
}
|
||||
}
|
||||
|
||||
ArCamera_release(ar_camera);
|
||||
}
|
||||
|
||||
} /* namespace rtabmap */
|
||||
103
app/android/jni/CameraARCore.h
Normal file
103
app/android/jni/CameraARCore.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the Universite de Sherbrooke nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CAMERAARCORE_H_
|
||||
#define CAMERAARCORE_H_
|
||||
|
||||
#include "CameraMobile.h"
|
||||
#include <rtabmap/core/Camera.h>
|
||||
#include <rtabmap/core/GeodeticCoords.h>
|
||||
#include <rtabmap/utilite/UMutex.h>
|
||||
#include <rtabmap/utilite/USemaphore.h>
|
||||
#include <rtabmap/utilite/UEventsSender.h>
|
||||
#include <rtabmap/utilite/UThread.h>
|
||||
#include <rtabmap/utilite/UEvent.h>
|
||||
#include <rtabmap/utilite/UTimer.h>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <background_renderer.h>
|
||||
|
||||
#include <arcore_c_api.h>
|
||||
#include <camera/NdkCameraDevice.h>
|
||||
#include <camera/NdkCameraManager.h>
|
||||
#include <media/NdkImageReader.h>
|
||||
#include <android/native_window.h>
|
||||
|
||||
namespace rtabmap {
|
||||
|
||||
class CameraARCore : public CameraMobile {
|
||||
public:
|
||||
static LaserScan scanFromPointCloudData(
|
||||
const float * pointCloudData,
|
||||
int points,
|
||||
const Transform & pose,
|
||||
const CameraModel & model,
|
||||
const cv::Mat & rgb,
|
||||
std::vector<cv::KeyPoint> * kpts = 0,
|
||||
std::vector<cv::Point3f> * kpts3D = 0);
|
||||
|
||||
public:
|
||||
CameraARCore(void* env, void* context, void* activity, bool depthFromMotion = false, bool smoothing = false);
|
||||
virtual ~CameraARCore();
|
||||
|
||||
bool uvsInitialized() const {return uvs_initialized_;}
|
||||
const float* uvsTransformed() const {return transformed_uvs_;}
|
||||
void getVPMatrices(glm::mat4 & view, glm::mat4 & projection) const {view=viewMatrix_; projection=projectionMatrix_;}
|
||||
|
||||
virtual void setScreenRotationAndSize(ScreenRotation colorCameraToDisplayRotation, int width, int height);
|
||||
|
||||
virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = "");
|
||||
void setupGL();
|
||||
virtual void close(); // close Tango connection
|
||||
virtual std::string getSerial() const;
|
||||
GLuint getTextureId() const {return textureId_;}
|
||||
|
||||
void imageCallback(AImageReader *reader);
|
||||
|
||||
protected:
|
||||
virtual SensorData captureImage(CameraInfo * info = 0); // should be called in opengl thread
|
||||
virtual void capturePoseOnly();
|
||||
|
||||
private:
|
||||
rtabmap::Transform getPoseAtTimestamp(double timestamp);
|
||||
|
||||
private:
|
||||
void * env_;
|
||||
void * context_;
|
||||
void * activity_;
|
||||
ArSession* arSession_ = nullptr;
|
||||
ArConfig* arConfig_ = nullptr;
|
||||
ArFrame* arFrame_ = nullptr;
|
||||
ArCameraIntrinsics *arCameraIntrinsics_ = nullptr;
|
||||
ArPose * arPose_ = nullptr;
|
||||
bool arInstallRequested_;
|
||||
UMutex arSessionMutex_;
|
||||
|
||||
bool depthFromMotion_;
|
||||
};
|
||||
|
||||
} /* namespace rtabmap */
|
||||
#endif /* CAMERAARCORE_H_ */
|
||||
356
app/android/jni/CameraAREngine.cpp
Normal file
356
app/android/jni/CameraAREngine.cpp
Normal file
@@ -0,0 +1,356 @@
|
||||
/*
|
||||
Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the Universite de Sherbrooke nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "CameraAREngine.h"
|
||||
#include "util.h"
|
||||
#include "rtabmap/utilite/ULogger.h"
|
||||
#include "rtabmap/core/util3d_transforms.h"
|
||||
#include "rtabmap/core/OdometryEvent.h"
|
||||
#include "rtabmap/core/util2d.h"
|
||||
|
||||
#include <media/NdkImage.h>
|
||||
|
||||
namespace rtabmap {
|
||||
|
||||
|
||||
//////////////////////////////
|
||||
// CameraAREngine
|
||||
//////////////////////////////
|
||||
CameraAREngine::CameraAREngine(void* env, void* context, void* activity, bool smoothing):
|
||||
CameraMobile(smoothing),
|
||||
env_(env),
|
||||
context_(context),
|
||||
activity_(activity),
|
||||
arInstallRequested_(false)
|
||||
{
|
||||
glGenTextures(1, &textureId_);
|
||||
}
|
||||
|
||||
CameraAREngine::~CameraAREngine() {
|
||||
// Disconnect ARCore service
|
||||
close();
|
||||
|
||||
glDeleteTextures(1, &textureId_);
|
||||
}
|
||||
|
||||
std::string CameraAREngine::getSerial() const
|
||||
{
|
||||
return "AREngine";
|
||||
}
|
||||
|
||||
bool CameraAREngine::init(const std::string & calibrationFolder, const std::string & cameraName)
|
||||
{
|
||||
close();
|
||||
|
||||
UScopeMutex lock(arSessionMutex_);
|
||||
|
||||
HwArInstallStatus install_status;
|
||||
// If install was not yet requested, that means that we are resuming the
|
||||
// activity first time because of explicit user interaction (such as
|
||||
// launching the application)
|
||||
bool user_requested_install = !arInstallRequested_;
|
||||
|
||||
// === ATTENTION! ATTENTION! ATTENTION! ===
|
||||
// This method can and will fail in user-facing situations. Your
|
||||
// application must handle these cases at least somewhat gracefully. See
|
||||
// HelloAR Java sample code for reasonable behavior.
|
||||
HwArEnginesApk_requestInstall(env_, activity_, user_requested_install, &install_status);
|
||||
|
||||
switch (install_status)
|
||||
{
|
||||
case HWAR_INSTALL_STATUS_INSTALLED:
|
||||
break;
|
||||
case HWAR_INSTALL_STATUS_INSTALL_REQUESTED:
|
||||
arInstallRequested_ = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// === ATTENTION! ATTENTION! ATTENTION! ===
|
||||
// This method can and will fail in user-facing situations. Your
|
||||
// application must handle these cases at least somewhat gracefully. See
|
||||
// HelloAR Java sample code for reasonable behavior.
|
||||
UASSERT(HwArSession_create(env_, context_, &arSession_) == HWAR_SUCCESS);
|
||||
UASSERT(arSession_);
|
||||
|
||||
HwArConfig_create(arSession_, &arConfig_);
|
||||
UASSERT(arConfig_);
|
||||
|
||||
HwArConfig_setFocusMode(arSession_, arConfig_, HWAR_FOCUS_MODE_FIXED);
|
||||
UASSERT(HwArSession_configure(arSession_, arConfig_) == HWAR_SUCCESS);
|
||||
|
||||
HwArFrame_create(arSession_, &arFrame_);
|
||||
UASSERT(arFrame_);
|
||||
|
||||
HwArCameraIntrinsics_create(arSession_, &arCameraIntrinsics_); // May fail?!
|
||||
//UASSERT(arCameraIntrinsics_);
|
||||
|
||||
HwArPose_create(arSession_, nullptr, &arPose_);
|
||||
UASSERT(arPose_);
|
||||
|
||||
/// Sets the behavior of @ref ArSession_update(). See
|
||||
/// ::ArUpdateMode for available options.
|
||||
HwArConfig_setUpdateMode(arSession_, arConfig_, HWAR_UPDATE_MODE_BLOCKING);
|
||||
|
||||
deviceTColorCamera_ = opticalRotation;
|
||||
|
||||
// Required as ArSession_update does some off-screen OpenGL stuff...
|
||||
HwArSession_setCameraTextureName(arSession_, textureId_);
|
||||
|
||||
if (HwArSession_resume(arSession_) != HWAR_SUCCESS)
|
||||
{
|
||||
UERROR("Cannot resume camera!");
|
||||
// In a rare case (such as another camera app launching) the camera may be
|
||||
// given to a different app and so may not be available to this app. Handle
|
||||
// this properly and recreate the session at the next iteration.
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CameraAREngine::close()
|
||||
{
|
||||
UScopeMutex lock(arSessionMutex_);
|
||||
if (arCameraIntrinsics_ != nullptr)
|
||||
{
|
||||
HwArCameraIntrinsics_destroy(arSession_, arCameraIntrinsics_);
|
||||
}
|
||||
arCameraIntrinsics_ = nullptr;
|
||||
|
||||
if(arSession_!= nullptr)
|
||||
{
|
||||
HwArSession_destroy(arSession_);
|
||||
}
|
||||
arSession_ = nullptr;
|
||||
|
||||
if(arConfig_!= nullptr)
|
||||
{
|
||||
HwArConfig_destroy(arConfig_);
|
||||
}
|
||||
arConfig_ = nullptr;
|
||||
|
||||
if (arFrame_ != nullptr)
|
||||
{
|
||||
HwArFrame_destroy(arFrame_);
|
||||
}
|
||||
arFrame_ = nullptr;
|
||||
|
||||
if (arPose_ != nullptr)
|
||||
{
|
||||
HwArPose_destroy(arPose_);
|
||||
}
|
||||
arPose_ = nullptr;
|
||||
|
||||
CameraMobile::close();
|
||||
}
|
||||
|
||||
SensorData CameraAREngine::captureImage(CameraInfo * info)
|
||||
{
|
||||
UScopeMutex lock(arSessionMutex_);
|
||||
//LOGI("Capturing image...");
|
||||
|
||||
SensorData data;
|
||||
if(!arSession_)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
// Update session to get current frame and render camera background.
|
||||
if (HwArSession_update(arSession_, arFrame_) != HWAR_SUCCESS) {
|
||||
LOGE("CameraAREngine::captureImage() ArSession_update error");
|
||||
return data;
|
||||
}
|
||||
|
||||
HwArCamera* ar_camera;
|
||||
HwArFrame_acquireCamera(arSession_, arFrame_, &ar_camera);
|
||||
|
||||
HwArTrackingState camera_tracking_state;
|
||||
HwArCamera_getTrackingState(arSession_, ar_camera, &camera_tracking_state);
|
||||
|
||||
Transform pose;
|
||||
if(camera_tracking_state == HWAR_TRACKING_STATE_TRACKING)
|
||||
{
|
||||
// pose in OpenGL coordinates
|
||||
float pose_raw[7];
|
||||
HwArCamera_getPose(arSession_, ar_camera, arPose_);
|
||||
HwArPose_getPoseRaw(arSession_, arPose_, pose_raw);
|
||||
pose = Transform(pose_raw[4], pose_raw[5], pose_raw[6], pose_raw[0], pose_raw[1], pose_raw[2], pose_raw[3]);
|
||||
|
||||
// Get calibration parameters
|
||||
// FIXME: Hard-coded as getting intrinsics with the api fails
|
||||
float fx=492.689667,fy=492.606201, cx=323.594849, cy=234.659744;
|
||||
int32_t camWidth=640, camHeight=480;
|
||||
//HwArCamera_getImageIntrinsics(arSession_, ar_camera, arCameraIntrinsics_);
|
||||
//HwArCameraIntrinsics_getFocalLength(arSession_, arCameraIntrinsics_, &fx, &fy);
|
||||
//HwArCameraIntrinsics_getPrincipalPoint(arSession_, arCameraIntrinsics_, &cx, &cy);
|
||||
//HwArCameraIntrinsics_getImageDimensions(arSession_, arCameraIntrinsics_, &camWidth, &camHeight);
|
||||
LOGI("%f %f %f %f %d %d", fx, fy, cx, cy, camWidth, camHeight);
|
||||
|
||||
if(fx > 0 && fy > 0 && camWidth > 0 && camHeight > 0 && cx > 0 && cy > 0)
|
||||
{
|
||||
//ArPointCloud * point_cloud;
|
||||
//ArFrame_acquirePointCloud(ar_session_, ar_frame_, &point_cloud);
|
||||
|
||||
HwArImage * image = nullptr;
|
||||
HwArImage * depthImage = nullptr;
|
||||
HwArStatus statusRgb = HwArFrame_acquireCameraImage(arSession_, arFrame_, &image);
|
||||
HwArStatus statusDepth = HwArFrame_acquireDepthImage(arSession_, arFrame_, &depthImage);
|
||||
if(statusRgb == HWAR_SUCCESS && statusDepth == HWAR_SUCCESS)
|
||||
{
|
||||
int64_t timestamp_ns;
|
||||
HwArFrame_getTimestamp(arSession_, arFrame_, ×tamp_ns);
|
||||
|
||||
int planeCount;
|
||||
uint8_t *imageData = nullptr;
|
||||
int len = 0;
|
||||
int stride;
|
||||
int width;
|
||||
int height;
|
||||
const AImage* ndkImageRGB;
|
||||
HwArImage_getNdkImage(image, &ndkImageRGB);
|
||||
|
||||
AImage_getNumberOfPlanes(ndkImageRGB, &planeCount);
|
||||
AImage_getWidth(ndkImageRGB, &width);
|
||||
AImage_getHeight(ndkImageRGB, &height);
|
||||
AImage_getPlaneRowStride(ndkImageRGB, 0, &stride);
|
||||
AImage_getPlaneData(ndkImageRGB, 0, &imageData, &len);
|
||||
LOGI("RGB: width=%d, height=%d, bytes=%d stride=%d planeCount=%d", width, height, len, stride, planeCount);
|
||||
|
||||
cv::Mat outputRGB;
|
||||
if(imageData != nullptr && len>0)
|
||||
{
|
||||
cv::cvtColor(cv::Mat(height+height/2, width, CV_8UC1, (void*)imageData), outputRGB, cv::COLOR_YUV2BGR_NV21);
|
||||
}
|
||||
|
||||
//Depth
|
||||
const AImage* ndkImageDepth;
|
||||
HwArImage_getNdkImage(depthImage, &ndkImageDepth);
|
||||
AImage_getNumberOfPlanes(ndkImageDepth, &planeCount);
|
||||
AImage_getWidth(ndkImageDepth, &width);
|
||||
AImage_getHeight(ndkImageDepth, &height);
|
||||
AImage_getPlaneRowStride(ndkImageDepth, 0, &stride);
|
||||
AImage_getPlaneData(ndkImageDepth, 0, &imageData, &len);
|
||||
LOGI("Depth: width=%d, height=%d, bytes=%d stride=%d planeCount=%d", width, height, len, stride, planeCount);
|
||||
|
||||
cv::Mat outputDepth(height, width, CV_16UC1);
|
||||
uint16_t *dataShort = (uint16_t *)imageData;
|
||||
for (int y = 0; y < outputDepth.rows; ++y)
|
||||
{
|
||||
for (int x = 0; x < outputDepth.cols; ++x)
|
||||
{
|
||||
uint16_t depthSample = dataShort[y*outputDepth.cols + x];
|
||||
uint16_t depthRange = (depthSample & 0x1FFF); // first 3 bits are confidence
|
||||
outputDepth.at<uint16_t>(y,x) = depthRange;
|
||||
}
|
||||
}
|
||||
|
||||
if(!outputRGB.empty() && !outputDepth.empty())
|
||||
{
|
||||
double stamp = double(timestamp_ns)/10e8;
|
||||
CameraModel model = CameraModel(fx, fy, cx, cy, deviceTColorCamera_, 0, cv::Size(camWidth, camHeight));
|
||||
data = SensorData(outputRGB, outputDepth, model, 0, stamp);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGE("CameraAREngine: failed to get rgb image (status=%d %d)", (int)statusRgb, (int)statusDepth);
|
||||
}
|
||||
|
||||
HwArImage_release(image);
|
||||
HwArImage_release(depthImage);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGE("Invalid intrinsics!");
|
||||
}
|
||||
}
|
||||
|
||||
HwArCamera_release(ar_camera);
|
||||
|
||||
if(pose.isNull())
|
||||
{
|
||||
LOGE("CameraAREngine: Pose is null");
|
||||
}
|
||||
else
|
||||
{
|
||||
pose = rtabmap::rtabmap_world_T_opengl_world * pose * rtabmap::opengl_world_T_rtabmap_world;
|
||||
this->poseReceived(pose);
|
||||
// adjust origin
|
||||
if(!getOriginOffset().isNull())
|
||||
{
|
||||
pose = getOriginOffset() * pose;
|
||||
}
|
||||
info->odomPose = pose;
|
||||
}
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
void CameraAREngine::capturePoseOnly()
|
||||
{
|
||||
UScopeMutex lock(arSessionMutex_);
|
||||
//LOGI("Capturing image...");
|
||||
|
||||
SensorData data;
|
||||
if(!arSession_)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Update session to get current frame and render camera background.
|
||||
if (HwArSession_update(arSession_, arFrame_) != HWAR_SUCCESS) {
|
||||
LOGE("CameraARCore::captureImage() ArSession_update error");
|
||||
return;
|
||||
}
|
||||
|
||||
HwArCamera* ar_camera;
|
||||
HwArFrame_acquireCamera(arSession_, arFrame_, &ar_camera);
|
||||
|
||||
HwArTrackingState camera_tracking_state;
|
||||
HwArCamera_getTrackingState(arSession_, ar_camera, &camera_tracking_state);
|
||||
|
||||
Transform pose;
|
||||
CameraModel model;
|
||||
if(camera_tracking_state == HWAR_TRACKING_STATE_TRACKING)
|
||||
{
|
||||
// pose in OpenGL coordinates
|
||||
float pose_raw[7];
|
||||
HwArCamera_getPose(arSession_, ar_camera, arPose_);
|
||||
HwArPose_getPoseRaw(arSession_, arPose_, pose_raw);
|
||||
pose = Transform(pose_raw[4], pose_raw[5], pose_raw[6], pose_raw[0], pose_raw[1], pose_raw[2], pose_raw[3]);
|
||||
if(!pose.isNull())
|
||||
{
|
||||
pose = rtabmap::rtabmap_world_T_opengl_world * pose * rtabmap::opengl_world_T_rtabmap_world;
|
||||
this->poseReceived(pose);
|
||||
}
|
||||
}
|
||||
|
||||
HwArCamera_release(ar_camera);
|
||||
}
|
||||
|
||||
} /* namespace rtabmap */
|
||||
78
app/android/jni/CameraAREngine.h
Normal file
78
app/android/jni/CameraAREngine.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the Universite de Sherbrooke nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CAMERAARENGINE_H_
|
||||
#define CAMERAARENGINE_H_
|
||||
|
||||
#include "CameraMobile.h"
|
||||
#include <rtabmap/core/Camera.h>
|
||||
#include <rtabmap/core/GeodeticCoords.h>
|
||||
#include <rtabmap/utilite/UMutex.h>
|
||||
#include <rtabmap/utilite/USemaphore.h>
|
||||
#include <rtabmap/utilite/UEventsSender.h>
|
||||
#include <rtabmap/utilite/UThread.h>
|
||||
#include <rtabmap/utilite/UEvent.h>
|
||||
#include <rtabmap/utilite/UTimer.h>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
||||
#include <huawei_arengine_interface.h>
|
||||
|
||||
namespace rtabmap {
|
||||
|
||||
class CameraAREngine : public CameraMobile {
|
||||
public:
|
||||
CameraAREngine(void* env, void* context, void* activity, bool smoothing = false);
|
||||
virtual ~CameraAREngine();
|
||||
|
||||
virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = "");
|
||||
virtual void close(); // close Tango connection
|
||||
virtual std::string getSerial() const;
|
||||
|
||||
protected:
|
||||
virtual SensorData captureImage(CameraInfo * info = 0);
|
||||
virtual void capturePoseOnly();
|
||||
|
||||
private:
|
||||
rtabmap::Transform getPoseAtTimestamp(double timestamp);
|
||||
|
||||
private:
|
||||
void * env_;
|
||||
void * context_;
|
||||
void * activity_;
|
||||
HwArSession* arSession_ = nullptr;
|
||||
HwArConfig* arConfig_ = nullptr;
|
||||
HwArFrame* arFrame_ = nullptr;
|
||||
HwArCameraIntrinsics *arCameraIntrinsics_ = nullptr;
|
||||
HwArPose * arPose_ = nullptr;
|
||||
bool arInstallRequested_;
|
||||
GLuint textureId_;
|
||||
UMutex arSessionMutex_;
|
||||
|
||||
};
|
||||
|
||||
} /* namespace rtabmap */
|
||||
#endif /* CAMERAARENGINE_H_ */
|
||||
463
app/android/jni/CameraMobile.cpp
Normal file
463
app/android/jni/CameraMobile.cpp
Normal file
@@ -0,0 +1,463 @@
|
||||
/*
|
||||
Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the Universite de Sherbrooke nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "CameraMobile.h"
|
||||
#include "util.h"
|
||||
#include "rtabmap/utilite/ULogger.h"
|
||||
#include "rtabmap/core/util3d_transforms.h"
|
||||
#include "rtabmap/core/OdometryEvent.h"
|
||||
#include "rtabmap/core/util2d.h"
|
||||
#include <glm/gtx/transform.hpp>
|
||||
|
||||
namespace rtabmap {
|
||||
|
||||
#define nullptr 0
|
||||
|
||||
//////////////////////////////
|
||||
// CameraMobile
|
||||
//////////////////////////////
|
||||
const float CameraMobile::bilateralFilteringSigmaS = 2.0f;
|
||||
const float CameraMobile::bilateralFilteringSigmaR = 0.075f;
|
||||
|
||||
const rtabmap::Transform CameraMobile::opticalRotation = Transform(
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
-1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, -1.0f, 0.0f, 0.0f);
|
||||
const rtabmap::Transform CameraMobile::opticalRotationInv = Transform(
|
||||
0.0f, -1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, -1.0f, 0.0f,
|
||||
1.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
CameraMobile::CameraMobile(bool smoothing) :
|
||||
Camera(10),
|
||||
deviceTColorCamera_(Transform::getIdentity()),
|
||||
spinOncePreviousStamp_(0.0),
|
||||
textureId_(0),
|
||||
uvs_initialized_(false),
|
||||
previousStamp_(0.0),
|
||||
stampEpochOffset_(0.0),
|
||||
smoothing_(smoothing),
|
||||
colorCameraToDisplayRotation_(ROTATION_0),
|
||||
originUpdate_(false)
|
||||
{
|
||||
}
|
||||
|
||||
CameraMobile::~CameraMobile() {
|
||||
// Disconnect camera service
|
||||
close();
|
||||
}
|
||||
|
||||
bool CameraMobile::init(const std::string &, const std::string &)
|
||||
{
|
||||
deviceTColorCamera_ = opticalRotation;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CameraMobile::close()
|
||||
{
|
||||
previousPose_.setNull();
|
||||
previousStamp_ = 0.0;
|
||||
lastKnownGPS_ = GPS();
|
||||
lastEnvSensors_.clear();
|
||||
originOffset_ = Transform();
|
||||
originUpdate_ = false;
|
||||
pose_ = Transform();
|
||||
data_ = SensorData();
|
||||
|
||||
if(textureId_ != 0)
|
||||
{
|
||||
glDeleteTextures(1, &textureId_);
|
||||
textureId_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CameraMobile::resetOrigin()
|
||||
{
|
||||
previousPose_.setNull();
|
||||
previousStamp_ = 0.0;
|
||||
lastKnownGPS_ = GPS();
|
||||
lastEnvSensors_.clear();
|
||||
pose_ = Transform();
|
||||
data_ = SensorData();
|
||||
originUpdate_ = true;
|
||||
}
|
||||
|
||||
void CameraMobile::poseReceived(const Transform & pose)
|
||||
{
|
||||
if(!pose.isNull())
|
||||
{
|
||||
// send pose of the camera (without optical rotation)
|
||||
Transform p = pose*deviceTColorCamera_;
|
||||
if(originUpdate_)
|
||||
{
|
||||
originOffset_ = p.translation().inverse();
|
||||
originUpdate_ = false;
|
||||
}
|
||||
|
||||
if(!originOffset_.isNull())
|
||||
{
|
||||
this->post(new PoseEvent(originOffset_*p));
|
||||
}
|
||||
else
|
||||
{
|
||||
this->post(new PoseEvent(p));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CameraMobile::isCalibrated() const
|
||||
{
|
||||
return model_.isValidForProjection();
|
||||
}
|
||||
|
||||
void CameraMobile::setGPS(const GPS & gps)
|
||||
{
|
||||
lastKnownGPS_ = gps;
|
||||
}
|
||||
|
||||
void CameraMobile::setData(const SensorData & data, const Transform & pose, const glm::mat4 & viewMatrix, const glm::mat4 & projectionMatrix, const float * texCoord)
|
||||
{
|
||||
LOGD("CameraMobile::setData pose=%s stamp=%f", pose.prettyPrint().c_str(), data.stamp());
|
||||
data_ = data;
|
||||
pose_ = pose;
|
||||
|
||||
viewMatrix_ = viewMatrix;
|
||||
projectionMatrix_ = projectionMatrix;
|
||||
|
||||
// adjust origin
|
||||
if(!originOffset_.isNull())
|
||||
{
|
||||
pose_ = originOffset_ * pose_;
|
||||
viewMatrix_ = glm::inverse(rtabmap::glmFromTransform(rtabmap::opengl_world_T_rtabmap_world * originOffset_ *rtabmap::rtabmap_world_T_opengl_world)*glm::inverse(viewMatrix_));
|
||||
}
|
||||
|
||||
if(textureId_ == 0)
|
||||
{
|
||||
glGenTextures(1, &textureId_);
|
||||
}
|
||||
|
||||
if(texCoord)
|
||||
{
|
||||
memcpy(transformed_uvs_, texCoord, 8*sizeof(float));
|
||||
uvs_initialized_ = true;
|
||||
}
|
||||
|
||||
LOGD("CameraMobile::setData textureId_=%d", (int)textureId_);
|
||||
|
||||
if(textureId_ != 0 && texCoord != 0)
|
||||
{
|
||||
cv::Mat rgbImage;
|
||||
cv::cvtColor(data.imageRaw(), rgbImage, cv::COLOR_BGR2RGBA);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, textureId_);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||
//glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
//glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
|
||||
//glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rgbImage.cols, rgbImage.rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbImage.data);
|
||||
|
||||
GLint error = glGetError();
|
||||
if(error != GL_NO_ERROR)
|
||||
{
|
||||
LOGE("OpenGL: Could not allocate texture (0x%x)\n", error);
|
||||
textureId_ = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CameraMobile::addEnvSensor(int type, float value)
|
||||
{
|
||||
lastEnvSensors_.insert(std::make_pair((EnvSensor::Type)type, EnvSensor((EnvSensor::Type)type, value)));
|
||||
}
|
||||
|
||||
void CameraMobile::spinOnce()
|
||||
{
|
||||
if(!this->isRunning())
|
||||
{
|
||||
bool ignoreFrame = false;
|
||||
//float rate = 10.0f; // maximum 10 FPS for image data
|
||||
double now = UTimer::now();
|
||||
/*if(rate>0.0f)
|
||||
{
|
||||
if((spinOncePreviousStamp_>=0.0 && now>spinOncePreviousStamp_ && now - spinOncePreviousStamp_ < 1.0f/rate) ||
|
||||
((spinOncePreviousStamp_<=0.0 || now<=spinOncePreviousStamp_) && spinOnceFrameRateTimer_.getElapsedTime() < 1.0f/rate))
|
||||
{
|
||||
ignoreFrame = true;
|
||||
}
|
||||
}*/
|
||||
|
||||
if(!ignoreFrame)
|
||||
{
|
||||
spinOnceFrameRateTimer_.start();
|
||||
spinOncePreviousStamp_ = now;
|
||||
mainLoop();
|
||||
}
|
||||
else
|
||||
{
|
||||
// just send pose
|
||||
capturePoseOnly();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CameraMobile::mainLoopBegin()
|
||||
{
|
||||
double t = cameraStartedTime_.elapsed();
|
||||
if(t < 5.0)
|
||||
{
|
||||
uSleep((5.0-t)*1000); // just to make sure that the camera is started
|
||||
}
|
||||
}
|
||||
|
||||
void CameraMobile::mainLoop()
|
||||
{
|
||||
CameraInfo info;
|
||||
SensorData data = this->captureImage(&info);
|
||||
|
||||
if(data.isValid() && !info.odomPose.isNull())
|
||||
{
|
||||
if(lastKnownGPS_.stamp() > 0.0 && data.stamp()-lastKnownGPS_.stamp()<1.0)
|
||||
{
|
||||
data.setGPS(lastKnownGPS_);
|
||||
}
|
||||
else if(lastKnownGPS_.stamp()>0.0)
|
||||
{
|
||||
LOGD("GPS too old (current time=%f, gps time = %f)", data.stamp(), lastKnownGPS_.stamp());
|
||||
}
|
||||
|
||||
if(lastEnvSensors_.size())
|
||||
{
|
||||
data.setEnvSensors(lastEnvSensors_);
|
||||
lastEnvSensors_.clear();
|
||||
}
|
||||
|
||||
if(smoothing_ && !data.depthRaw().empty())
|
||||
{
|
||||
//UTimer t;
|
||||
data.setDepthOrRightRaw(rtabmap::util2d::fastBilateralFiltering(data.depthRaw(), bilateralFilteringSigmaS, bilateralFilteringSigmaR));
|
||||
//LOGD("Bilateral filtering, time=%fs", t.ticks());
|
||||
}
|
||||
|
||||
// Rotate image depending on the camera orientation
|
||||
if(colorCameraToDisplayRotation_ == ROTATION_90)
|
||||
{
|
||||
UDEBUG("ROTATION_90");
|
||||
cv::Mat rgb, depth;
|
||||
cv::Mat rgbt(data.imageRaw().cols, data.imageRaw().rows, data.imageRaw().type());
|
||||
cv::flip(data.imageRaw(),rgb,1);
|
||||
cv::transpose(rgb,rgbt);
|
||||
rgb = rgbt;
|
||||
cv::Mat deptht(data.depthRaw().cols, data.depthRaw().rows, data.depthRaw().type());
|
||||
cv::flip(data.depthRaw(),depth,1);
|
||||
cv::transpose(depth,deptht);
|
||||
depth = deptht;
|
||||
CameraModel model = data.cameraModels()[0];
|
||||
cv::Size sizet(model.imageHeight(), model.imageWidth());
|
||||
model = CameraModel(
|
||||
model.fy(),
|
||||
model.fx(),
|
||||
model.cy(),
|
||||
model.cx()>0?model.imageWidth()-model.cx():0,
|
||||
model.localTransform()*rtabmap::Transform(0,-1,0,0, 1,0,0,0, 0,0,1,0));
|
||||
model.setImageSize(sizet);
|
||||
data.setRGBDImage(rgb, depth, model);
|
||||
|
||||
std::vector<cv::KeyPoint> keypoints = data.keypoints();
|
||||
for(size_t i=0; i<keypoints.size(); ++i)
|
||||
{
|
||||
keypoints[i].pt.x = data.keypoints()[i].pt.y;
|
||||
keypoints[i].pt.y = rgb.rows - data.keypoints()[i].pt.x;
|
||||
}
|
||||
data.setFeatures(keypoints, data.keypoints3D(), cv::Mat());
|
||||
}
|
||||
else if(colorCameraToDisplayRotation_ == ROTATION_180)
|
||||
{
|
||||
UDEBUG("ROTATION_180");
|
||||
cv::Mat rgb, depth;
|
||||
cv::flip(data.imageRaw(),rgb,1);
|
||||
cv::flip(rgb,rgb,0);
|
||||
cv::flip(data.depthOrRightRaw(),depth,1);
|
||||
cv::flip(depth,depth,0);
|
||||
CameraModel model = data.cameraModels()[0];
|
||||
cv::Size sizet(model.imageWidth(), model.imageHeight());
|
||||
model = CameraModel(
|
||||
model.fx(),
|
||||
model.fy(),
|
||||
model.cx()>0?model.imageWidth()-model.cx():0,
|
||||
model.cy()>0?model.imageHeight()-model.cy():0,
|
||||
model.localTransform()*rtabmap::Transform(0,0,0,0,0,1,0));
|
||||
model.setImageSize(sizet);
|
||||
data.setRGBDImage(rgb, depth, model);
|
||||
|
||||
std::vector<cv::KeyPoint> keypoints = data.keypoints();
|
||||
for(size_t i=0; i<keypoints.size(); ++i)
|
||||
{
|
||||
keypoints[i].pt.x = rgb.cols - data.keypoints()[i].pt.x;
|
||||
keypoints[i].pt.y = rgb.rows - data.keypoints()[i].pt.y;
|
||||
}
|
||||
data.setFeatures(keypoints, data.keypoints3D(), cv::Mat());
|
||||
}
|
||||
else if(colorCameraToDisplayRotation_ == ROTATION_270)
|
||||
{
|
||||
UDEBUG("ROTATION_270");
|
||||
cv::Mat rgb(data.imageRaw().cols, data.imageRaw().rows, data.imageRaw().type());
|
||||
cv::transpose(data.imageRaw(),rgb);
|
||||
cv::flip(rgb,rgb,1);
|
||||
cv::Mat depth(data.depthOrRightRaw().cols, data.depthOrRightRaw().rows, data.depthOrRightRaw().type());
|
||||
cv::transpose(data.depthOrRightRaw(),depth);
|
||||
cv::flip(depth,depth,1);
|
||||
CameraModel model = data.cameraModels()[0];
|
||||
cv::Size sizet(model.imageHeight(), model.imageWidth());
|
||||
model = CameraModel(
|
||||
model.fy(),
|
||||
model.fx(),
|
||||
model.cy()>0?model.imageHeight()-model.cy():0,
|
||||
model.cx(),
|
||||
model.localTransform()*rtabmap::Transform(0,1,0,0, -1,0,0,0, 0,0,1,0));
|
||||
model.setImageSize(sizet);
|
||||
data.setRGBDImage(rgb, depth, model);
|
||||
|
||||
std::vector<cv::KeyPoint> keypoints = data.keypoints();
|
||||
for(size_t i=0; i<keypoints.size(); ++i)
|
||||
{
|
||||
keypoints[i].pt.x = rgb.cols - data.keypoints()[i].pt.y;
|
||||
keypoints[i].pt.y = data.keypoints()[i].pt.x;
|
||||
}
|
||||
data.setFeatures(keypoints, data.keypoints3D(), cv::Mat());
|
||||
}
|
||||
|
||||
rtabmap::Transform pose = info.odomPose;
|
||||
data.setGroundTruth(Transform());
|
||||
|
||||
// convert stamp to epoch
|
||||
bool firstFrame = previousPose_.isNull();
|
||||
if(firstFrame)
|
||||
{
|
||||
stampEpochOffset_ = UTimer::now()-data.stamp();
|
||||
}
|
||||
data.setStamp(stampEpochOffset_ + data.stamp());
|
||||
OdometryInfo info;
|
||||
if(!firstFrame)
|
||||
{
|
||||
info.interval = data.stamp()-previousStamp_;
|
||||
info.transform = previousPose_.inverse() * pose;
|
||||
}
|
||||
// linear cov = 0.0001
|
||||
info.reg.covariance = cv::Mat::eye(6,6,CV_64FC1) * (firstFrame?9999.0:0.0001);
|
||||
if(!firstFrame)
|
||||
{
|
||||
// angular cov = 0.000001
|
||||
info.reg.covariance.at<double>(3,3) *= 0.01;
|
||||
info.reg.covariance.at<double>(4,4) *= 0.01;
|
||||
info.reg.covariance.at<double>(5,5) *= 0.01;
|
||||
}
|
||||
LOGI("Publish odometry message (variance=%f)", firstFrame?9999:0.0001);
|
||||
this->post(new OdometryEvent(data, pose, info));
|
||||
previousPose_ = pose;
|
||||
previousStamp_ = data.stamp();
|
||||
}
|
||||
else if(!this->isKilled() && info.odomPose.isNull())
|
||||
{
|
||||
LOGW("Odometry lost");
|
||||
this->post(new OdometryEvent());
|
||||
}
|
||||
}
|
||||
|
||||
SensorData CameraMobile::captureImage(CameraInfo * info)
|
||||
{
|
||||
if(info)
|
||||
{
|
||||
info->odomPose = pose_;
|
||||
}
|
||||
return data_;
|
||||
}
|
||||
|
||||
LaserScan CameraMobile::scanFromPointCloudData(
|
||||
const cv::Mat & pointCloudData,
|
||||
int points,
|
||||
const Transform & pose,
|
||||
const CameraModel & model,
|
||||
const cv::Mat & rgb,
|
||||
std::vector<cv::KeyPoint> * kpts,
|
||||
std::vector<cv::Point3f> * kpts3D,
|
||||
int kptsSize)
|
||||
{
|
||||
if(!pointCloudData.empty())
|
||||
{
|
||||
cv::Mat scanData(1, pointCloudData.cols, CV_32FC4);
|
||||
float * ptr = scanData.ptr<float>();
|
||||
const float * inPtr = pointCloudData.ptr<float>();
|
||||
int ic = pointCloudData.channels();
|
||||
UASSERT(pointCloudData.depth() == CV_32F && ic >= 3);
|
||||
|
||||
int oi = 0;
|
||||
for(unsigned int i=0;i<points; ++i)
|
||||
{
|
||||
cv::Point3f pt(inPtr[i*ic], inPtr[i*ic + 1], inPtr[i*ic + 2]);
|
||||
pt = util3d::transformPoint(pt, pose.inverse()*rtabmap_world_T_opengl_world);
|
||||
ptr[oi*4] = pt.x;
|
||||
ptr[oi*4 + 1] = pt.y;
|
||||
ptr[oi*4 + 2] = pt.z;
|
||||
|
||||
//get color from rgb image
|
||||
cv::Point3f org= pt;
|
||||
pt = util3d::transformPoint(pt, opticalRotationInv);
|
||||
if(pt.z > 0)
|
||||
{
|
||||
int u,v;
|
||||
model.reproject(pt.x, pt.y, pt.z, u, v);
|
||||
unsigned char r=255,g=255,b=255;
|
||||
if(model.inFrame(u, v))
|
||||
{
|
||||
b=rgb.at<cv::Vec3b>(v,u).val[0];
|
||||
g=rgb.at<cv::Vec3b>(v,u).val[1];
|
||||
r=rgb.at<cv::Vec3b>(v,u).val[2];
|
||||
if(kpts)
|
||||
kpts->push_back(cv::KeyPoint(u,v,kptsSize));
|
||||
if(kpts3D)
|
||||
kpts3D->push_back(org);
|
||||
|
||||
*(int*)&ptr[oi*4 + 3] = int(b) | (int(g) << 8) | (int(r) << 16);
|
||||
++oi;
|
||||
}
|
||||
}
|
||||
//confidence
|
||||
//*(int*)&ptr[i*4 + 3] = (int(pointCloudData[i*4 + 3] * 255.0f) << 8) | (int(255) << 16);
|
||||
|
||||
}
|
||||
return LaserScan::backwardCompatibility(scanData.colRange(0, oi), 0, 10, rtabmap::Transform::getIdentity());
|
||||
}
|
||||
return LaserScan();
|
||||
}
|
||||
|
||||
} /* namespace rtabmap */
|
||||
163
app/android/jni/CameraMobile.h
Normal file
163
app/android/jni/CameraMobile.h
Normal file
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the Universite de Sherbrooke nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CAMERAMOBILE_H_
|
||||
#define CAMERAMOBILE_H_
|
||||
|
||||
#include <rtabmap/core/Camera.h>
|
||||
#include <rtabmap/core/GeodeticCoords.h>
|
||||
#include <rtabmap/utilite/UMutex.h>
|
||||
#include <rtabmap/utilite/USemaphore.h>
|
||||
#include <rtabmap/utilite/UEventsSender.h>
|
||||
#include <rtabmap/utilite/UThread.h>
|
||||
#include <rtabmap/utilite/UEvent.h>
|
||||
#include <rtabmap/utilite/UTimer.h>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include "util.h"
|
||||
|
||||
namespace rtabmap {
|
||||
|
||||
class CameraInfoEvent: public UEvent
|
||||
{
|
||||
public:
|
||||
CameraInfoEvent(int type, const std::string & key, const std::string & value) : type_(type), key_(key), value_(value) {}
|
||||
virtual std::string getClassName() const {return "CameraInfoEvent";}
|
||||
int type() const {return type_;}
|
||||
const std::string & key() const {return key_;}
|
||||
const std::string & value() const {return value_;}
|
||||
|
||||
private:
|
||||
int type_;
|
||||
std::string key_;
|
||||
std::string value_;
|
||||
|
||||
};
|
||||
|
||||
class PoseEvent: public UEvent
|
||||
{
|
||||
public:
|
||||
PoseEvent(const Transform & pose) : pose_(pose) {}
|
||||
virtual std::string getClassName() const {return "PoseEvent";}
|
||||
const Transform & pose() const {return pose_;}
|
||||
|
||||
private:
|
||||
Transform pose_;
|
||||
};
|
||||
|
||||
class CameraMobile : public Camera, public UThread, public UEventsSender {
|
||||
public:
|
||||
static const float bilateralFilteringSigmaS;
|
||||
static const float bilateralFilteringSigmaR;
|
||||
|
||||
static const rtabmap::Transform opticalRotation;
|
||||
static const rtabmap::Transform opticalRotationInv;
|
||||
|
||||
public:
|
||||
static LaserScan scanFromPointCloudData(
|
||||
const cv::Mat & pointCloudData,
|
||||
int points,
|
||||
const Transform & pose,
|
||||
const CameraModel & model,
|
||||
const cv::Mat & rgb,
|
||||
std::vector<cv::KeyPoint> * kpts = 0,
|
||||
std::vector<cv::Point3f> * kpts3D = 0,
|
||||
int kptsSize = 3);
|
||||
|
||||
public:
|
||||
CameraMobile(bool smoothing = false);
|
||||
virtual ~CameraMobile();
|
||||
|
||||
// abstract functions
|
||||
virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = "");
|
||||
virtual void close(); // inherited classes should call its parent in their close().
|
||||
virtual std::string getSerial() const {return "CameraMobile";}
|
||||
|
||||
const Transform & getOriginOffset() const {return originOffset_;} // in rtabmap frame
|
||||
void resetOrigin();
|
||||
virtual bool isCalibrated() const;
|
||||
|
||||
void poseReceived(const Transform & pose); // in rtabmap frame
|
||||
|
||||
const CameraModel & getCameraModel() const {return model_;}
|
||||
const Transform & getDeviceTColorCamera() const {return deviceTColorCamera_;}
|
||||
void setSmoothing(bool enabled) {smoothing_ = enabled;}
|
||||
virtual void setScreenRotationAndSize(ScreenRotation colorCameraToDisplayRotation, int width, int height) {colorCameraToDisplayRotation_ = colorCameraToDisplayRotation;}
|
||||
void setGPS(const GPS & gps);
|
||||
void addEnvSensor(int type, float value);
|
||||
void setData(const SensorData & data, const Transform & pose, const glm::mat4 & viewMatrix, const glm::mat4 & projectionMatrix, const float * texCoord);
|
||||
|
||||
void spinOnce(); // Should only be called if not thread is not running, otherwise it does nothing
|
||||
|
||||
GLuint getTextureId() {return textureId_;}
|
||||
bool uvsInitialized() const {return uvs_initialized_;}
|
||||
const float* uvsTransformed() const {return transformed_uvs_;}
|
||||
void getVPMatrices(glm::mat4 & view, glm::mat4 & projection) const {view=viewMatrix_; projection=projectionMatrix_;}
|
||||
ScreenRotation getScreenRotation() const {return colorCameraToDisplayRotation_;}
|
||||
|
||||
void setOcclusionImage(const cv::Mat & image, const CameraModel & model) {occlusionModel_ = model; occlusionImage_ = image;}
|
||||
const cv::Mat & getOcclusionImage(CameraModel * model=0) const {if(model)*model=occlusionModel_; return occlusionImage_; }
|
||||
|
||||
protected:
|
||||
virtual SensorData captureImage(CameraInfo * info = 0);
|
||||
virtual void capturePoseOnly() {}
|
||||
|
||||
virtual void mainLoopBegin();
|
||||
virtual void mainLoop();
|
||||
|
||||
protected:
|
||||
CameraModel model_; // local transform is the device to camera optical rotation in rtabmap frame
|
||||
Transform deviceTColorCamera_; // device to camera optical rotation in rtabmap frame
|
||||
UTimer spinOnceFrameRateTimer_;
|
||||
double spinOncePreviousStamp_;
|
||||
|
||||
GLuint textureId_;
|
||||
glm::mat4 viewMatrix_;
|
||||
glm::mat4 projectionMatrix_;
|
||||
float transformed_uvs_[8];
|
||||
bool uvs_initialized_ = false;
|
||||
|
||||
private:
|
||||
Transform previousPose_;
|
||||
double previousStamp_;
|
||||
UTimer cameraStartedTime_;
|
||||
double stampEpochOffset_;
|
||||
bool smoothing_;
|
||||
ScreenRotation colorCameraToDisplayRotation_;
|
||||
GPS lastKnownGPS_;
|
||||
EnvSensors lastEnvSensors_;
|
||||
Transform originOffset_;
|
||||
bool originUpdate_;
|
||||
|
||||
SensorData data_;
|
||||
Transform pose_;
|
||||
|
||||
cv::Mat occlusionImage_;
|
||||
CameraModel occlusionModel_;
|
||||
};
|
||||
|
||||
} /* namespace rtabmap */
|
||||
#endif /* CAMERATANGO_H_ */
|
||||
894
app/android/jni/CameraTango.cpp
Normal file
894
app/android/jni/CameraTango.cpp
Normal file
@@ -0,0 +1,894 @@
|
||||
/*
|
||||
Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the Universite de Sherbrooke nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "CameraTango.h"
|
||||
#include "util.h"
|
||||
#include "rtabmap/utilite/ULogger.h"
|
||||
#include "rtabmap/core/util3d_transforms.h"
|
||||
#include "rtabmap/core/OdometryEvent.h"
|
||||
#include "rtabmap/core/util2d.h"
|
||||
#include <tango_client_api.h>
|
||||
#include <tango_support_api.h>
|
||||
#include "tango-gl/camera.h"
|
||||
|
||||
namespace rtabmap {
|
||||
|
||||
#define nullptr 0
|
||||
const int kVersionStringLength = 128;
|
||||
const int holeSize = 5;
|
||||
const float maxDepthError = 0.10;
|
||||
const int scanDownsampling = 1;
|
||||
|
||||
//android phone
|
||||
//11 10 01 00 // portrait
|
||||
//01 11 00 10 // left
|
||||
//10 00 11 01 // right
|
||||
//00 01 10 11 // down
|
||||
|
||||
const float kTextureCoords0[] = {1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0};
|
||||
const float kTextureCoords90[] = {0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0};
|
||||
const float kTextureCoords180[] = {0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0};
|
||||
const float kTextureCoords270[] = {1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0};
|
||||
|
||||
// Callbacks
|
||||
void onPointCloudAvailableRouter(void* context, const TangoPointCloud* point_cloud)
|
||||
{
|
||||
CameraTango* app = static_cast<CameraTango*>(context);
|
||||
if(point_cloud->num_points>0)
|
||||
{
|
||||
app->cloudReceived(cv::Mat(1, point_cloud->num_points, CV_32FC4, point_cloud->points[0]), point_cloud->timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
void onFrameAvailableRouter(void* context, TangoCameraId id, const TangoImageBuffer* color)
|
||||
{
|
||||
CameraTango* app = static_cast<CameraTango*>(context);
|
||||
|
||||
cv::Mat tangoImage;
|
||||
if(color->format == TANGO_HAL_PIXEL_FORMAT_RGBA_8888)
|
||||
{
|
||||
tangoImage = cv::Mat(color->height, color->width, CV_8UC4, color->data);
|
||||
}
|
||||
else if(color->format == TANGO_HAL_PIXEL_FORMAT_YV12)
|
||||
{
|
||||
tangoImage = cv::Mat(color->height+color->height/2, color->width, CV_8UC1, color->data);
|
||||
}
|
||||
else if(color->format == TANGO_HAL_PIXEL_FORMAT_YCrCb_420_SP)
|
||||
{
|
||||
tangoImage = cv::Mat(color->height+color->height/2, color->width, CV_8UC1, color->data);
|
||||
}
|
||||
else if(color->format == 35)
|
||||
{
|
||||
tangoImage = cv::Mat(color->height+color->height/2, color->width, CV_8UC1, color->data);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGE("Not supported color format : %d.", color->format);
|
||||
}
|
||||
|
||||
if(!tangoImage.empty())
|
||||
{
|
||||
app->rgbReceived(tangoImage, (unsigned int)color->format, color->timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
void onPoseAvailableRouter(void* context, const TangoPoseData* pose)
|
||||
{
|
||||
if(pose->status_code == TANGO_POSE_VALID)
|
||||
{
|
||||
CameraTango* app = static_cast<CameraTango*>(context);
|
||||
app->poseReceived(rtabmap_world_T_tango_world * app->tangoPoseToTransform(pose) * tango_device_T_rtabmap_world);
|
||||
}
|
||||
}
|
||||
|
||||
void onTangoEventAvailableRouter(void* context, const TangoEvent* event)
|
||||
{
|
||||
CameraTango* app = static_cast<CameraTango*>(context);
|
||||
app->tangoEventReceived(event->type, event->event_key, event->event_value);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// CameraTango
|
||||
//////////////////////////////
|
||||
CameraTango::CameraTango(bool colorCamera, int decimation, bool publishRawScan, bool smoothing) :
|
||||
CameraMobile(smoothing),
|
||||
tango_config_(0),
|
||||
colorCamera_(colorCamera),
|
||||
decimation_(decimation),
|
||||
rawScanPublished_(publishRawScan),
|
||||
tangoColorType_(0),
|
||||
tangoColorStamp_(0)
|
||||
{
|
||||
UASSERT(decimation >= 1);
|
||||
}
|
||||
|
||||
CameraTango::~CameraTango() {
|
||||
// Disconnect Tango service
|
||||
close();
|
||||
}
|
||||
|
||||
// Compute fisheye distorted coordinates from undistorted coordinates.
|
||||
// The distortion model used by the Tango fisheye camera is called FOV and is
|
||||
// described in 'Straight lines have to be straight' by Frederic Devernay and
|
||||
// Olivier Faugeras. See https://hal.inria.fr/inria-00267247/document.
|
||||
// Tango ROS Streamer: https://github.com/Intermodalics/tango_ros/blob/master/tango_ros_common/tango_ros_native/src/tango_ros_node.cpp
|
||||
void applyFovModel(
|
||||
double xu, double yu, double w, double w_inverse, double two_tan_w_div_two,
|
||||
double* xd, double* yd) {
|
||||
double ru = sqrt(xu * xu + yu * yu);
|
||||
constexpr double epsilon = 1e-7;
|
||||
if (w < epsilon || ru < epsilon) {
|
||||
*xd = xu;
|
||||
*yd = yu ;
|
||||
} else {
|
||||
double rd_div_ru = std::atan(ru * two_tan_w_div_two) * w_inverse / ru;
|
||||
*xd = xu * rd_div_ru;
|
||||
*yd = yu * rd_div_ru;
|
||||
}
|
||||
}
|
||||
// Compute the warp maps to undistort the Tango fisheye image using the FOV
|
||||
// model. See OpenCV documentation for more information on warp maps:
|
||||
// http://docs.opencv.org/2.4/modules/imgproc/doc/geometric_transformations.html
|
||||
// Tango ROS Streamer: https://github.com/Intermodalics/tango_ros/blob/master/tango_ros_common/tango_ros_native/src/tango_ros_node.cpp
|
||||
// @param fisheyeModel the fisheye camera intrinsics.
|
||||
// @param mapX the output map for the x direction.
|
||||
// @param mapY the output map for the y direction.
|
||||
void initFisheyeRectificationMap(
|
||||
const CameraModel& fisheyeModel,
|
||||
cv::Mat & mapX, cv::Mat & mapY) {
|
||||
const double & fx = fisheyeModel.K().at<double>(0,0);
|
||||
const double & fy = fisheyeModel.K().at<double>(1,1);
|
||||
const double & cx = fisheyeModel.K().at<double>(0,2);
|
||||
const double & cy = fisheyeModel.K().at<double>(1,2);
|
||||
const double & w = fisheyeModel.D().at<double>(0,0);
|
||||
mapX.create(fisheyeModel.imageSize(), CV_32FC1);
|
||||
mapY.create(fisheyeModel.imageSize(), CV_32FC1);
|
||||
LOGD("initFisheyeRectificationMap: fx=%f fy=%f, cx=%f, cy=%f, w=%f", fx, fy, cx, cy, w);
|
||||
// Pre-computed variables for more efficiency.
|
||||
const double fy_inverse = 1.0 / fy;
|
||||
const double fx_inverse = 1.0 / fx;
|
||||
const double w_inverse = 1 / w;
|
||||
const double two_tan_w_div_two = 2.0 * std::tan(w * 0.5);
|
||||
// Compute warp maps in x and y directions.
|
||||
// OpenCV expects maps from dest to src, i.e. from undistorted to distorted
|
||||
// pixel coordinates.
|
||||
for(int iu = 0; iu < fisheyeModel.imageHeight(); ++iu) {
|
||||
for (int ju = 0; ju < fisheyeModel.imageWidth(); ++ju) {
|
||||
double xu = (ju - cx) * fx_inverse;
|
||||
double yu = (iu - cy) * fy_inverse;
|
||||
double xd, yd;
|
||||
applyFovModel(xu, yu, w, w_inverse, two_tan_w_div_two, &xd, &yd);
|
||||
double jd = cx + xd * fx;
|
||||
double id = cy + yd * fy;
|
||||
mapX.at<float>(iu, ju) = jd;
|
||||
mapY.at<float>(iu, ju) = id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CameraTango::init(const std::string & calibrationFolder, const std::string & cameraName)
|
||||
{
|
||||
close();
|
||||
|
||||
TangoSupport_initialize(TangoService_getPoseAtTime, TangoService_getCameraIntrinsics);
|
||||
|
||||
// Connect to Tango
|
||||
LOGI("NativeRTABMap: Setup tango config");
|
||||
tango_config_ = TangoService_getConfig(TANGO_CONFIG_DEFAULT);
|
||||
if (tango_config_ == nullptr)
|
||||
{
|
||||
LOGE("NativeRTABMap: Failed to get default config form");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set auto-recovery for motion tracking as requested by the user.
|
||||
bool is_atuo_recovery = true;
|
||||
int ret = TangoConfig_setBool(tango_config_, "config_enable_auto_recovery", is_atuo_recovery);
|
||||
if (ret != TANGO_SUCCESS)
|
||||
{
|
||||
LOGE("NativeRTABMap: config_enable_auto_recovery() failed with error code: %d", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(colorCamera_)
|
||||
{
|
||||
// Enable color.
|
||||
ret = TangoConfig_setBool(tango_config_, "config_enable_color_camera", true);
|
||||
if (ret != TANGO_SUCCESS)
|
||||
{
|
||||
LOGE("NativeRTABMap: config_enable_color_camera() failed with error code: %d", ret);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Enable depth.
|
||||
ret = TangoConfig_setBool(tango_config_, "config_enable_depth", true);
|
||||
if (ret != TANGO_SUCCESS)
|
||||
{
|
||||
LOGE("NativeRTABMap: config_enable_depth() failed with error code: %d", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Need to specify the depth_mode as XYZC.
|
||||
ret = TangoConfig_setInt32(tango_config_, "config_depth_mode", TANGO_POINTCLOUD_XYZC);
|
||||
if (ret != TANGO_SUCCESS)
|
||||
{
|
||||
LOGE("Failed to set 'depth_mode' configuration flag with error code: %d", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Note that it's super important for AR applications that we enable low
|
||||
// latency imu integration so that we have pose information available as
|
||||
// quickly as possible. Without setting this flag, you'll often receive
|
||||
// invalid poses when calling GetPoseAtTime for an image.
|
||||
ret = TangoConfig_setBool(tango_config_, "config_enable_low_latency_imu_integration", true);
|
||||
if (ret != TANGO_SUCCESS)
|
||||
{
|
||||
LOGE("NativeRTABMap: Failed to enable low latency imu integration.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Drift correction allows motion tracking to recover after it loses tracking.
|
||||
//
|
||||
// The drift corrected pose is is available through the frame pair with
|
||||
// base frame AREA_DESCRIPTION and target frame DEVICE.
|
||||
/*ret = TangoConfig_setBool(tango_config_, "config_enable_drift_correction", true);
|
||||
if (ret != TANGO_SUCCESS) {
|
||||
LOGE(
|
||||
"NativeRTABMap: enabling config_enable_drift_correction "
|
||||
"failed with error code: %d",
|
||||
ret);
|
||||
return false;
|
||||
}*/
|
||||
|
||||
// Get TangoCore version string from service.
|
||||
char tango_core_version[kVersionStringLength];
|
||||
ret = TangoConfig_getString(tango_config_, "tango_service_library_version", tango_core_version, kVersionStringLength);
|
||||
if (ret != TANGO_SUCCESS)
|
||||
{
|
||||
LOGE("NativeRTABMap: get tango core version failed with error code: %d", ret);
|
||||
return false;
|
||||
}
|
||||
LOGI("NativeRTABMap: Tango version : %s", tango_core_version);
|
||||
|
||||
|
||||
// Callbacks
|
||||
LOGI("NativeRTABMap: Setup callbacks");
|
||||
// Attach the OnXYZijAvailable callback.
|
||||
// The callback will be called after the service is connected.
|
||||
ret = TangoService_connectOnPointCloudAvailable(onPointCloudAvailableRouter);
|
||||
if (ret != TANGO_SUCCESS)
|
||||
{
|
||||
LOGE("NativeRTABMap: Failed to connect to point cloud callback with error code: %d", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = TangoService_connectOnFrameAvailable(colorCamera_?TANGO_CAMERA_COLOR:TANGO_CAMERA_FISHEYE, this, onFrameAvailableRouter);
|
||||
if (ret != TANGO_SUCCESS)
|
||||
{
|
||||
LOGE("NativeRTABMap: Failed to connect to color callback with error code: %d", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Attach the onPoseAvailable callback.
|
||||
// The callback will be called after the service is connected.
|
||||
TangoCoordinateFramePair pair;
|
||||
//pair.base = TANGO_COORDINATE_FRAME_AREA_DESCRIPTION; // drift correction is enabled
|
||||
pair.base = TANGO_COORDINATE_FRAME_START_OF_SERVICE;
|
||||
pair.target = TANGO_COORDINATE_FRAME_DEVICE;
|
||||
ret = TangoService_connectOnPoseAvailable(1, &pair, onPoseAvailableRouter);
|
||||
if (ret != TANGO_SUCCESS)
|
||||
{
|
||||
LOGE("NativeRTABMap: Failed to connect to pose callback with error code: %d", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Attach the onEventAvailable callback.
|
||||
// The callback will be called after the service is connected.
|
||||
ret = TangoService_connectOnTangoEvent(onTangoEventAvailableRouter);
|
||||
if (ret != TANGO_SUCCESS)
|
||||
{
|
||||
LOGE("PointCloudApp: Failed to connect to event callback with error code: %d", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now connect service so the callbacks above will be called
|
||||
LOGI("NativeRTABMap: Connect to tango service");
|
||||
ret = TangoService_connect(this, tango_config_);
|
||||
if (ret != TANGO_SUCCESS)
|
||||
{
|
||||
LOGE("NativeRTABMap: Failed to connect to the Tango service with error code: %d", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
// update extrinsics
|
||||
LOGI("NativeRTABMap: Update extrinsics");
|
||||
TangoPoseData pose_data;
|
||||
TangoCoordinateFramePair frame_pair;
|
||||
|
||||
// TangoService_getPoseAtTime function is used for query device extrinsics
|
||||
// as well. We use timestamp 0.0 and the target frame pair to get the
|
||||
// extrinsics from the sensors.
|
||||
//
|
||||
// Get color camera with respect to device transformation matrix.
|
||||
frame_pair.base = TANGO_COORDINATE_FRAME_DEVICE;
|
||||
frame_pair.target = colorCamera_?TANGO_COORDINATE_FRAME_CAMERA_COLOR:TANGO_COORDINATE_FRAME_CAMERA_FISHEYE;
|
||||
ret = TangoService_getPoseAtTime(0.0, frame_pair, &pose_data);
|
||||
if (ret != TANGO_SUCCESS)
|
||||
{
|
||||
LOGE("NativeRTABMap: Failed to get transform between the color camera frame and device frames");
|
||||
return false;
|
||||
}
|
||||
deviceTColorCamera_ = rtabmap::Transform(
|
||||
pose_data.translation[0],
|
||||
pose_data.translation[1],
|
||||
pose_data.translation[2],
|
||||
pose_data.orientation[0],
|
||||
pose_data.orientation[1],
|
||||
pose_data.orientation[2],
|
||||
pose_data.orientation[3]);
|
||||
deviceTColorCamera_ = rtabmap_world_T_opengl_world * deviceTColorCamera_;
|
||||
|
||||
// camera intrinsic
|
||||
TangoCameraIntrinsics color_camera_intrinsics;
|
||||
ret = TangoService_getCameraIntrinsics(colorCamera_?TANGO_CAMERA_COLOR:TANGO_CAMERA_FISHEYE, &color_camera_intrinsics);
|
||||
if (ret != TANGO_SUCCESS)
|
||||
{
|
||||
LOGE("NativeRTABMap: Failed to get the intrinsics for the color camera with error code: %d.", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
LOGD("Calibration: fx=%f fy=%f cx=%f cy=%f width=%d height=%d",
|
||||
color_camera_intrinsics.fx,
|
||||
color_camera_intrinsics.fy,
|
||||
color_camera_intrinsics.cx,
|
||||
color_camera_intrinsics.cy,
|
||||
color_camera_intrinsics.width,
|
||||
color_camera_intrinsics.height);
|
||||
|
||||
cv::Mat K = cv::Mat::eye(3, 3, CV_64FC1);
|
||||
K.at<double>(0,0) = color_camera_intrinsics.fx;
|
||||
K.at<double>(1,1) = color_camera_intrinsics.fy;
|
||||
K.at<double>(0,2) = color_camera_intrinsics.cx;
|
||||
K.at<double>(1,2) = color_camera_intrinsics.cy;
|
||||
cv::Mat D = cv::Mat::zeros(1, 5, CV_64FC1);
|
||||
LOGD("Calibration type = %d", color_camera_intrinsics.calibration_type);
|
||||
if(color_camera_intrinsics.calibration_type == TANGO_CALIBRATION_POLYNOMIAL_5_PARAMETERS ||
|
||||
color_camera_intrinsics.calibration_type == TANGO_CALIBRATION_EQUIDISTANT)
|
||||
{
|
||||
D.at<double>(0,0) = color_camera_intrinsics.distortion[0];
|
||||
D.at<double>(0,1) = color_camera_intrinsics.distortion[1];
|
||||
D.at<double>(0,2) = color_camera_intrinsics.distortion[2];
|
||||
D.at<double>(0,3) = color_camera_intrinsics.distortion[3];
|
||||
D.at<double>(0,4) = color_camera_intrinsics.distortion[4];
|
||||
}
|
||||
else if(color_camera_intrinsics.calibration_type == TANGO_CALIBRATION_POLYNOMIAL_3_PARAMETERS)
|
||||
{
|
||||
D.at<double>(0,0) = color_camera_intrinsics.distortion[0];
|
||||
D.at<double>(0,1) = color_camera_intrinsics.distortion[1];
|
||||
D.at<double>(0,2) = 0.;
|
||||
D.at<double>(0,3) = 0.;
|
||||
D.at<double>(0,4) = color_camera_intrinsics.distortion[2];
|
||||
}
|
||||
else if(color_camera_intrinsics.calibration_type == TANGO_CALIBRATION_POLYNOMIAL_2_PARAMETERS)
|
||||
{
|
||||
D.at<double>(0,0) = color_camera_intrinsics.distortion[0];
|
||||
D.at<double>(0,1) = color_camera_intrinsics.distortion[1];
|
||||
D.at<double>(0,2) = 0.;
|
||||
D.at<double>(0,3) = 0.;
|
||||
D.at<double>(0,4) = 0.;
|
||||
}
|
||||
|
||||
cv::Mat R = cv::Mat::eye(3, 3, CV_64FC1);
|
||||
cv::Mat P;
|
||||
|
||||
LOGD("Distortion params: %f, %f, %f, %f, %f", D.at<double>(0,0), D.at<double>(0,1), D.at<double>(0,2), D.at<double>(0,3), D.at<double>(0,4));
|
||||
model_ = CameraModel(colorCamera_?"color":"fisheye",
|
||||
cv::Size(color_camera_intrinsics.width, color_camera_intrinsics.height),
|
||||
K, D, R, P,
|
||||
deviceTColorCamera_);
|
||||
|
||||
if(!colorCamera_)
|
||||
{
|
||||
initFisheyeRectificationMap(model_, fisheyeRectifyMapX_, fisheyeRectifyMapY_);
|
||||
}
|
||||
|
||||
LOGI("deviceTColorCameraRtabmap =%s", deviceTColorCamera_.prettyPrint().c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
void CameraTango::close()
|
||||
{
|
||||
if(tango_config_)
|
||||
{
|
||||
TangoConfig_free(tango_config_);
|
||||
tango_config_ = nullptr;
|
||||
LOGI("TangoService_disconnect()");
|
||||
TangoService_disconnect();
|
||||
LOGI("TangoService_disconnect() done.");
|
||||
}
|
||||
fisheyeRectifyMapX_ = cv::Mat();
|
||||
fisheyeRectifyMapY_ = cv::Mat();
|
||||
|
||||
CameraMobile::close();
|
||||
}
|
||||
|
||||
void CameraTango::cloudReceived(const cv::Mat & cloud, double timestamp)
|
||||
{
|
||||
if(!cloud.empty())
|
||||
{
|
||||
//LOGD("Depth received! %fs (%d points)", timestamp, cloud.cols);
|
||||
|
||||
UASSERT(cloud.type() == CV_32FC4);
|
||||
boost::mutex::scoped_lock lock(dataMutex_);
|
||||
|
||||
// From post: http://stackoverflow.com/questions/29236110/timing-issues-with-tango-image-frames
|
||||
// "In the current version of Project Tango Tablet RGB IR camera
|
||||
// is used for both depth and color images and it can only do one
|
||||
// or the other for each frame. So in the stream we get 4 RGB frames
|
||||
// followed by 1 Depth frame resulting in the pattern you observed. This
|
||||
// is more of a hardware limitation."
|
||||
//
|
||||
// So, synchronize with the last RGB frame before the Depth is acquired
|
||||
if(!tangoColor_.empty())
|
||||
{
|
||||
UTimer timer;
|
||||
double dt = fabs(timestamp - tangoColorStamp_);
|
||||
|
||||
//LOGD("Depth: %f vs %f = %f", tangoColorStamp_, timestamp, dt);
|
||||
|
||||
if(dt >= 0.0 && dt < 0.5)
|
||||
{
|
||||
bool notify = !data_.isValid();
|
||||
|
||||
cv::Mat tangoImage = tangoColor_;
|
||||
cv::Mat rgb;
|
||||
double cloudStamp = timestamp;
|
||||
double rgbStamp = tangoColorStamp_;
|
||||
int tangoColorType = tangoColorType_;
|
||||
|
||||
tangoColor_ = cv::Mat();
|
||||
tangoColorStamp_ = 0.0;
|
||||
tangoColorType_ = 0;
|
||||
|
||||
LOGD("tangoColorType=%d", tangoColorType);
|
||||
if(tangoColorType == TANGO_HAL_PIXEL_FORMAT_RGBA_8888)
|
||||
{
|
||||
cv::cvtColor(tangoImage, rgb, cv::COLOR_RGBA2BGR);
|
||||
}
|
||||
else if(tangoColorType == TANGO_HAL_PIXEL_FORMAT_YV12)
|
||||
{
|
||||
cv::cvtColor(tangoImage, rgb, cv::COLOR_YUV2BGR_YV12);
|
||||
}
|
||||
else if(tangoColorType == TANGO_HAL_PIXEL_FORMAT_YCrCb_420_SP)
|
||||
{
|
||||
cv::cvtColor(tangoImage, rgb, cv::COLOR_YUV2BGR_NV21);
|
||||
}
|
||||
else if(tangoColorType == 35)
|
||||
{
|
||||
cv::cvtColor(tangoImage, rgb, cv::COLOR_YUV420sp2GRAY);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGE("Not supported color format : %d.", tangoColorType);
|
||||
data_ = SensorData();
|
||||
return;
|
||||
}
|
||||
|
||||
//for(int i=0; i<rgb.cols; ++i)
|
||||
//{
|
||||
// UERROR("%d,%d,%d", (int)rgb.at<cv::Vec3b>(i)[0], (int)rgb.at<cv::Vec3b>(i)[1], (int)rgb.at<cv::Vec3b>(i)[2]);
|
||||
//}
|
||||
|
||||
CameraModel model = model_;
|
||||
|
||||
if(colorCamera_)
|
||||
{
|
||||
if(decimation_ > 1)
|
||||
{
|
||||
rgb = util2d::decimate(rgb, decimation_);
|
||||
model = model.scaled(1.0/double(decimation_));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//UTimer t;
|
||||
cv::Mat rgbRect;
|
||||
cv::remap(rgb, rgbRect, fisheyeRectifyMapX_, fisheyeRectifyMapY_, cv::INTER_LINEAR, cv::BORDER_CONSTANT, 0);
|
||||
rgb = rgbRect;
|
||||
//LOGD("Rectification time=%fs", t.ticks());
|
||||
}
|
||||
|
||||
// Querying the depth image's frame transformation based on the depth image's
|
||||
// timestamp.
|
||||
cv::Mat depth;
|
||||
|
||||
// Calculate the relative pose from color camera frame at timestamp
|
||||
// color_timestamp t1 and depth
|
||||
// camera frame at depth_timestamp t0.
|
||||
Transform colorToDepth;
|
||||
TangoPoseData pose_color_image_t1_T_depth_image_t0;
|
||||
if (TangoSupport_calculateRelativePose(
|
||||
rgbStamp, colorCamera_?TANGO_COORDINATE_FRAME_CAMERA_COLOR:TANGO_COORDINATE_FRAME_CAMERA_FISHEYE, cloudStamp,
|
||||
TANGO_COORDINATE_FRAME_CAMERA_DEPTH,
|
||||
&pose_color_image_t1_T_depth_image_t0) == TANGO_SUCCESS)
|
||||
{
|
||||
colorToDepth = tangoPoseToTransform(&pose_color_image_t1_T_depth_image_t0);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGE(
|
||||
"SynchronizationApplication: Could not find a valid relative pose at "
|
||||
"time for color and "
|
||||
" depth cameras.");
|
||||
}
|
||||
|
||||
if(colorToDepth.getNormSquared() > 100000)
|
||||
{
|
||||
LOGE("Very large color to depth error detected (%s)! Ignoring this frame!", colorToDepth.prettyPrint().c_str());
|
||||
colorToDepth.setNull();
|
||||
}
|
||||
cv::Mat scan;
|
||||
if(!colorToDepth.isNull())
|
||||
{
|
||||
// The Color Camera frame at timestamp t0 with respect to Depth
|
||||
// Camera frame at timestamp t1.
|
||||
//LOGD("colorToDepth=%s", colorToDepth.prettyPrint().c_str());
|
||||
LOGD("rgb=%dx%d cloud size=%d", rgb.cols, rgb.rows, (int)cloud.total());
|
||||
|
||||
int pixelsSet = 0;
|
||||
int depthSizeDec = colorCamera_?8:1;
|
||||
depth = cv::Mat::zeros(model_.imageHeight()/depthSizeDec, model_.imageWidth()/depthSizeDec, CV_16UC1); // mm
|
||||
CameraModel depthModel = model_.scaled(1.0f/float(depthSizeDec));
|
||||
std::vector<cv::Point3f> scanData(rawScanPublished_?cloud.total():0);
|
||||
int oi=0;
|
||||
int closePoints = 0;
|
||||
float closeROI[4];
|
||||
closeROI[0] = depth.cols/4;
|
||||
closeROI[1] = 3*(depth.cols/4);
|
||||
closeROI[2] = depth.rows/4;
|
||||
closeROI[3] = 3*(depth.rows/4);
|
||||
unsigned short minDepthValue=10000;
|
||||
for(unsigned int i=0; i<cloud.total(); ++i)
|
||||
{
|
||||
const float * p = cloud.ptr<float>(0,i);
|
||||
cv::Point3f pt = util3d::transformPoint(cv::Point3f(p[0], p[1], p[2]), colorToDepth);
|
||||
|
||||
if(pt.z > 0.0f && i%scanDownsampling == 0 && rawScanPublished_)
|
||||
{
|
||||
scanData.at(oi++) = pt;
|
||||
}
|
||||
|
||||
int pixel_x_l, pixel_y_l, pixel_x_h, pixel_y_h;
|
||||
// get the coordinate on image plane.
|
||||
pixel_x_l = static_cast<int>((depthModel.fx()) * (pt.x / pt.z) + depthModel.cx());
|
||||
pixel_y_l = static_cast<int>((depthModel.fy()) * (pt.y / pt.z) + depthModel.cy());
|
||||
pixel_x_h = static_cast<int>((depthModel.fx()) * (pt.x / pt.z) + depthModel.cx() + 0.5f);
|
||||
pixel_y_h = static_cast<int>((depthModel.fy()) * (pt.y / pt.z) + depthModel.cy() + 0.5f);
|
||||
unsigned short depth_value(pt.z * 1000.0f);
|
||||
|
||||
if(pixel_x_l>=closeROI[0] && pixel_x_l<closeROI[1] &&
|
||||
pixel_y_l>closeROI[2] && pixel_y_l<closeROI[3] &&
|
||||
depth_value < 600)
|
||||
{
|
||||
++closePoints;
|
||||
if(depth_value < minDepthValue)
|
||||
{
|
||||
minDepthValue = depth_value;
|
||||
}
|
||||
}
|
||||
|
||||
bool pixelSet = false;
|
||||
if(pixel_x_l>=0 && pixel_x_l<depth.cols &&
|
||||
pixel_y_l>0 && pixel_y_l<depth.rows && // ignore first line
|
||||
depth_value)
|
||||
{
|
||||
unsigned short & depthPixel = depth.at<unsigned short>(pixel_y_l, pixel_x_l);
|
||||
if(depthPixel == 0 || depthPixel > depth_value)
|
||||
{
|
||||
depthPixel = depth_value;
|
||||
pixelSet = true;
|
||||
}
|
||||
}
|
||||
if(pixel_x_h>=0 && pixel_x_h<depth.cols &&
|
||||
pixel_y_h>0 && pixel_y_h<depth.rows && // ignore first line
|
||||
depth_value)
|
||||
{
|
||||
unsigned short & depthPixel = depth.at<unsigned short>(pixel_y_h, pixel_x_h);
|
||||
if(depthPixel == 0 || depthPixel > depth_value)
|
||||
{
|
||||
depthPixel = depth_value;
|
||||
pixelSet = true;
|
||||
}
|
||||
}
|
||||
if(pixelSet)
|
||||
{
|
||||
pixelsSet += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(closePoints > 100)
|
||||
{
|
||||
this->post(new CameraInfoEvent(0, "TooClose", ""));
|
||||
}
|
||||
|
||||
if(oi)
|
||||
{
|
||||
scan = cv::Mat(1, oi, CV_32FC3, scanData.data()).clone();
|
||||
}
|
||||
//LOGD("pixels depth set= %d", pixelsSet);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGE("color to depth pose is null?!? (rgb stamp=%f) (depth stamp=%f)", rgbStamp, cloudStamp);
|
||||
}
|
||||
|
||||
if(!rgb.empty() && !depth.empty())
|
||||
{
|
||||
depth = rtabmap::util2d::fillDepthHoles(depth, holeSize, maxDepthError);
|
||||
|
||||
Transform odom = getPoseAtTimestamp(rgbStamp);
|
||||
|
||||
//LOGD("Local = %s", model.localTransform().prettyPrint().c_str());
|
||||
//LOGD("tango = %s", poseDevice.prettyPrint().c_str());
|
||||
//LOGD("opengl(t)= %s", (opengl_world_T_tango_world * poseDevice).prettyPrint().c_str());
|
||||
|
||||
// adjust origin
|
||||
if(!getOriginOffset().isNull())
|
||||
{
|
||||
odom = getOriginOffset() * odom;
|
||||
}
|
||||
|
||||
// occlusion depth
|
||||
if(!depth.empty())
|
||||
{
|
||||
rtabmap::CameraModel depthModel = model.scaled(float(depth.cols) / float(model.imageWidth()));
|
||||
depthModel.setLocalTransform(odom*model.localTransform());
|
||||
this->setOcclusionImage(depth, depthModel);
|
||||
}
|
||||
|
||||
//LOGD("rtabmap = %s", odom.prettyPrint().c_str());
|
||||
//LOGD("opengl(r)= %s", (opengl_world_T_rtabmap_world * odom * rtabmap_device_T_opengl_device).prettyPrint().c_str());
|
||||
|
||||
Transform scanLocalTransform = model.localTransform();
|
||||
|
||||
if(rawScanPublished_)
|
||||
{
|
||||
data_ = SensorData(LaserScan::backwardCompatibility(scan, cloud.total()/scanDownsampling, 0, scanLocalTransform), rgb, depth, model, this->getNextSeqID(), rgbStamp);
|
||||
}
|
||||
else
|
||||
{
|
||||
data_ = SensorData(rgb, depth, model, this->getNextSeqID(), rgbStamp);
|
||||
}
|
||||
data_.setGroundTruth(odom);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGE("Could not get depth and rgb images!?!");
|
||||
data_ = SensorData();
|
||||
return;
|
||||
}
|
||||
|
||||
if(notify)
|
||||
{
|
||||
dataReady_.release();
|
||||
}
|
||||
LOGD("process cloud received %fs", timer.ticks());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CameraTango::rgbReceived(const cv::Mat & tangoImage, int type, double timestamp)
|
||||
{
|
||||
if(!tangoImage.empty())
|
||||
{
|
||||
//LOGD("RGB received! %fs", timestamp);
|
||||
|
||||
boost::mutex::scoped_lock lock(dataMutex_);
|
||||
|
||||
tangoColor_ = tangoImage.clone();
|
||||
tangoColorStamp_ = timestamp;
|
||||
tangoColorType_ = type;
|
||||
}
|
||||
}
|
||||
|
||||
void CameraTango::tangoEventReceived(int type, const char * key, const char * value)
|
||||
{
|
||||
this->post(new CameraInfoEvent(type, key, value));
|
||||
}
|
||||
|
||||
std::string CameraTango::getSerial() const
|
||||
{
|
||||
return "Tango";
|
||||
}
|
||||
|
||||
rtabmap::Transform CameraTango::tangoPoseToTransform(const TangoPoseData * tangoPose) const
|
||||
{
|
||||
UASSERT(tangoPose);
|
||||
rtabmap::Transform pose;
|
||||
|
||||
pose = rtabmap::Transform(
|
||||
tangoPose->translation[0],
|
||||
tangoPose->translation[1],
|
||||
tangoPose->translation[2],
|
||||
tangoPose->orientation[0],
|
||||
tangoPose->orientation[1],
|
||||
tangoPose->orientation[2],
|
||||
tangoPose->orientation[3]);
|
||||
|
||||
return pose;
|
||||
}
|
||||
|
||||
rtabmap::Transform CameraTango::getPoseAtTimestamp(double timestamp)
|
||||
{
|
||||
rtabmap::Transform pose;
|
||||
|
||||
TangoPoseData pose_start_service_T_device;
|
||||
TangoCoordinateFramePair frame_pair;
|
||||
frame_pair.base = TANGO_COORDINATE_FRAME_START_OF_SERVICE;
|
||||
frame_pair.target = TANGO_COORDINATE_FRAME_DEVICE;
|
||||
TangoErrorType status = TangoService_getPoseAtTime(timestamp, frame_pair, &pose_start_service_T_device);
|
||||
if (status != TANGO_SUCCESS)
|
||||
{
|
||||
LOGE(
|
||||
"PoseData: Failed to get transform between the Start of service and "
|
||||
"device frames at timestamp %lf",
|
||||
timestamp);
|
||||
}
|
||||
if (pose_start_service_T_device.status_code != TANGO_POSE_VALID)
|
||||
{
|
||||
LOGW(
|
||||
"PoseData: Failed to get transform between the Start of service and "
|
||||
"device frames at timestamp %lf",
|
||||
timestamp);
|
||||
}
|
||||
else
|
||||
{
|
||||
pose = rtabmap_world_T_tango_world * tangoPoseToTransform(&pose_start_service_T_device) * tango_device_T_rtabmap_world;
|
||||
}
|
||||
|
||||
return pose;
|
||||
}
|
||||
|
||||
SensorData CameraTango::captureImage(CameraInfo * info)
|
||||
{
|
||||
//LOGI("Capturing image...");
|
||||
|
||||
if(textureId_ == 0)
|
||||
{
|
||||
glGenTextures(1, &textureId_);
|
||||
glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureId_);
|
||||
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
}
|
||||
|
||||
// Update Texture (optional, just for first-view rendering)
|
||||
if(colorCamera_ && textureId_)
|
||||
{
|
||||
double video_overlay_timestamp;
|
||||
TangoErrorType status = TangoService_updateTextureExternalOes(TANGO_CAMERA_COLOR, textureId_, &video_overlay_timestamp);
|
||||
|
||||
if (status == TANGO_SUCCESS)
|
||||
{
|
||||
if(info)
|
||||
{
|
||||
info->odomPose = getPoseAtTimestamp(video_overlay_timestamp);
|
||||
}
|
||||
|
||||
int rotation = static_cast<int>(getScreenRotation()) + 1; // remove 90deg camera rotation
|
||||
if (rotation > 3) {
|
||||
rotation -= 4;
|
||||
}
|
||||
|
||||
TangoDoubleMatrixTransformData matrix_transform;
|
||||
status = TangoSupport_getDoubleMatrixTransformAtTime(
|
||||
video_overlay_timestamp,
|
||||
TANGO_COORDINATE_FRAME_CAMERA_COLOR,
|
||||
TANGO_COORDINATE_FRAME_START_OF_SERVICE,
|
||||
TANGO_SUPPORT_ENGINE_OPENGL,
|
||||
TANGO_SUPPORT_ENGINE_OPENGL,
|
||||
static_cast<TangoSupportRotation>(rotation),
|
||||
&matrix_transform);
|
||||
if (matrix_transform.status_code == TANGO_POSE_VALID)
|
||||
{
|
||||
// Get projection matrix
|
||||
TangoCameraIntrinsics color_camera_intrinsics;
|
||||
int ret = TangoSupport_getCameraIntrinsicsBasedOnDisplayRotation(
|
||||
TANGO_CAMERA_COLOR,
|
||||
static_cast<TangoSupportRotation>(rotation),
|
||||
&color_camera_intrinsics);
|
||||
|
||||
if (ret == TANGO_SUCCESS) {
|
||||
float image_width = static_cast<float>(color_camera_intrinsics.width);
|
||||
float image_height = static_cast<float>(color_camera_intrinsics.height);
|
||||
float fx = static_cast<float>(color_camera_intrinsics.fx);
|
||||
float fy = static_cast<float>(color_camera_intrinsics.fy);
|
||||
float cx = static_cast<float>(color_camera_intrinsics.cx);
|
||||
float cy = static_cast<float>(color_camera_intrinsics.cy);
|
||||
|
||||
viewMatrix_ = glm::make_mat4(matrix_transform.matrix);
|
||||
if(!getOriginOffset().isNull())
|
||||
{
|
||||
viewMatrix_ = glm::inverse(rtabmap::glmFromTransform(rtabmap::opengl_world_T_rtabmap_world * getOriginOffset() *rtabmap::rtabmap_world_T_opengl_world)*glm::inverse(viewMatrix_));
|
||||
}
|
||||
|
||||
projectionMatrix_ = tango_gl::Camera::ProjectionMatrixForCameraIntrinsics(
|
||||
image_width, image_height, fx, fy, cx, cy, 0.3, 50);
|
||||
|
||||
switch(rotation)
|
||||
{
|
||||
case ROTATION_90:
|
||||
memcpy(transformed_uvs_, kTextureCoords90, 8*sizeof(float));
|
||||
break;
|
||||
case ROTATION_180:
|
||||
memcpy(transformed_uvs_, kTextureCoords180, 8*sizeof(float));
|
||||
break;
|
||||
case ROTATION_270:
|
||||
memcpy(transformed_uvs_, kTextureCoords270, 8*sizeof(float));
|
||||
break;
|
||||
case ROTATION_0:
|
||||
default:
|
||||
memcpy(transformed_uvs_, kTextureCoords0, 8*sizeof(float));
|
||||
}
|
||||
uvs_initialized_ = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("TangoSupport_getCameraIntrinsicsBasedOnDisplayRotation failed!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("TangoSupport_getDoubleMatrixTransformAtTime failed!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("TangoService_updateTextureExternalOes failed!");
|
||||
}
|
||||
}
|
||||
|
||||
SensorData data;
|
||||
if(dataReady_.acquireTry(1))
|
||||
{
|
||||
boost::mutex::scoped_lock lock(dataMutex_);
|
||||
data = data_;
|
||||
data_ = SensorData();
|
||||
if(info)
|
||||
{
|
||||
info->odomPose = data.groundTruth();
|
||||
data.setGroundTruth(Transform());
|
||||
}
|
||||
}
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
} /* namespace rtabmap */
|
||||
85
app/android/jni/CameraTango.h
Normal file
85
app/android/jni/CameraTango.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the Universite de Sherbrooke nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CAMERATANGO_H_
|
||||
#define CAMERATANGO_H_
|
||||
|
||||
#include "CameraMobile.h"
|
||||
#include <rtabmap/core/Camera.h>
|
||||
#include <rtabmap/core/GeodeticCoords.h>
|
||||
#include <rtabmap/utilite/UMutex.h>
|
||||
#include <rtabmap/utilite/USemaphore.h>
|
||||
#include <rtabmap/utilite/UEventsSender.h>
|
||||
#include <rtabmap/utilite/UThread.h>
|
||||
#include <rtabmap/utilite/UEvent.h>
|
||||
#include <rtabmap/utilite/UTimer.h>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <tango_client_api.h>
|
||||
#include <tango_support_api.h>
|
||||
|
||||
namespace rtabmap {
|
||||
|
||||
class CameraTango : public CameraMobile {
|
||||
public:
|
||||
CameraTango(bool colorCamera, int decimation, bool publishRawScan, bool smoothing);
|
||||
virtual ~CameraTango();
|
||||
|
||||
virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = "");
|
||||
virtual void close(); // close Tango connection
|
||||
virtual std::string getSerial() const;
|
||||
rtabmap::Transform tangoPoseToTransform(const TangoPoseData * tangoPose) const;
|
||||
void setColorCamera(bool enabled) {if(!this->isRunning()) colorCamera_ = enabled;}
|
||||
void setDecimation(int value) {decimation_ = value;}
|
||||
void setRawScanPublished(bool enabled) {rawScanPublished_ = enabled;}
|
||||
|
||||
void cloudReceived(const cv::Mat & cloud, double timestamp);
|
||||
void rgbReceived(const cv::Mat & tangoImage, int type, double timestamp);
|
||||
void tangoEventReceived(int type, const char * key, const char * value);
|
||||
|
||||
protected:
|
||||
virtual SensorData captureImage(CameraInfo * info = 0);
|
||||
|
||||
private:
|
||||
rtabmap::Transform getPoseAtTimestamp(double timestamp);
|
||||
|
||||
private:
|
||||
void * tango_config_;
|
||||
bool colorCamera_;
|
||||
int decimation_;
|
||||
bool rawScanPublished_;
|
||||
SensorData data_;
|
||||
cv::Mat tangoColor_;
|
||||
int tangoColorType_;
|
||||
double tangoColorStamp_;
|
||||
boost::mutex dataMutex_;
|
||||
USemaphore dataReady_;
|
||||
cv::Mat fisheyeRectifyMapX_;
|
||||
cv::Mat fisheyeRectifyMapY_;
|
||||
};
|
||||
|
||||
} /* namespace rtabmap */
|
||||
#endif /* CAMERATANGO_H_ */
|
||||
155
app/android/jni/ProgressionStatus.h
Normal file
155
app/android/jni/ProgressionStatus.h
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* ProgressionStatus.h
|
||||
*
|
||||
* Created on: Feb 28, 2017
|
||||
* Author: mathieu
|
||||
*/
|
||||
|
||||
#ifndef APP_ANDROID_JNI_PROGRESSIONSTATUS_H_
|
||||
#define APP_ANDROID_JNI_PROGRESSIONSTATUS_H_
|
||||
|
||||
#include <rtabmap/core/ProgressState.h>
|
||||
#include <rtabmap/utilite/ULogger.h>
|
||||
#include <rtabmap/utilite/UEventsManager.h>
|
||||
#ifdef __ANDROID__
|
||||
#include <jni.h>
|
||||
#endif
|
||||
|
||||
namespace rtabmap {
|
||||
|
||||
class ProgressEvent : public UEvent
|
||||
{
|
||||
public:
|
||||
ProgressEvent(int count = 1) : count_(count){}
|
||||
virtual std::string getClassName() const {return "ProgressEvent";}
|
||||
|
||||
int count_;
|
||||
};
|
||||
|
||||
class ProgressionStatus: public ProgressState, public UEventsHandler
|
||||
{
|
||||
public:
|
||||
ProgressionStatus() : count_(0), max_(100)
|
||||
#ifdef __ANDROID__
|
||||
, jvm_(0), rtabmap_(0)
|
||||
#else
|
||||
, swiftClassPtr_(0)
|
||||
#endif
|
||||
{
|
||||
registerToEventsManager();
|
||||
}
|
||||
|
||||
#ifdef __ANDROID__
|
||||
void setJavaObjects(JavaVM * jvm, jobject rtabmap)
|
||||
{
|
||||
jvm_ = jvm;
|
||||
rtabmap_ = rtabmap;
|
||||
}
|
||||
#else
|
||||
void setSwiftCallback(void * classPtr, void(*callback)(void *, int, int))
|
||||
{
|
||||
swiftClassPtr_ = classPtr;
|
||||
swiftCallback = callback;
|
||||
}
|
||||
#endif
|
||||
|
||||
void reset(int max)
|
||||
{
|
||||
count_=-1;
|
||||
max_ = max;
|
||||
setCanceled(false);
|
||||
|
||||
increment();
|
||||
}
|
||||
|
||||
void setMax(int max)
|
||||
{
|
||||
max_ = max;
|
||||
}
|
||||
int getMax() const {return max_;}
|
||||
|
||||
void increment(int count = 1) const
|
||||
{
|
||||
UEventsManager::post(new ProgressEvent(count));
|
||||
}
|
||||
|
||||
void finish()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
virtual bool callback(const std::string & msg) const
|
||||
{
|
||||
if(!isCanceled())
|
||||
{
|
||||
increment();
|
||||
}
|
||||
|
||||
return ProgressState::callback(msg);
|
||||
}
|
||||
virtual ~ProgressionStatus(){}
|
||||
|
||||
protected:
|
||||
virtual bool handleEvent(UEvent * event)
|
||||
{
|
||||
if(event->getClassName().compare("ProgressEvent") == 0)
|
||||
{
|
||||
count_ += ((ProgressEvent*)event)->count_;
|
||||
// Call JAVA callback
|
||||
bool success = false;
|
||||
#ifdef __ANDROID__
|
||||
if(jvm_ && rtabmap_)
|
||||
{
|
||||
JNIEnv *env = 0;
|
||||
jint rs = jvm_->AttachCurrentThread(&env, NULL);
|
||||
if(rs == JNI_OK && env)
|
||||
{
|
||||
jclass clazz = env->GetObjectClass(rtabmap_);
|
||||
if(clazz)
|
||||
{
|
||||
jmethodID methodID = env->GetMethodID(clazz, "updateProgressionCallback", "(II)V" );
|
||||
if(methodID)
|
||||
{
|
||||
env->CallVoidMethod(rtabmap_, methodID,
|
||||
count_,
|
||||
max_);
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
jvm_->DetachCurrentThread();
|
||||
}
|
||||
#else // APPLE
|
||||
if(swiftClassPtr_)
|
||||
{
|
||||
std::function<void()> actualCallback = [&](){
|
||||
swiftCallback(swiftClassPtr_, count_, max_);
|
||||
};
|
||||
actualCallback();
|
||||
success = true;
|
||||
}
|
||||
#endif
|
||||
if(!success)
|
||||
{
|
||||
UERROR("Failed to call rtabmap::updateProgressionCallback");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
int count_;
|
||||
int max_;
|
||||
#ifdef __ANDROID__
|
||||
JavaVM *jvm_;
|
||||
jobject rtabmap_;
|
||||
#else
|
||||
void * swiftClassPtr_;
|
||||
void(*swiftCallback)(void *, int, int);
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif /* APP_ANDROID_JNI_PROGRESSIONSTATUS_H_ */
|
||||
4264
app/android/jni/RTABMapApp.cpp
Normal file
4264
app/android/jni/RTABMapApp.cpp
Normal file
File diff suppressed because it is too large
Load Diff
313
app/android/jni/RTABMapApp.h
Normal file
313
app/android/jni/RTABMapApp.h
Normal file
@@ -0,0 +1,313 @@
|
||||
/*
|
||||
Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the Universite de Sherbrooke nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef RTABMAP_APP_H_
|
||||
#define RTABMAP_APP_H_
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <jni.h>
|
||||
#endif
|
||||
#include <memory>
|
||||
|
||||
#include <tango-gl/util.h>
|
||||
|
||||
#include "scene.h"
|
||||
#include "CameraMobile.h"
|
||||
#include "util.h"
|
||||
#include "ProgressionStatus.h"
|
||||
|
||||
#include <rtabmap/core/RtabmapThread.h>
|
||||
#include <rtabmap/utilite/UEventsHandler.h>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <pcl/pcl_base.h>
|
||||
#include <pcl/TextureMesh.h>
|
||||
|
||||
|
||||
// RTABMapApp handles the application lifecycle and resources.
|
||||
class RTABMapApp : public UEventsHandler {
|
||||
public:
|
||||
// Constructor and deconstructor.
|
||||
#ifdef __ANDROID__
|
||||
RTABMapApp(JNIEnv* env, jobject caller_activity);
|
||||
#else // __APPLE__
|
||||
RTABMapApp();
|
||||
void setupSwiftCallbacks(void * classPtr,
|
||||
void(*progressCallback)(void *, int, int),
|
||||
void(*initCallback)(void *, int, const char*),
|
||||
void(*statsUpdatedCallback)(void *,
|
||||
int, int, int, int,
|
||||
float,
|
||||
int, int, int, int, int ,int,
|
||||
float,
|
||||
int,
|
||||
float,
|
||||
int,
|
||||
float, float, float, float,
|
||||
int, int,
|
||||
float, float, float, float, float, float));
|
||||
|
||||
#endif
|
||||
~RTABMapApp();
|
||||
|
||||
void setScreenRotation(int displayRotation, int cameraRotation);
|
||||
|
||||
int openDatabase(const std::string & databasePath, bool databaseInMemory, bool optimize, bool clearDatabase);
|
||||
|
||||
bool isBuiltWith(int cameraDriver) const;
|
||||
#ifdef __ANDROID__
|
||||
bool startCamera(JNIEnv* env, jobject iBinder, jobject context, jobject activity, int driver);
|
||||
#else // __APPLE__
|
||||
bool startCamera();
|
||||
#endif
|
||||
// Allocate OpenGL resources for rendering, mainly for initializing the Scene.
|
||||
void InitializeGLContent();
|
||||
|
||||
// Setup the view port width and height.
|
||||
void SetViewPort(int width, int height);
|
||||
|
||||
// Main render loop.
|
||||
int Render();
|
||||
|
||||
void stopCamera();
|
||||
|
||||
// Set render camera's viewing angle, first person, third person or top down.
|
||||
//
|
||||
// @param: camera_type, camera type includes first person, third person and
|
||||
// top down
|
||||
void SetCameraType(tango_gl::GestureCamera::CameraType camera_type);
|
||||
|
||||
// Touch event passed from android activity. This function only supports two
|
||||
// touches.
|
||||
//
|
||||
// @param: touch_count, total count for touches.
|
||||
// @param: event, touch event of current touch.
|
||||
// @param: x0, normalized touch location for touch 0 on x axis.
|
||||
// @param: y0, normalized touch location for touch 0 on y axis.
|
||||
// @param: x1, normalized touch location for touch 1 on x axis.
|
||||
// @param: y1, normalized touch location for touch 1 on y axis.
|
||||
void OnTouchEvent(int touch_count, tango_gl::GestureCamera::TouchEvent event,
|
||||
float x0, float y0, float x1, float y1);
|
||||
|
||||
void setPausedMapping(bool paused);
|
||||
void setOnlineBlending(bool enabled);
|
||||
void setMapCloudShown(bool shown);
|
||||
void setOdomCloudShown(bool shown);
|
||||
void setMeshRendering(bool enabled, bool withTexture);
|
||||
void setPointSize(float value);
|
||||
void setFOV(float angle);
|
||||
void setOrthoCropFactor(float value);
|
||||
void setGridRotation(float value);
|
||||
void setLighting(bool enabled);
|
||||
void setBackfaceCulling(bool enabled);
|
||||
void setWireframe(bool enabled);
|
||||
void setLocalizationMode(bool enabled);
|
||||
void setTrajectoryMode(bool enabled);
|
||||
void setGraphOptimization(bool enabled);
|
||||
void setNodesFiltering(bool enabled);
|
||||
void setGraphVisible(bool visible);
|
||||
void setGridVisible(bool visible);
|
||||
void setRawScanSaved(bool enabled);
|
||||
void setCameraColor(bool enabled);
|
||||
void setFullResolution(bool enabled);
|
||||
void setSmoothing(bool enabled);
|
||||
void setDepthFromMotion(bool enabled);
|
||||
void setAppendMode(bool enabled);
|
||||
void setDataRecorderMode(bool enabled);
|
||||
void setMaxCloudDepth(float value);
|
||||
void setMinCloudDepth(float value);
|
||||
void setCloudDensityLevel(int value);
|
||||
void setMeshAngleTolerance(float value);
|
||||
void setMeshDecimationFactor(float value);
|
||||
void setMeshTriangleSize(int value);
|
||||
void setClusterRatio(float value);
|
||||
void setMaxGainRadius(float value);
|
||||
void setRenderingTextureDecimation(int value);
|
||||
void setBackgroundColor(float gray);
|
||||
void setDepthConfidence(int value);
|
||||
int setMappingParameter(const std::string & key, const std::string & value);
|
||||
void setGPS(const rtabmap::GPS & gps);
|
||||
void addEnvSensor(int type, float value);
|
||||
|
||||
void save(const std::string & databasePath);
|
||||
bool recover(const std::string & from, const std::string & to);
|
||||
void cancelProcessing();
|
||||
bool exportMesh(
|
||||
float cloudVoxelSize,
|
||||
bool regenerateCloud,
|
||||
bool meshing,
|
||||
int textureSize,
|
||||
int textureCount,
|
||||
int normalK,
|
||||
bool optimized,
|
||||
float optimizedVoxelSize,
|
||||
int optimizedDepth,
|
||||
int optimizedMaxPolygons,
|
||||
float optimizedColorRadius,
|
||||
bool optimizedCleanWhitePolygons,
|
||||
int optimizedMinClusterSize,
|
||||
float optimizedMaxTextureDistance,
|
||||
int optimizedMinTextureClusterSize,
|
||||
bool blockRendering);
|
||||
bool postExportation(bool visualize);
|
||||
bool writeExportedMesh(const std::string & directory, const std::string & name);
|
||||
int postProcessing(int approach);
|
||||
|
||||
void postCameraPoseEvent(
|
||||
float x, float y, float z, float qx, float qy, float qz, float qw, double stamp);
|
||||
|
||||
void postOdometryEvent(
|
||||
rtabmap::Transform pose,
|
||||
float rgb_fx, float rgb_fy, float rgb_cx, float rgb_cy,
|
||||
float depth_fx, float depth_fy, float depth_cx, float depth_cy,
|
||||
const rtabmap::Transform & rgbFrame,
|
||||
const rtabmap::Transform & depthFrame,
|
||||
double stamp,
|
||||
double depthStamp,
|
||||
const void * yPlane, const void * uPlane, const void * vPlane, int yPlaneLen, int rgbWidth, int rgbHeight, int rgbFormat,
|
||||
const void * depth, int depthLen, int depthWidth, int depthHeight, int depthFormat,
|
||||
const void * conf, int confLen, int confWidth, int confHeight, int confFormat,
|
||||
const float * points, int pointsLen, int pointsChannels,
|
||||
const rtabmap::Transform & viewMatrix, //view matrix
|
||||
float p00, float p11, float p02, float p12, float p22, float p32, float p23, // projection matrix
|
||||
float t0, float t1, float t2, float t3, float t4, float t5, float t6, float t7); // tex coord
|
||||
|
||||
protected:
|
||||
virtual bool handleEvent(UEvent * event);
|
||||
|
||||
private:
|
||||
int updateMeshDecimation(int width, int height);
|
||||
rtabmap::ParametersMap getRtabmapParameters();
|
||||
bool smoothMesh(int id, rtabmap::Mesh & mesh);
|
||||
void gainCompensation(bool full = false);
|
||||
std::vector<pcl::Vertices> filterOrganizedPolygons(const std::vector<pcl::Vertices> & polygons, int cloudSize) const;
|
||||
std::vector<pcl::Vertices> filterPolygons(const std::vector<pcl::Vertices> & polygons, int cloudSize) const;
|
||||
|
||||
private:
|
||||
int cameraDriver_;
|
||||
rtabmap::CameraMobile * camera_;
|
||||
rtabmap::RtabmapThread * rtabmapThread_;
|
||||
rtabmap::Rtabmap * rtabmap_;
|
||||
rtabmap::LogHandler * logHandler_;
|
||||
|
||||
bool odomCloudShown_;
|
||||
bool graphOptimization_;
|
||||
bool nodesFiltering_;
|
||||
bool localizationMode_;
|
||||
bool trajectoryMode_;
|
||||
bool rawScanSaved_;
|
||||
bool smoothing_;
|
||||
bool depthFromMotion_;
|
||||
bool cameraColor_;
|
||||
bool fullResolution_;
|
||||
bool appendMode_;
|
||||
float maxCloudDepth_;
|
||||
float minCloudDepth_;
|
||||
int cloudDensityLevel_;
|
||||
int meshTrianglePix_;
|
||||
float meshAngleToleranceDeg_;
|
||||
float meshDecimationFactor_;
|
||||
float clusterRatio_;
|
||||
float maxGainRadius_;
|
||||
int renderingTextureDecimation_;
|
||||
float backgroundColor_;
|
||||
int depthConfidence_;
|
||||
|
||||
rtabmap::ParametersMap mappingParameters_;
|
||||
|
||||
bool dataRecorderMode_;
|
||||
bool clearSceneOnNextRender_;
|
||||
bool openingDatabase_;
|
||||
bool exporting_;
|
||||
bool postProcessing_;
|
||||
bool filterPolygonsOnNextRender_;
|
||||
int gainCompensationOnNextRender_;
|
||||
bool bilateralFilteringOnNextRender_;
|
||||
bool takeScreenshotOnNextRender_;
|
||||
bool cameraJustInitialized_;
|
||||
int totalPoints_;
|
||||
int totalPolygons_;
|
||||
int lastDrawnCloudsCount_;
|
||||
float renderingTime_;
|
||||
double lastPostRenderEventTime_;
|
||||
double lastPoseEventTime_;
|
||||
std::map<std::string, float> bufferedStatsData_;
|
||||
|
||||
bool visualizingMesh_;
|
||||
bool exportedMeshUpdated_;
|
||||
pcl::TextureMesh::Ptr optMesh_;
|
||||
cv::Mat optTexture_;
|
||||
int optRefId_;
|
||||
rtabmap::Transform * optRefPose_; // App crashes when loading native library if not dynamic
|
||||
|
||||
// main_scene_ includes all drawable object for visualizing Tango device's
|
||||
// movement and point cloud.
|
||||
Scene main_scene_;
|
||||
|
||||
UTimer fpsTime_;
|
||||
|
||||
std::list<rtabmap::RtabmapEvent*> rtabmapEvents_;
|
||||
std::list<rtabmap::OdometryEvent> odomEvents_;
|
||||
std::list<rtabmap::Transform> poseEvents_;
|
||||
std::map<double, rtabmap::Transform> poseBuffer_;
|
||||
|
||||
rtabmap::Transform mapToOdom_;
|
||||
|
||||
boost::mutex cameraMutex_;
|
||||
boost::mutex rtabmapMutex_;
|
||||
boost::mutex meshesMutex_;
|
||||
boost::mutex odomMutex_;
|
||||
boost::mutex poseMutex_;
|
||||
boost::mutex renderingMutex_;
|
||||
|
||||
USemaphore screenshotReady_;
|
||||
|
||||
std::map<int, rtabmap::Mesh> createdMeshes_;
|
||||
std::map<int, rtabmap::Transform> rawPoses_;
|
||||
|
||||
std::pair<rtabmap::RtabmapEventInit::Status, std::string> status_;
|
||||
|
||||
rtabmap::ProgressionStatus progressionStatus_;
|
||||
|
||||
#ifndef __ANDROID__
|
||||
void * swiftClassPtr_;
|
||||
void(*swiftInitCallback)(void *, int, const char *);
|
||||
void(*swiftStatsUpdatedCallback)(void *,
|
||||
int, int, int, int,
|
||||
float,
|
||||
int, int, int, int, int ,int,
|
||||
float,
|
||||
int,
|
||||
float,
|
||||
int,
|
||||
float, float, float, float,
|
||||
int, int,
|
||||
float, float, float, float, float, float);
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // TANGO_POINT_CLOUD_POINT_CLOUD_APP_H_
|
||||
210
app/android/jni/background_renderer.cc
Normal file
210
app/android/jni/background_renderer.cc
Normal file
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright 2018 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// This modules handles drawing the passthrough camera image into the OpenGL
|
||||
// scene.
|
||||
|
||||
#include "background_renderer.h"
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace {
|
||||
|
||||
const std::string kVertexShader =
|
||||
"attribute vec4 a_Position;\n"
|
||||
"attribute vec2 a_TexCoord;\n"
|
||||
|
||||
"varying vec2 v_TexCoord;\n"
|
||||
|
||||
"void main() {\n"
|
||||
" gl_Position = a_Position;\n"
|
||||
" v_TexCoord = a_TexCoord;\n"
|
||||
"}\n";
|
||||
|
||||
const std::string kFragmentShaderOES =
|
||||
"#extension GL_OES_EGL_image_external : require\n"
|
||||
"precision mediump float;\n"
|
||||
"varying vec2 v_TexCoord;\n"
|
||||
"uniform samplerExternalOES sTexture;\n"
|
||||
"uniform bool uRedUnknown;\n"
|
||||
"void main() {\n"
|
||||
" vec4 sample = texture2D(sTexture, v_TexCoord);\n"
|
||||
" float grey = 0.21 * sample.r + 0.71 * sample.g + 0.07 * sample.b;\n"
|
||||
" gl_FragColor = vec4(grey, uRedUnknown?0.0:grey, uRedUnknown?0.0:grey, 0.5);\n"
|
||||
"}\n";
|
||||
|
||||
const std::string kFragmentShaderBlendingOES =
|
||||
"#extension GL_OES_EGL_image_external : require\n"
|
||||
"precision mediump float;\n"
|
||||
"varying vec2 v_TexCoord;\n"
|
||||
"uniform samplerExternalOES sTexture;\n"
|
||||
"uniform sampler2D uDepthTexture;\n"
|
||||
"uniform vec2 uScreenScale;\n"
|
||||
"uniform bool uRedUnknown;\n"
|
||||
"void main() {\n"
|
||||
" vec4 sample = texture2D(sTexture, v_TexCoord);\n"
|
||||
" vec2 coord = uScreenScale * gl_FragCoord.xy;\n;"
|
||||
" vec4 depthPacked = texture2D(uDepthTexture, coord);\n"
|
||||
" float depth = dot(depthPacked, 1./vec4(1.,255.,65025.,16581375.));\n"
|
||||
" if(depth > 0.0)\n"
|
||||
" gl_FragColor = vec4(sample.r, sample.g, sample.b, 0.5);\n"
|
||||
" else {\n"
|
||||
" float grey = 0.21 * sample.r + 0.71 * sample.g + 0.07 * sample.b;\n"
|
||||
" gl_FragColor = vec4(grey, uRedUnknown?0.0:grey, uRedUnknown?0.0:grey, 0.5);\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
|
||||
const std::string kFragmentShader =
|
||||
"precision mediump float;\n"
|
||||
"varying vec2 v_TexCoord;\n"
|
||||
"uniform sampler2D sTexture;\n"
|
||||
"uniform bool uRedUnknown;\n"
|
||||
"void main() {\n"
|
||||
" vec4 sample = texture2D(sTexture, v_TexCoord);\n"
|
||||
" float grey = 0.21 * sample.r + 0.71 * sample.g + 0.07 * sample.b;\n"
|
||||
" gl_FragColor = vec4(grey, uRedUnknown?0.0:grey, uRedUnknown?0.0:grey, 0.5);\n"
|
||||
"}\n";
|
||||
|
||||
const std::string kFragmentShaderBlending =
|
||||
"precision mediump float;\n"
|
||||
"varying vec2 v_TexCoord;\n"
|
||||
"uniform sampler2D sTexture;\n"
|
||||
"uniform sampler2D uDepthTexture;\n"
|
||||
"uniform vec2 uScreenScale;\n"
|
||||
"uniform bool uRedUnknown;\n"
|
||||
"void main() {\n"
|
||||
" vec4 sample = texture2D(sTexture, v_TexCoord);\n"
|
||||
" vec2 coord = uScreenScale * gl_FragCoord.xy;\n;"
|
||||
" vec4 depthPacked = texture2D(uDepthTexture, coord);\n"
|
||||
" float depth = dot(depthPacked, 1./vec4(1.,255.,65025.,16581375.));\n"
|
||||
" if(depth > 0.0)\n"
|
||||
" gl_FragColor = vec4(sample.r, sample.g, sample.b, 0.5);\n"
|
||||
" else {\n"
|
||||
" float grey = 0.21 * sample.r + 0.71 * sample.g + 0.07 * sample.b;\n"
|
||||
" gl_FragColor = vec4(grey, uRedUnknown?0.0:grey, uRedUnknown?0.0:grey, 0.5);\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
|
||||
/* To debug depth texture
|
||||
const std::string kFragmentShader =
|
||||
"precision mediump float;\n"
|
||||
"varying vec2 v_TexCoord;\n"
|
||||
"uniform sampler2D sTexture;\n"
|
||||
|
||||
"void main() {\n"
|
||||
" float uNearZ = 0.2;\n"
|
||||
" float uFarZ = 1000.0;\n"
|
||||
" float depth = texture2D(sTexture, v_TexCoord).r;\n"
|
||||
" float num = (2.0 * uNearZ * uFarZ);\n"
|
||||
" float diff = (uFarZ - uNearZ);\n"
|
||||
" float add = (uFarZ + uNearZ);\n"
|
||||
" float ndcDepth = depth * 2.0 - 1.0;\n" // Back to NDC
|
||||
" float linearDepth = num / (add - ndcDepth * diff);\n" // inverse projection matrix
|
||||
" float grey = linearDepth/3.0;\n"
|
||||
" gl_FragColor = vec4(grey, grey, grey, 0.5);\n"
|
||||
"}\n";
|
||||
*/
|
||||
|
||||
} // namespace
|
||||
|
||||
std::vector<GLuint> BackgroundRenderer::shaderPrograms_;
|
||||
|
||||
BackgroundRenderer::~BackgroundRenderer()
|
||||
{
|
||||
for(unsigned int i=0; i<shaderPrograms_.size(); ++i)
|
||||
{
|
||||
glDeleteShader(shaderPrograms_[i]);
|
||||
}
|
||||
shaderPrograms_.clear();
|
||||
}
|
||||
|
||||
void BackgroundRenderer::InitializeGlContent(GLuint textureId, bool oes)
|
||||
{
|
||||
LOGI("textureId=%d", textureId);
|
||||
|
||||
texture_id_ = textureId;
|
||||
#ifdef __ANDROID__
|
||||
oes_ = oes;
|
||||
#endif
|
||||
|
||||
if(shaderPrograms_.empty())
|
||||
{
|
||||
shaderPrograms_.resize(2,0);
|
||||
shaderPrograms_[0] = tango_gl::util::CreateProgram(
|
||||
kVertexShader.c_str(),
|
||||
oes_?kFragmentShaderOES.c_str():kFragmentShader.c_str());
|
||||
UASSERT(shaderPrograms_[0]!=0);
|
||||
shaderPrograms_[1] = tango_gl::util::CreateProgram(
|
||||
kVertexShader.c_str(),
|
||||
oes_?kFragmentShaderBlendingOES.c_str():kFragmentShaderBlending.c_str());
|
||||
UASSERT(shaderPrograms_[1]!=0);
|
||||
}
|
||||
}
|
||||
|
||||
void BackgroundRenderer::Draw(const float * transformed_uvs, const GLuint & depthTexture, int screenWidth, int screenHeight, bool redUnknown) {
|
||||
static_assert(std::extent<decltype(BackgroundRenderer_kVertices)>::value == kNumVertices * 2, "Incorrect kVertices length");
|
||||
|
||||
GLuint program = shaderPrograms_[depthTexture>0?1:0];
|
||||
|
||||
glUseProgram(program);
|
||||
glDepthMask(GL_FALSE);
|
||||
glEnable (GL_BLEND);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
#ifdef __ANDROID__
|
||||
if(oes_)
|
||||
glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_id_);
|
||||
else
|
||||
#endif
|
||||
glBindTexture(GL_TEXTURE_2D, texture_id_);
|
||||
|
||||
if(depthTexture>0)
|
||||
{
|
||||
// Texture activate unit 1
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
// Bind the texture to this unit.
|
||||
glBindTexture(GL_TEXTURE_2D, depthTexture);
|
||||
// Tell the texture uniform sampler to use this texture in the shader by binding to texture unit 1.
|
||||
GLuint depth_texture_handle = glGetUniformLocation(program, "uDepthTexture");
|
||||
glUniform1i(depth_texture_handle, 1);
|
||||
|
||||
GLuint screenScale_handle = glGetUniformLocation(program, "uScreenScale");
|
||||
glUniform2f(screenScale_handle, 1.0f/(float)screenWidth, 1.0f/(float)screenHeight);
|
||||
}
|
||||
|
||||
GLuint screenScale_handle = glGetUniformLocation(program, "uRedUnknown");
|
||||
glUniform1i(screenScale_handle, redUnknown);
|
||||
|
||||
GLuint attributeVertices = glGetAttribLocation(program, "a_Position");
|
||||
GLuint attributeUvs = glGetAttribLocation(program, "a_TexCoord");
|
||||
|
||||
glVertexAttribPointer(attributeVertices, 2, GL_FLOAT, GL_FALSE, 0, BackgroundRenderer_kVertices);
|
||||
glVertexAttribPointer(attributeUvs, 2, GL_FLOAT, GL_FALSE, 0, transformed_uvs?transformed_uvs:BackgroundRenderer_kTexCoord);
|
||||
|
||||
glEnableVertexAttribArray(attributeVertices);
|
||||
glEnableVertexAttribArray(attributeUvs);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
glDisableVertexAttribArray(attributeVertices);
|
||||
glDisableVertexAttribArray(attributeUvs);
|
||||
|
||||
glUseProgram(0);
|
||||
glDepthMask(GL_TRUE);
|
||||
glDisable (GL_BLEND);
|
||||
tango_gl::util::CheckGlError("BackgroundRenderer::Draw() error");
|
||||
}
|
||||
|
||||
70
app/android/jni/background_renderer.h
Normal file
70
app/android/jni/background_renderer.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2018 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef C_ARCORE_AUGMENTED_IMAGE_BACKGROUND_RENDERER_H_
|
||||
#define C_ARCORE_AUGMENTED_IMAGE_BACKGROUND_RENDERER_H_
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
#else // __APPLE__
|
||||
#include <OpenGLES/ES2/gl.h>
|
||||
#include <OpenGLES/ES2/glext.h>
|
||||
#endif
|
||||
#include <cstdlib>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
static const GLfloat BackgroundRenderer_kVertices[] = {
|
||||
-1.0f, -1.0f, +1.0f, -1.0f, -1.0f, +1.0f, +1.0f, +1.0f,
|
||||
};
|
||||
static const GLfloat BackgroundRenderer_kTexCoord[] = {
|
||||
1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
};
|
||||
|
||||
//android phone
|
||||
//11 10 01 00 // portrait
|
||||
//01 11 00 10 // left
|
||||
//10 00 11 01 // right
|
||||
//00 01 10 11 // down
|
||||
|
||||
|
||||
// This class renders the passthrough camera image into the OpenGL frame.
|
||||
class BackgroundRenderer {
|
||||
public:
|
||||
// Positions of the quad vertices in clip space (X, Y).
|
||||
|
||||
static constexpr int kNumVertices = 4;
|
||||
|
||||
public:
|
||||
BackgroundRenderer() = default;
|
||||
~BackgroundRenderer();
|
||||
|
||||
// Sets up OpenGL state. Must be called on the OpenGL thread and before any
|
||||
// other methods below.
|
||||
void InitializeGlContent(GLuint textureId, bool oes);
|
||||
|
||||
// Draws the background image. This methods must be called for every ArFrame
|
||||
// returned by ArSession_update() to catch display geometry change events.
|
||||
void Draw(const float * transformed_uvs, const GLuint & depthTexture, int screenWidth, int screenHeight, bool redUnknown);
|
||||
|
||||
private:
|
||||
static std::vector<GLuint> shaderPrograms_;
|
||||
GLuint texture_id_;
|
||||
bool oes_ = false;
|
||||
};
|
||||
|
||||
#endif // C_ARCORE_AUGMENTED_IMAGE_BACKGROUND_RENDERER_H_
|
||||
131
app/android/jni/bounding_box_drawable.h
Normal file
131
app/android/jni/bounding_box_drawable.h
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the Universite de Sherbrooke nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef BOUNDING_BOX_DRAWABLE_H_
|
||||
#define BOUNDING_BOX_DRAWABLE_H_
|
||||
|
||||
#include "tango-gl/line.h"
|
||||
|
||||
class BoundingBoxDrawable : public tango_gl::Line
|
||||
{
|
||||
public:
|
||||
BoundingBoxDrawable() :
|
||||
Line(3.0f, GL_LINES)
|
||||
{
|
||||
vec_vertices_.resize(24);
|
||||
}
|
||||
|
||||
void updateVertices(const pcl::PointXYZ & min, const pcl::PointXYZ & max)
|
||||
{
|
||||
int index = 0;
|
||||
vec_vertices_[index].x = min.x;
|
||||
vec_vertices_[index].y = min.y;
|
||||
vec_vertices_[index++].z = min.z;
|
||||
vec_vertices_[index].x = min.x;
|
||||
vec_vertices_[index].y = max.y;
|
||||
vec_vertices_[index++].z = min.z;
|
||||
|
||||
vec_vertices_[index].x = min.x;
|
||||
vec_vertices_[index].y = min.y;
|
||||
vec_vertices_[index++].z = min.z;
|
||||
vec_vertices_[index].x = max.x;
|
||||
vec_vertices_[index].y = min.y;
|
||||
vec_vertices_[index++].z = min.z;
|
||||
|
||||
vec_vertices_[index].x = min.x;
|
||||
vec_vertices_[index].y = min.y;
|
||||
vec_vertices_[index++].z = min.z;
|
||||
vec_vertices_[index].x = min.x;
|
||||
vec_vertices_[index].y = min.y;
|
||||
vec_vertices_[index++].z = max.z;
|
||||
|
||||
vec_vertices_[index].x = max.x;
|
||||
vec_vertices_[index].y = max.y;
|
||||
vec_vertices_[index++].z = max.z;
|
||||
vec_vertices_[index].x = max.x;
|
||||
vec_vertices_[index].y = min.y;
|
||||
vec_vertices_[index++].z = max.z;
|
||||
|
||||
vec_vertices_[index].x = max.x;
|
||||
vec_vertices_[index].y = max.y;
|
||||
vec_vertices_[index++].z = max.z;
|
||||
vec_vertices_[index].x = min.x;
|
||||
vec_vertices_[index].y = max.y;
|
||||
vec_vertices_[index++].z = max.z;
|
||||
|
||||
vec_vertices_[index].x = max.x;
|
||||
vec_vertices_[index].y = max.y;
|
||||
vec_vertices_[index++].z = max.z;
|
||||
vec_vertices_[index].x = max.x;
|
||||
vec_vertices_[index].y = max.y;
|
||||
vec_vertices_[index++].z = min.z;
|
||||
|
||||
vec_vertices_[index].x = max.x;
|
||||
vec_vertices_[index].y = min.y;
|
||||
vec_vertices_[index++].z = min.z;
|
||||
vec_vertices_[index].x = max.x;
|
||||
vec_vertices_[index].y = min.y;
|
||||
vec_vertices_[index++].z = max.z;
|
||||
|
||||
vec_vertices_[index].x = max.x;
|
||||
vec_vertices_[index].y = min.y;
|
||||
vec_vertices_[index++].z = min.z;
|
||||
vec_vertices_[index].x = max.x;
|
||||
vec_vertices_[index].y = max.y;
|
||||
vec_vertices_[index++].z = min.z;
|
||||
|
||||
vec_vertices_[index].x = min.x;
|
||||
vec_vertices_[index].y = max.y;
|
||||
vec_vertices_[index++].z = min.z;
|
||||
vec_vertices_[index].x = max.x;
|
||||
vec_vertices_[index].y = max.y;
|
||||
vec_vertices_[index++].z = min.z;
|
||||
|
||||
vec_vertices_[index].x = min.x;
|
||||
vec_vertices_[index].y = max.y;
|
||||
vec_vertices_[index++].z = min.z;
|
||||
vec_vertices_[index].x = min.x;
|
||||
vec_vertices_[index].y = max.y;
|
||||
vec_vertices_[index++].z = max.z;
|
||||
|
||||
vec_vertices_[index].x = min.x;
|
||||
vec_vertices_[index].y = min.y;
|
||||
vec_vertices_[index++].z = max.z;
|
||||
vec_vertices_[index].x = max.x;
|
||||
vec_vertices_[index].y = min.y;
|
||||
vec_vertices_[index++].z = max.z;
|
||||
|
||||
vec_vertices_[index].x = min.x;
|
||||
vec_vertices_[index].y = min.y;
|
||||
vec_vertices_[index++].z = max.z;
|
||||
vec_vertices_[index].x = min.x;
|
||||
vec_vertices_[index].y = max.y;
|
||||
vec_vertices_[index++].z = max.z;
|
||||
}
|
||||
|
||||
};
|
||||
#endif // TANGO_GL_LINE_H_
|
||||
164
app/android/jni/graph_drawable.cpp
Normal file
164
app/android/jni/graph_drawable.cpp
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the Universite de Sherbrooke nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "graph_drawable.h"
|
||||
#include "rtabmap/utilite/ULogger.h"
|
||||
#include "util.h"
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <GLES2/gl2.h>
|
||||
#else //__APPLE__
|
||||
#include <OpenGLES/ES2/gl.h>
|
||||
#endif
|
||||
|
||||
GraphDrawable::GraphDrawable(
|
||||
GLuint shaderProgram,
|
||||
const std::map<int, rtabmap::Transform> & poses,
|
||||
const std::multimap<int, rtabmap::Link> & links) :
|
||||
vertex_buffers_(0),
|
||||
pose_(1.0f),
|
||||
visible_(true),
|
||||
lineWidth_(3.0f),
|
||||
shader_program_(shaderProgram)
|
||||
{
|
||||
UASSERT(!poses.empty());
|
||||
|
||||
glGenBuffers(1, &vertex_buffers_);
|
||||
|
||||
if(vertex_buffers_)
|
||||
{
|
||||
LOGI("Creating vertex buffer %d", vertex_buffers_);
|
||||
std::vector<float> vertices = std::vector<float>(poses.size()*3);
|
||||
int i=0;
|
||||
std::map<int, int> idsToIndices;
|
||||
for(std::map<int, rtabmap::Transform>::const_iterator iter=poses.begin(); iter!=poses.end(); ++iter)
|
||||
{
|
||||
vertices[i*3] = iter->second.x();
|
||||
vertices[i*3+1] = iter->second.y();
|
||||
vertices[i*3+2] = iter->second.z();
|
||||
idsToIndices.insert(std::make_pair(iter->first, i));
|
||||
++i;
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffers_);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * (int)vertices.size(), (const void *)vertices.data(), GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
GLint error = glGetError();
|
||||
if(error != GL_NO_ERROR)
|
||||
{
|
||||
LOGI("OpenGL: Could not allocate point cloud (0x%x)\n", error);
|
||||
vertex_buffers_ = 0;
|
||||
}
|
||||
else if(links.size())
|
||||
{
|
||||
neighborIndices_.resize(links.size() * 2);
|
||||
loopClosureIndices_.resize(links.size() * 2);
|
||||
int oiNeighbors = 0;
|
||||
int oiLoopClosures = 0;
|
||||
for(std::multimap<int, rtabmap::Link>::const_iterator iter=links.begin(); iter!=links.end(); ++iter)
|
||||
{
|
||||
std::map<int, int>::const_iterator jterFrom = idsToIndices.find(iter->second.from());
|
||||
std::map<int, int>::const_iterator jterTo = idsToIndices.find(iter->second.to());
|
||||
if(jterFrom != idsToIndices.end() && jterTo != idsToIndices.end())
|
||||
{
|
||||
if(iter->second.type() == rtabmap::Link::kNeighbor)
|
||||
{
|
||||
neighborIndices_[oiNeighbors++] = (unsigned short)jterFrom->second;
|
||||
neighborIndices_[oiNeighbors++] = (unsigned short)jterTo->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
loopClosureIndices_[oiLoopClosures++] = (unsigned short)jterFrom->second;
|
||||
loopClosureIndices_[oiLoopClosures++] = (unsigned short)jterTo->second;
|
||||
}
|
||||
}
|
||||
}
|
||||
neighborIndices_.resize(oiNeighbors);
|
||||
loopClosureIndices_.resize(oiLoopClosures);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GraphDrawable::~GraphDrawable()
|
||||
{
|
||||
LOGI("Freeing cloud buffer %d", vertex_buffers_);
|
||||
if (vertex_buffers_)
|
||||
{
|
||||
glDeleteBuffers(1, &vertex_buffers_);
|
||||
tango_gl::util::CheckGlError("GraphDrawable::~GraphDrawable()");
|
||||
vertex_buffers_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void GraphDrawable::setPose(const rtabmap::Transform & pose)
|
||||
{
|
||||
UASSERT(!pose.isNull());
|
||||
|
||||
pose_ = glmFromTransform(pose);
|
||||
}
|
||||
|
||||
void GraphDrawable::Render(const glm::mat4 & projectionMatrix, const glm::mat4 & viewMatrix) {
|
||||
|
||||
if(vertex_buffers_ && (neighborIndices_.size() || loopClosureIndices_.size()) && visible_)
|
||||
{
|
||||
glUseProgram(shader_program_);
|
||||
glLineWidth(lineWidth_);
|
||||
|
||||
GLuint mvp_handle_ = glGetUniformLocation(shader_program_, "mvp");
|
||||
glm::mat4 mvp_mat = projectionMatrix * viewMatrix * pose_;
|
||||
glUniformMatrix4fv(mvp_handle_, 1, GL_FALSE, glm::value_ptr(mvp_mat));
|
||||
|
||||
GLuint color_handle = glGetUniformLocation(shader_program_, "color");
|
||||
|
||||
GLint attribute_vertex = glGetAttribLocation(shader_program_, "vertex");
|
||||
|
||||
glEnableVertexAttribArray(attribute_vertex);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffers_);
|
||||
glVertexAttribPointer(attribute_vertex, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GLfloat), 0);
|
||||
|
||||
if(neighborIndices_.size())
|
||||
{
|
||||
glUniform3f(color_handle, 1.0f, 0.0f, 0.0f); // blue for neighbors
|
||||
glDrawElements(GL_LINES, neighborIndices_.size(), GL_UNSIGNED_SHORT, neighborIndices_.data());
|
||||
}
|
||||
if(loopClosureIndices_.size())
|
||||
{
|
||||
glUniform3f(color_handle, 0.0f, 0.0f, 1.0f); // red for loop closures
|
||||
glDrawElements(GL_LINES, loopClosureIndices_.size(), GL_UNSIGNED_SHORT, loopClosureIndices_.data());
|
||||
}
|
||||
|
||||
glDisableVertexAttribArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
glUseProgram(0);
|
||||
tango_gl::util::CheckGlError("GraphDrawable::Render()");
|
||||
}
|
||||
}
|
||||
|
||||
68
app/android/jni/graph_drawable.h
Normal file
68
app/android/jni/graph_drawable.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the Universite de Sherbrooke nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef GRAPH_DRAWABLE_H_
|
||||
#define GRAPH_DRAWABLE_H_
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <jni.h>
|
||||
#endif
|
||||
#include <tango-gl/util.h>
|
||||
#include <vector>
|
||||
#include <pcl/point_cloud.h>
|
||||
#include <pcl/point_types.h>
|
||||
#include <rtabmap/core/Transform.h>
|
||||
#include <rtabmap/core/Link.h>
|
||||
#include <pcl/Vertices.h>
|
||||
#include "util.h"
|
||||
|
||||
class GraphDrawable {
|
||||
public:
|
||||
GraphDrawable(
|
||||
GLuint shaderProgram,
|
||||
const std::map<int, rtabmap::Transform> & poses,
|
||||
const std::multimap<int, rtabmap::Link> & links);
|
||||
virtual ~GraphDrawable();
|
||||
|
||||
void setPose(const rtabmap::Transform & mapToOdom);
|
||||
void setVisible(bool visible) {visible_=visible;}
|
||||
|
||||
void Render(const glm::mat4 & projectionMatrix, const glm::mat4 & viewMatrix);
|
||||
|
||||
private:
|
||||
// Vertex buffer of the point cloud geometry.
|
||||
GLuint vertex_buffers_;
|
||||
std::vector<GLushort> neighborIndices_;
|
||||
std::vector<GLushort> loopClosureIndices_;
|
||||
glm::mat4 pose_;
|
||||
bool visible_;
|
||||
float lineWidth_;
|
||||
|
||||
GLuint shader_program_;
|
||||
};
|
||||
|
||||
#endif // GRAPH_DRAWABLE_H_
|
||||
969
app/android/jni/jni_interface.cpp
Normal file
969
app/android/jni/jni_interface.cpp
Normal file
@@ -0,0 +1,969 @@
|
||||
/*
|
||||
Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the Universite de Sherbrooke nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define GLM_FORCE_RADIANS
|
||||
|
||||
#include <jni.h>
|
||||
#include <RTABMapApp.h>
|
||||
#include <scene.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void GetJStringContent(JNIEnv *AEnv, jstring AStr, std::string &ARes) {
|
||||
if (!AStr) {
|
||||
ARes.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
const char *s = AEnv->GetStringUTFChars(AStr,NULL);
|
||||
ARes=s;
|
||||
AEnv->ReleaseStringUTFChars(AStr,s);
|
||||
}
|
||||
|
||||
inline jlong jptr(RTABMapApp *native_computer_vision_application) {
|
||||
return reinterpret_cast<intptr_t>(native_computer_vision_application);
|
||||
}
|
||||
|
||||
inline RTABMapApp *native(jlong ptr) {
|
||||
return reinterpret_cast<RTABMapApp *>(ptr);
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_createNativeApplication(
|
||||
JNIEnv* env, jclass, jobject activity)
|
||||
{
|
||||
return jptr(new RTABMapApp(env, activity));
|
||||
}
|
||||
|
||||
JNIEXPORT void Java_com_introlab_rtabmap_RTABMapLib_destroyNativeApplication(
|
||||
JNIEnv *, jclass, jlong native_application) {
|
||||
if(native_application)
|
||||
{
|
||||
delete native(native_application);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setScreenRotation(
|
||||
JNIEnv* env, jclass, jlong native_application, int displayRotation, int cameraRotation)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setScreenRotation(displayRotation, cameraRotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT int JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_openDatabase(
|
||||
JNIEnv* env, jclass, jlong native_application, jstring databasePath, bool databaseInMemory, bool optimize, bool clearDatabase)
|
||||
{
|
||||
std::string databasePathC;
|
||||
GetJStringContent(env,databasePath,databasePathC);
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->openDatabase(databasePathC, databaseInMemory, optimize, clearDatabase);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT bool JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_recover(
|
||||
JNIEnv* env, jclass, jlong native_application, jstring from, jstring to)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
std::string toC;
|
||||
GetJStringContent(env,to,toC);
|
||||
std::string fromC;
|
||||
GetJStringContent(env,from,fromC);
|
||||
return native(native_application)->recover(fromC, toC);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT bool JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_isBuiltWith(
|
||||
JNIEnv* env, jclass, jlong native_application, int cameraDriver) {
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->isBuiltWith(cameraDriver);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT bool JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_startCamera(
|
||||
JNIEnv* env, jclass, jlong native_application, jobject iBinder, jobject context, jobject activity, int driver) {
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->startCamera(env, iBinder, context, activity, driver);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_initGlContent(
|
||||
JNIEnv*, jclass, jlong native_application) {
|
||||
if(native_application)
|
||||
{
|
||||
native(native_application)->InitializeGLContent();
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setupGraphic(
|
||||
JNIEnv*, jclass, jlong native_application, jint width, jint height) {
|
||||
if(native_application)
|
||||
{
|
||||
native(native_application)->SetViewPort(width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT int JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_render(
|
||||
JNIEnv*, jclass, jlong native_application) {
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->Render();
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_stopCamera(
|
||||
JNIEnv*, jclass, jlong native_application) {
|
||||
if(native_application)
|
||||
{
|
||||
native(native_application)->stopCamera();
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setCamera(
|
||||
JNIEnv*, jclass, jlong native_application, int camera_index) {
|
||||
if(native_application)
|
||||
{
|
||||
using namespace tango_gl;
|
||||
GestureCamera::CameraType cam_type =
|
||||
static_cast<GestureCamera::CameraType>(camera_index);
|
||||
native(native_application)->SetCameraType(cam_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_onTouchEvent(
|
||||
JNIEnv*, jclass, jlong native_application, int touch_count, int event, float x0, float y0, float x1,
|
||||
float y1) {
|
||||
if(native_application)
|
||||
{
|
||||
using namespace tango_gl;
|
||||
GestureCamera::TouchEvent touch_event =
|
||||
static_cast<GestureCamera::TouchEvent>(event);
|
||||
native(native_application)->OnTouchEvent(touch_count, touch_event, x0, y0, x1, y1);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setPausedMapping(
|
||||
JNIEnv*, jclass, jlong native_application, bool paused)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setPausedMapping(paused);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setOnlineBlending(
|
||||
JNIEnv*, jclass, jlong native_application, bool enabled)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setOnlineBlending(enabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setMapCloudShown(
|
||||
JNIEnv*, jclass, jlong native_application, bool shown)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setMapCloudShown(shown);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setOdomCloudShown(
|
||||
JNIEnv*, jclass, jlong native_application, bool shown)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setOdomCloudShown(shown);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setMeshRendering(
|
||||
JNIEnv*, jclass, jlong native_application, bool enabled, bool withTexture)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setMeshRendering(enabled, withTexture);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setPointSize(
|
||||
JNIEnv*, jclass, jlong native_application, float value)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setPointSize(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setFOV(
|
||||
JNIEnv*, jclass, jlong native_application, float fov)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setFOV(fov);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setOrthoCropFactor(
|
||||
JNIEnv*, jclass, jlong native_application, float value)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setOrthoCropFactor(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setGridRotation(
|
||||
JNIEnv*, jclass, jlong native_application, float value)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setGridRotation(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setLighting(
|
||||
JNIEnv*, jclass, jlong native_application, bool enabled)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setLighting(enabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setBackfaceCulling(
|
||||
JNIEnv*, jclass, jlong native_application, bool enabled)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setBackfaceCulling(enabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setWireframe(
|
||||
JNIEnv*, jclass, jlong native_application, bool enabled)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setWireframe(enabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setLocalizationMode(
|
||||
JNIEnv*, jclass, jlong native_application, bool enabled)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setLocalizationMode(enabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setTrajectoryMode(
|
||||
JNIEnv*, jclass, jlong native_application, bool enabled)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setTrajectoryMode(enabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setGraphOptimization(
|
||||
JNIEnv*, jclass, jlong native_application, bool enabled)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setGraphOptimization(enabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setNodesFiltering(
|
||||
JNIEnv*, jclass, jlong native_application, bool enabled)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setNodesFiltering(enabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setGraphVisible(
|
||||
JNIEnv*, jclass, jlong native_application, bool visible)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setGraphVisible(visible);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setGridVisible(
|
||||
JNIEnv*, jclass, jlong native_application, bool visible)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setGridVisible(visible);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setRawScanSaved(
|
||||
JNIEnv*, jclass, jlong native_application, bool enabled)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setRawScanSaved(enabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setFullResolution(
|
||||
JNIEnv*, jclass, jlong native_application, bool enabled)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setFullResolution(enabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setSmoothing(
|
||||
JNIEnv*, jclass, jlong native_application, bool enabled)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setSmoothing(enabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setDepthFromMotion(
|
||||
JNIEnv*, jclass, jlong native_application, bool enabled)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setDepthFromMotion(enabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setCameraColor(
|
||||
JNIEnv*, jclass, jlong native_application, bool enabled)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setCameraColor(enabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setAppendMode(
|
||||
JNIEnv*, jclass, jlong native_application, bool enabled)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setAppendMode(enabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setDataRecorderMode(
|
||||
JNIEnv*, jclass, jlong native_application, bool enabled)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setDataRecorderMode(enabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setMaxCloudDepth(
|
||||
JNIEnv*, jclass, jlong native_application, float value)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setMaxCloudDepth(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setMinCloudDepth(
|
||||
JNIEnv*, jclass, jlong native_application, float value)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setMinCloudDepth(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setCloudDensityLevel(
|
||||
JNIEnv*, jclass, jlong native_application, int value)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setCloudDensityLevel(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setMeshAngleTolerance(
|
||||
JNIEnv*, jclass, jlong native_application, float value)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setMeshAngleTolerance(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setMeshTriangleSize(
|
||||
JNIEnv*, jclass, jlong native_application, int value)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setMeshTriangleSize(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setClusterRatio(
|
||||
JNIEnv*, jclass, jlong native_application, float value)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setClusterRatio(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setMaxGainRadius(
|
||||
JNIEnv*, jclass, jlong native_application, float value)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setMaxGainRadius(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setRenderingTextureDecimation(
|
||||
JNIEnv*, jclass, jlong native_application, int value)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setRenderingTextureDecimation(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setBackgroundColor(
|
||||
JNIEnv*, jclass, jlong native_application, float value)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setBackgroundColor(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setMappingParameter(
|
||||
JNIEnv* env, jclass, jlong native_application, jstring key, jstring value)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
std::string keyC, valueC;
|
||||
GetJStringContent(env,key,keyC);
|
||||
GetJStringContent(env,value,valueC);
|
||||
return native(native_application)->setMappingParameter(keyC, valueC);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setGPS(
|
||||
JNIEnv*, jclass, jlong native_application,
|
||||
double stamp,
|
||||
double longitude,
|
||||
double latitude,
|
||||
double altitude,
|
||||
double accuracy,
|
||||
double bearing)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->setGPS(rtabmap::GPS(stamp,
|
||||
longitude,
|
||||
latitude,
|
||||
altitude,
|
||||
accuracy,
|
||||
bearing));
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_addEnvSensor(
|
||||
JNIEnv*, jclass, jlong native_application,
|
||||
int type,
|
||||
float value)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->addEnvSensor(type, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_save(
|
||||
JNIEnv* env, jclass, jlong native_application, jstring databasePath)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
std::string databasePathC;
|
||||
GetJStringContent(env,databasePath,databasePathC);
|
||||
return native(native_application)->save(databasePathC);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_cancelProcessing(
|
||||
JNIEnv* env, jclass, jlong native_application)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->cancelProcessing();
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT bool JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_exportMesh(
|
||||
JNIEnv* env, jclass, jlong native_application,
|
||||
float cloudVoxelSize,
|
||||
bool regenerateCloud,
|
||||
bool meshing,
|
||||
int textureSize,
|
||||
int textureCount,
|
||||
int normalK,
|
||||
bool optimized,
|
||||
float optimizedVoxelSize,
|
||||
int optimizedDepth,
|
||||
int optimizedMaxPolygons,
|
||||
float optimizedColorRadius,
|
||||
bool optimizedCleanWhitePolygons,
|
||||
int optimizedMinClusterSize,
|
||||
float optimizedMaxTextureDistance,
|
||||
int optimizedMinTextureClusterSize,
|
||||
bool blockRendering)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->exportMesh(
|
||||
cloudVoxelSize,
|
||||
regenerateCloud,
|
||||
meshing,
|
||||
textureSize,
|
||||
textureCount,
|
||||
normalK,
|
||||
optimized,
|
||||
optimizedVoxelSize,
|
||||
optimizedDepth,
|
||||
optimizedMaxPolygons,
|
||||
optimizedColorRadius,
|
||||
optimizedCleanWhitePolygons,
|
||||
optimizedMinClusterSize,
|
||||
optimizedMaxTextureDistance,
|
||||
optimizedMinTextureClusterSize,
|
||||
blockRendering);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT bool JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_postExportation(
|
||||
JNIEnv* env, jclass, jlong native_application, bool visualize)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->postExportation(visualize);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT bool JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_writeExportedMesh(
|
||||
JNIEnv* env, jclass, jlong native_application, jstring directory, jstring name)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
std::string directoryC;
|
||||
GetJStringContent(env,directory,directoryC);
|
||||
std::string nameC;
|
||||
GetJStringContent(env,name,nameC);
|
||||
return native(native_application)->writeExportedMesh(directoryC, nameC);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT int JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_postProcessing(
|
||||
JNIEnv* env, jclass, jlong native_application, int approach)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
return native(native_application)->postProcessing(approach);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_postCameraPoseEvent(
|
||||
JNIEnv* env, jclass, jlong native_application,
|
||||
float x, float y, float z, float qx, float qy, float qz, float qw, double stamp)
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
native(native_application)->postCameraPoseEvent(x,y,z,qx,qy,qz,qw, stamp);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_postOdometryEvent(
|
||||
JNIEnv* env, jclass, jlong native_application,
|
||||
float x, float y, float z, float qx, float qy, float qz, float qw,
|
||||
float rgb_fx, float rgb_fy, float rgb_cx, float rgb_cy,
|
||||
float rgbFrameX, float rgbFrameY, float rgbFrameZ, float rgbFrameQX, float rgbFrameQY, float rgbFrameQZ, float rgbFrameQW,
|
||||
double stamp,
|
||||
jobject yPlane, jobject uPlane, jobject vPlane, int yPlaneLen, int rgbWidth, int rgbHeight, int rgbFormat,
|
||||
jobject points, int pointsLen,
|
||||
float vx, float vy, float vz, float vqx, float vqy, float vqz, float vqw, //view matrix
|
||||
float p00, float p11, float p02, float p12, float p22, float p32, float p23, // projection matrix
|
||||
float t0, float t1, float t2, float t3, float t4, float t5, float t6, float t7) // tex coord
|
||||
{
|
||||
if(native_application)
|
||||
{
|
||||
void *yPtr = env->GetDirectBufferAddress(yPlane);
|
||||
void *uPtr = env->GetDirectBufferAddress(uPlane);
|
||||
void *vPtr = env->GetDirectBufferAddress(vPlane);
|
||||
float *pointsPtr = (float *)env->GetDirectBufferAddress(points);
|
||||
native(native_application)->postOdometryEvent(
|
||||
rtabmap::Transform(x,y,z,qx,qy,qz,qw),
|
||||
rgb_fx,rgb_fy,rgb_cx,rgb_cy,
|
||||
0,0,0,0,
|
||||
rtabmap::Transform(rgbFrameX, rgbFrameY, rgbFrameZ, rgbFrameQX, rgbFrameQY, rgbFrameQZ, rgbFrameQW),
|
||||
rtabmap::Transform(),
|
||||
stamp,
|
||||
0,
|
||||
yPtr, uPtr, vPtr, yPlaneLen, rgbWidth, rgbHeight, rgbFormat,
|
||||
0,0,0,0,0, //depth
|
||||
0,0,0,0,0, //conf
|
||||
pointsPtr, pointsLen, 4,
|
||||
rtabmap::Transform(vx, vy, vz, vqx, vqy, vqz, vqw),
|
||||
p00, p11, p02, p12, p22, p32, p23,
|
||||
t0, t1, t2, t3, t4, t5, t6, t7);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("native_application is null!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_postOdometryEventDepth(
|
||||
JNIEnv* env, jclass, jlong native_application,
|
||||
float x, float y, float z, float qx, float qy, float qz, float qw,
|
||||
float rgb_fx, float rgb_fy, float rgb_cx, float rgb_cy,
|
||||
float depth_fx, float depth_fy, float depth_cx, float depth_cy,
|
||||
float rgbFrameX, float rgbFrameY, float rgbFrameZ, float rgbFrameQX, float rgbFrameQY, float rgbFrameQZ, float rgbFrameQW,
|
||||
float depthFrameX, float depthFrameY, float depthFrameZ, float depthFrameQX, float depthFrameQY, float depthFrameQZ, float depthFrameQW,
|
||||
double rgbStamp,
|
||||
double depthStamp,
|
||||
jobject yPlane, jobject uPlane, jobject vPlane, int yPlaneLen, int rgbWidth, int rgbHeight, int rgbFormat,
|
||||
jobject depth, int depthLen, int depthWidth, int depthHeight, int depthFormat,
|
||||
jobject points, int pointsLen,
|
||||
float vx, float vy, float vz, float vqx, float vqy, float vqz, float vqw, //view matrix
|
||||
float p00, float p11, float p02, float p12, float p22, float p32, float p23, // projection matrix
|
||||
float t0, float t1, float t2, float t3, float t4, float t5, float t6, float t7) // tex coord)
|
||||
{
|
||||
void *yPtr = env->GetDirectBufferAddress(yPlane);
|
||||
void *uPtr = env->GetDirectBufferAddress(uPlane);
|
||||
void *vPtr = env->GetDirectBufferAddress(vPlane);
|
||||
void *depthPtr = env->GetDirectBufferAddress(depth);
|
||||
float *pointsPtr = (float *)env->GetDirectBufferAddress(points);
|
||||
native(native_application)->postOdometryEvent(
|
||||
rtabmap::Transform(x,y,z,qx,qy,qz,qw),
|
||||
rgb_fx,rgb_fy,rgb_cx,rgb_cy,
|
||||
depth_fx,depth_fy,depth_cx,depth_cy,
|
||||
rtabmap::Transform(rgbFrameX, rgbFrameY, rgbFrameZ, rgbFrameQX, rgbFrameQY, rgbFrameQZ, rgbFrameQW),
|
||||
rtabmap::Transform(depthFrameX, depthFrameY, depthFrameZ, depthFrameQX, depthFrameQY, depthFrameQZ, depthFrameQW),
|
||||
rgbStamp,
|
||||
depthStamp,
|
||||
yPtr, uPtr, vPtr, yPlaneLen, rgbWidth, rgbHeight, rgbFormat,
|
||||
depthPtr, depthLen, depthWidth, depthHeight, depthFormat,
|
||||
0,0,0,0,0, // conf
|
||||
pointsPtr, pointsLen, 4,
|
||||
rtabmap::Transform(vx, vy, vz, vqx, vqy, vqz, vqw),
|
||||
p00, p11, p02, p12, p22, p32, p23,
|
||||
t0, t1, t2, t3, t4, t5, t6, t7);
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
1235
app/android/jni/point_cloud_drawable.cpp
Normal file
1235
app/android/jni/point_cloud_drawable.cpp
Normal file
File diff suppressed because it is too large
Load Diff
140
app/android/jni/point_cloud_drawable.h
Normal file
140
app/android/jni/point_cloud_drawable.h
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the Universite de Sherbrooke nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef TANGO_POINT_CLOUD_POINT_CLOUD_DRAWABLE_H_
|
||||
#define TANGO_POINT_CLOUD_POINT_CLOUD_DRAWABLE_H_
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <jni.h>
|
||||
#endif
|
||||
|
||||
#include <tango-gl/util.h>
|
||||
#include <vector>
|
||||
#include <pcl/point_cloud.h>
|
||||
#include <pcl/point_types.h>
|
||||
#include <rtabmap/core/Transform.h>
|
||||
#include <pcl/Vertices.h>
|
||||
#include "util.h"
|
||||
|
||||
// PointCloudDrawable is responsible for the point cloud rendering.
|
||||
class PointCloudDrawable {
|
||||
public:
|
||||
static void createShaderPrograms();
|
||||
static void releaseShaderPrograms();
|
||||
|
||||
private:
|
||||
static std::vector<GLuint> shaderPrograms_;
|
||||
|
||||
public:
|
||||
PointCloudDrawable(
|
||||
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
|
||||
const pcl::IndicesPtr & indices,
|
||||
float gainR = 1.0f,
|
||||
float gainG = 1.0f,
|
||||
float gainB = 1.0f);
|
||||
PointCloudDrawable(
|
||||
const rtabmap::Mesh & mesh,
|
||||
bool createWireframe = false);
|
||||
virtual ~PointCloudDrawable();
|
||||
|
||||
void updatePolygons(const std::vector<pcl::Vertices> & polygons, const std::vector<pcl::Vertices> & polygonsLowRes = std::vector<pcl::Vertices>(), bool createWireframe = false);
|
||||
void updateCloud(const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud, const pcl::IndicesPtr & indices);
|
||||
void updateMesh(const rtabmap::Mesh & mesh, bool createWireframe = false);
|
||||
void setPose(const rtabmap::Transform & pose);
|
||||
void setVisible(bool visible) {visible_=visible;}
|
||||
void setGains(float gainR, float gainG, float gainB) {gainR_ = gainR; gainG_ = gainG; gainB_ = gainB;}
|
||||
rtabmap::Transform getPose() const {return pose_;}
|
||||
const glm::mat4 & getPoseGl() const {return poseGl_;}
|
||||
bool isVisible() const {return visible_;}
|
||||
bool hasMesh() const {return index_buffers_[0] != 0;}
|
||||
bool hasTexture() const {return texture_ != 0;}
|
||||
float getMinHeight() const {return minHeight_;}
|
||||
const pcl::PointXYZ & aabbMinModel() const {return aabbMinModel_;}
|
||||
const pcl::PointXYZ & aabbMaxModel() const {return aabbMaxModel_;}
|
||||
const pcl::PointXYZ & aabbMinWorld() const {return aabbMinWorld_;}
|
||||
const pcl::PointXYZ & aabbMaxWorld() const {return aabbMaxWorld_;}
|
||||
|
||||
// Update current point cloud data.
|
||||
//
|
||||
// @param projection_mat: projection matrix from current render camera.
|
||||
// @param view_mat: view matrix from current render camera.
|
||||
// @param model_mat: model matrix for this point cloud frame.
|
||||
// @param vertices: all vertices in this point cloud frame.
|
||||
void Render(
|
||||
const glm::mat4 & projectionMatrix,
|
||||
const glm::mat4 & viewMatrix,
|
||||
bool meshRendering = true,
|
||||
float pointSize = 3.0f,
|
||||
bool textureRendering = false,
|
||||
bool lighting = true,
|
||||
float distanceToCamSqr = 0.0f,
|
||||
const GLuint & depthTexture = 0,
|
||||
int screenWidth = 0, // nonnull if depthTexture>0
|
||||
int screenHeight = 0, // nonnull if depthTexture>0
|
||||
float nearClipPlane = 0, // nonnull if depthTexture>0
|
||||
float farClipPlane = 0, // nonnull if depthTexture>0
|
||||
bool packDepthToColorChannel = false,
|
||||
bool wireFrame = false) const;
|
||||
|
||||
private:
|
||||
template<class PointT>
|
||||
void updateAABBMinMax(const PointT & pt, pcl::PointXYZ & min, pcl::PointXYZ & max)
|
||||
{
|
||||
if(pt.x<min.x) min.x = pt.x;
|
||||
if(pt.y<min.y) min.y = pt.y;
|
||||
if(pt.z<min.z) min.z = pt.z;
|
||||
if(pt.x>max.x) max.x = pt.x;
|
||||
if(pt.y>max.y) max.y = pt.y;
|
||||
if(pt.z>max.z) max.z = pt.z;
|
||||
}
|
||||
void updateAABBWorld(const rtabmap::Transform & pose);
|
||||
|
||||
private:
|
||||
// Vertex buffer of the point cloud geometry.
|
||||
GLuint vertex_buffer_;
|
||||
GLuint texture_;
|
||||
std::vector<GLuint> index_buffers_;
|
||||
std::vector<int> index_buffers_count_;
|
||||
int nPoints_;
|
||||
rtabmap::Transform pose_;
|
||||
glm::mat4 poseGl_;
|
||||
bool visible_;
|
||||
bool hasNormals_;
|
||||
std::vector<unsigned int> organizedToDenseIndices_;
|
||||
float minHeight_; // odom frame
|
||||
|
||||
float gainR_;
|
||||
float gainG_;
|
||||
float gainB_;
|
||||
|
||||
pcl::PointXYZ aabbMinModel_;
|
||||
pcl::PointXYZ aabbMaxModel_;
|
||||
pcl::PointXYZ aabbMinWorld_;
|
||||
pcl::PointXYZ aabbMaxWorld_;
|
||||
};
|
||||
|
||||
#endif // TANGO_POINT_CLOUD_POINT_CLOUD_DRAWABLE_H_
|
||||
961
app/android/jni/scene.cpp
Normal file
961
app/android/jni/scene.cpp
Normal file
@@ -0,0 +1,961 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <tango-gl/conversions.h>
|
||||
#include <tango-gl/gesture_camera.h>
|
||||
#include <tango-gl/util.h>
|
||||
|
||||
#include <rtabmap/utilite/ULogger.h>
|
||||
#include <rtabmap/utilite/UStl.h>
|
||||
#include <rtabmap/utilite/UTimer.h>
|
||||
#include <rtabmap/core/util3d_filtering.h>
|
||||
#include <rtabmap/core/util3d_transforms.h>
|
||||
#include <rtabmap/core/util3d_surface.h>
|
||||
#include <pcl/common/transforms.h>
|
||||
#include <pcl/common/common.h>
|
||||
|
||||
#include <glm/gtx/transform.hpp>
|
||||
|
||||
#include "scene.h"
|
||||
#include "util.h"
|
||||
|
||||
// We want to represent the device properly with respect to the ground so we'll
|
||||
// add an offset in z to our origin. We'll set this offset to 1.3 meters based
|
||||
// on the average height of a human standing with a Tango device. This allows us
|
||||
// to place a grid roughly on the ground for most users.
|
||||
const glm::vec3 kHeightOffset = glm::vec3(0.0f, -1.3f, 0.0f);
|
||||
|
||||
// Color of the motion tracking trajectory.
|
||||
const tango_gl::Color kTraceColor(0.66f, 0.66f, 0.66f);
|
||||
|
||||
// Color of the ground grid.
|
||||
const tango_gl::Color kGridColor(0.85f, 0.85f, 0.85f);
|
||||
|
||||
// Frustum scale.
|
||||
const glm::vec3 kFrustumScale = glm::vec3(0.4f, 0.3f, 0.5f);
|
||||
|
||||
const std::string kGraphVertexShader =
|
||||
"precision mediump float;\n"
|
||||
"precision mediump int;\n"
|
||||
"attribute vec3 vertex;\n"
|
||||
"uniform vec3 color;\n"
|
||||
"uniform mat4 mvp;\n"
|
||||
"varying vec3 v_color;\n"
|
||||
"void main() {\n"
|
||||
" gl_Position = mvp*vec4(vertex.x, vertex.y, vertex.z, 1.0);\n"
|
||||
" v_color = color;\n"
|
||||
"}\n";
|
||||
const std::string kGraphFragmentShader =
|
||||
"precision mediump float;\n"
|
||||
"precision mediump int;\n"
|
||||
"varying vec3 v_color;\n"
|
||||
"void main() {\n"
|
||||
" gl_FragColor = vec4(v_color.z, v_color.y, v_color.x, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
|
||||
|
||||
Scene::Scene() :
|
||||
background_renderer_(0),
|
||||
gesture_camera_(0),
|
||||
axis_(0),
|
||||
frustum_(0),
|
||||
grid_(0),
|
||||
box_(0),
|
||||
trace_(0),
|
||||
graph_(0),
|
||||
graphVisible_(true),
|
||||
gridVisible_(true),
|
||||
traceVisible_(true),
|
||||
frustumVisible_(true),
|
||||
color_camera_to_display_rotation_(rtabmap::ROTATION_0),
|
||||
currentPose_(0),
|
||||
graph_shader_program_(0),
|
||||
blending_(true),
|
||||
mapRendering_(true),
|
||||
meshRendering_(true),
|
||||
meshRenderingTexture_(true),
|
||||
pointSize_(10.0f),
|
||||
boundingBoxRendering_(false),
|
||||
lighting_(false),
|
||||
backfaceCulling_(true),
|
||||
wireFrame_(false),
|
||||
r_(0.0f),
|
||||
g_(0.0f),
|
||||
b_(0.0f),
|
||||
fboId_(0),
|
||||
rboId_(0),
|
||||
screenWidth_(0),
|
||||
screenHeight_(0),
|
||||
doubleTapOn_(false)
|
||||
{
|
||||
depthTexture_ = 0;
|
||||
gesture_camera_ = new tango_gl::GestureCamera();
|
||||
gesture_camera_->SetCameraType(
|
||||
tango_gl::GestureCamera::kThirdPersonFollow);
|
||||
}
|
||||
|
||||
Scene::~Scene() {
|
||||
DeleteResources();
|
||||
delete gesture_camera_;
|
||||
delete currentPose_;
|
||||
}
|
||||
|
||||
//Should only be called in OpenGL thread!
|
||||
void Scene::InitGLContent()
|
||||
{
|
||||
if(axis_ != 0)
|
||||
{
|
||||
DeleteResources();
|
||||
}
|
||||
|
||||
UASSERT(axis_ == 0);
|
||||
|
||||
|
||||
axis_ = new tango_gl::Axis();
|
||||
frustum_ = new tango_gl::Frustum();
|
||||
trace_ = new tango_gl::Trace();
|
||||
grid_ = new tango_gl::Grid();
|
||||
box_ = new BoundingBoxDrawable();
|
||||
|
||||
|
||||
axis_->SetScale(glm::vec3(0.5f,0.5f,0.5f));
|
||||
frustum_->SetColor(kTraceColor);
|
||||
trace_->ClearVertexArray();
|
||||
trace_->SetColor(kTraceColor);
|
||||
grid_->SetColor(kGridColor);
|
||||
grid_->SetPosition(kHeightOffset);
|
||||
box_->SetShader();
|
||||
box_->SetColor(1,0,0);
|
||||
|
||||
PointCloudDrawable::createShaderPrograms();
|
||||
|
||||
if(graph_shader_program_ == 0)
|
||||
{
|
||||
graph_shader_program_ = tango_gl::util::CreateProgram(kGraphVertexShader.c_str(), kGraphFragmentShader.c_str());
|
||||
UASSERT(graph_shader_program_ != 0);
|
||||
}
|
||||
}
|
||||
|
||||
//Should only be called in OpenGL thread!
|
||||
void Scene::DeleteResources() {
|
||||
|
||||
LOGI("Scene::DeleteResources()");
|
||||
if(axis_)
|
||||
{
|
||||
delete axis_;
|
||||
axis_ = 0;
|
||||
delete frustum_;
|
||||
delete trace_;
|
||||
delete grid_;
|
||||
delete box_;
|
||||
delete background_renderer_;
|
||||
background_renderer_ = 0;
|
||||
}
|
||||
|
||||
PointCloudDrawable::releaseShaderPrograms();
|
||||
|
||||
if (graph_shader_program_) {
|
||||
glDeleteShader(graph_shader_program_);
|
||||
graph_shader_program_ = 0;
|
||||
}
|
||||
|
||||
if(fboId_>0)
|
||||
{
|
||||
glDeleteFramebuffers(1, &fboId_);
|
||||
fboId_ = 0;
|
||||
glDeleteRenderbuffers(1, &rboId_);
|
||||
rboId_ = 0;
|
||||
glDeleteTextures(1, &depthTexture_);
|
||||
depthTexture_ = 0;
|
||||
}
|
||||
|
||||
clear();
|
||||
}
|
||||
|
||||
//Should only be called in OpenGL thread!
|
||||
void Scene::clear()
|
||||
{
|
||||
LOGI("Scene::clear()");
|
||||
for(std::map<int, PointCloudDrawable*>::iterator iter=pointClouds_.begin(); iter!=pointClouds_.end(); ++iter)
|
||||
{
|
||||
delete iter->second;
|
||||
}
|
||||
for(std::map<int, tango_gl::Axis*>::iterator iter=markers_.begin(); iter!=markers_.end(); ++iter)
|
||||
{
|
||||
delete iter->second;
|
||||
}
|
||||
if(trace_)
|
||||
{
|
||||
trace_->ClearVertexArray();
|
||||
}
|
||||
if(graph_)
|
||||
{
|
||||
delete graph_;
|
||||
graph_ = 0;
|
||||
}
|
||||
pointClouds_.clear();
|
||||
markers_.clear();
|
||||
if(grid_)
|
||||
{
|
||||
grid_->SetPosition(kHeightOffset);
|
||||
}
|
||||
}
|
||||
|
||||
//Should only be called in OpenGL thread!
|
||||
void Scene::SetupViewPort(int w, int h) {
|
||||
if (h == 0) {
|
||||
LOGE("Setup graphic height not valid");
|
||||
}
|
||||
|
||||
UASSERT(gesture_camera_ != 0);
|
||||
gesture_camera_->SetWindowSize(static_cast<float>(w), static_cast<float>(h));
|
||||
glViewport(0, 0, w, h);
|
||||
if(screenWidth_ != w || screenHeight_ != h || fboId_ == 0)
|
||||
{
|
||||
UINFO("Setup viewport OpenGL: %dx%d", w, h);
|
||||
|
||||
if(fboId_>0)
|
||||
{
|
||||
glDeleteFramebuffers(1, &fboId_);
|
||||
fboId_ = 0;
|
||||
glDeleteRenderbuffers(1, &rboId_);
|
||||
rboId_ = 0;
|
||||
glDeleteTextures(1, &depthTexture_);
|
||||
depthTexture_ = 0;
|
||||
}
|
||||
|
||||
GLint originid = 0;
|
||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &originid);
|
||||
|
||||
// regenerate fbo texture
|
||||
// create a framebuffer object, you need to delete them when program exits.
|
||||
glGenFramebuffers(1, &fboId_);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fboId_);
|
||||
|
||||
// Create depth texture
|
||||
glGenTextures(1, &depthTexture_);
|
||||
glBindTexture(GL_TEXTURE_2D, depthTexture_);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glGenRenderbuffers(1, &rboId_);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, rboId_);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, w, h);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
|
||||
// Set the texture to be at the color attachment point of the FBO (we pack depth 32 bits in color)
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, depthTexture_, 0);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboId_);
|
||||
|
||||
GLuint status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
UASSERT ( status == GL_FRAMEBUFFER_COMPLETE);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, originid);
|
||||
}
|
||||
screenWidth_ = w;
|
||||
screenHeight_ = h;
|
||||
}
|
||||
|
||||
std::vector<glm::vec4> computeFrustumPlanes(const glm::mat4 & mat, bool normalize = true)
|
||||
{
|
||||
// http://www.txutxi.com/?p=444
|
||||
std::vector<glm::vec4> planes(6);
|
||||
|
||||
// Left Plane
|
||||
// col4 + col1
|
||||
planes[0].x = mat[0][3] + mat[0][0];
|
||||
planes[0].y = mat[1][3] + mat[1][0];
|
||||
planes[0].z = mat[2][3] + mat[2][0];
|
||||
planes[0].w = mat[3][3] + mat[3][0];
|
||||
|
||||
// Right Plane
|
||||
// col4 - col1
|
||||
planes[1].x = mat[0][3] - mat[0][0];
|
||||
planes[1].y = mat[1][3] - mat[1][0];
|
||||
planes[1].z = mat[2][3] - mat[2][0];
|
||||
planes[1].w = mat[3][3] - mat[3][0];
|
||||
|
||||
// Bottom Plane
|
||||
// col4 + col2
|
||||
planes[2].x = mat[0][3] + mat[0][1];
|
||||
planes[2].y = mat[1][3] + mat[1][1];
|
||||
planes[2].z = mat[2][3] + mat[2][1];
|
||||
planes[2].w = mat[3][3] + mat[3][1];
|
||||
|
||||
// Top Plane
|
||||
// col4 - col2
|
||||
planes[3].x = mat[0][3] - mat[0][1];
|
||||
planes[3].y = mat[1][3] - mat[1][1];
|
||||
planes[3].z = mat[2][3] - mat[2][1];
|
||||
planes[3].w = mat[3][3] - mat[3][1];
|
||||
|
||||
// Near Plane
|
||||
// col4 + col3
|
||||
planes[4].x = mat[0][3] + mat[0][2];
|
||||
planes[4].y = mat[1][3] + mat[1][2];
|
||||
planes[4].z = mat[2][3] + mat[2][2];
|
||||
planes[4].w = mat[3][3] + mat[3][2];
|
||||
|
||||
// Far Plane
|
||||
// col4 - col3
|
||||
planes[5].x = mat[0][3] - mat[0][2];
|
||||
planes[5].y = mat[1][3] - mat[1][2];
|
||||
planes[5].z = mat[2][3] - mat[2][2];
|
||||
planes[5].w = mat[3][3] - mat[3][2];
|
||||
|
||||
//if(normalize)
|
||||
{
|
||||
for(unsigned int i=0;i<planes.size(); ++i)
|
||||
{
|
||||
if(normalize)
|
||||
{
|
||||
float d = std::sqrt(planes[i].x * planes[i].x + planes[i].y * planes[i].y + planes[i].z * planes[i].z); // for normalizing the coordinates
|
||||
planes[i].x/=d;
|
||||
planes[i].y/=d;
|
||||
planes[i].z/=d;
|
||||
planes[i].w/=d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return planes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells whether or not b is intersecting f.
|
||||
* http://www.txutxi.com/?p=584
|
||||
* @param planes Viewing frustum.
|
||||
* @param boxMin The axis aligned bounding box min.
|
||||
* @param boxMax The axis aligned bounding box max.
|
||||
* @return True if b intersects f, false otherwise.
|
||||
*/
|
||||
bool intersectFrustumAABB(
|
||||
const std::vector<glm::vec4> &planes,
|
||||
const pcl::PointXYZ &boxMin,
|
||||
const pcl::PointXYZ &boxMax)
|
||||
{
|
||||
// Indexed for the 'index trick' later
|
||||
const pcl::PointXYZ * box[] = {&boxMin, &boxMax};
|
||||
|
||||
// We only need to do 6 point-plane tests
|
||||
for (unsigned int i = 0; i < planes.size(); ++i)
|
||||
{
|
||||
// This is the current plane
|
||||
const glm::vec4 &p = planes[i];
|
||||
|
||||
// p-vertex selection (with the index trick)
|
||||
// According to the plane normal we can know the
|
||||
// indices of the positive vertex
|
||||
const int px = p.x > 0.0f?1:0;
|
||||
const int py = p.y > 0.0f?1:0;
|
||||
const int pz = p.z > 0.0f?1:0;
|
||||
|
||||
// Dot product
|
||||
// project p-vertex on plane normal
|
||||
// (How far is p-vertex from the origin)
|
||||
const float dp =
|
||||
(p.x*box[px]->x) +
|
||||
(p.y*box[py]->y) +
|
||||
(p.z*box[pz]->z) + p.w;
|
||||
|
||||
// Doesn't intersect if it is behind the plane
|
||||
if (dp < 0) {return false; }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//Should only be called in OpenGL thread!
|
||||
int Scene::Render(const float * uvsTransformed, glm::mat4 arViewMatrix, glm::mat4 arProjectionMatrix, const rtabmap::Mesh & occlusionMesh, bool mapping)
|
||||
{
|
||||
UASSERT(gesture_camera_ != 0);
|
||||
|
||||
if(currentPose_ == 0)
|
||||
{
|
||||
currentPose_ = new rtabmap::Transform(0,0,0,0,0,-M_PI/2.0f);
|
||||
}
|
||||
glm::vec3 position(currentPose_->x(), currentPose_->y(), currentPose_->z());
|
||||
Eigen::Quaternionf quat = currentPose_->getQuaternionf();
|
||||
glm::quat rotation(quat.w(), quat.x(), quat.y(), quat.z());
|
||||
glm::mat4 rotateM;
|
||||
if(!currentPose_->isNull())
|
||||
{
|
||||
rotateM = glm::rotate<float>(float(color_camera_to_display_rotation_)*-1.57079632679489661923132169163975144, glm::vec3(0.0f, 0.0f, 1.0f));
|
||||
|
||||
if (gesture_camera_->GetCameraType() == tango_gl::GestureCamera::kFirstPerson)
|
||||
{
|
||||
// In first person mode, we directly control camera's motion.
|
||||
gesture_camera_->SetPosition(position);
|
||||
gesture_camera_->SetRotation(rotation*glm::quat(rotateM));
|
||||
}
|
||||
else
|
||||
{
|
||||
// In third person or top down mode, we follow the camera movement.
|
||||
gesture_camera_->SetAnchorPosition(position, rotation*glm::quat(rotateM));
|
||||
}
|
||||
}
|
||||
|
||||
glm::mat4 projectionMatrix = gesture_camera_->GetProjectionMatrix();
|
||||
glm::mat4 viewMatrix = gesture_camera_->GetViewMatrix();
|
||||
|
||||
bool renderBackgroundCamera =
|
||||
background_renderer_ &&
|
||||
gesture_camera_->GetCameraType() == tango_gl::GestureCamera::kFirstPerson &&
|
||||
!rtabmap::glmToTransform(arProjectionMatrix).isNull() &&
|
||||
uvsTransformed;
|
||||
|
||||
if(renderBackgroundCamera)
|
||||
{
|
||||
if(projectionMatrix[0][0] > arProjectionMatrix[0][0]-0.3)
|
||||
{
|
||||
projectionMatrix = arProjectionMatrix;
|
||||
viewMatrix = arViewMatrix;
|
||||
}
|
||||
else
|
||||
{
|
||||
renderBackgroundCamera = false;
|
||||
}
|
||||
}
|
||||
|
||||
rtabmap::Transform openglCamera = GetOpenGLCameraPose();//*rtabmap::Transform(0.0f, 0.0f, 3.0f, 0.0f, 0.0f, 0.0f);
|
||||
// transform in same coordinate as frustum filtering
|
||||
openglCamera *= rtabmap::Transform(
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
-1.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
//Culling
|
||||
std::vector<glm::vec4> planes = computeFrustumPlanes(projectionMatrix*viewMatrix, true);
|
||||
std::vector<PointCloudDrawable*> cloudsToDraw(pointClouds_.size());
|
||||
int oi=0;
|
||||
for(std::map<int, PointCloudDrawable*>::const_iterator iter=pointClouds_.begin(); iter!=pointClouds_.end(); ++iter)
|
||||
{
|
||||
if(!mapRendering_ && iter->first > 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if(iter->second->isVisible())
|
||||
{
|
||||
if(intersectFrustumAABB(planes,
|
||||
iter->second->aabbMinWorld(),
|
||||
iter->second->aabbMaxWorld()))
|
||||
{
|
||||
cloudsToDraw[oi++] = iter->second;
|
||||
}
|
||||
}
|
||||
}
|
||||
cloudsToDraw.resize(oi);
|
||||
|
||||
// First rendering to get depth texture
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LESS);
|
||||
glDepthMask(GL_TRUE);
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
glDisable (GL_BLEND);
|
||||
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
if(backfaceCulling_)
|
||||
{
|
||||
glEnable(GL_CULL_FACE);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_CULL_FACE);
|
||||
}
|
||||
|
||||
bool onlineBlending =
|
||||
(!meshRendering_ &&
|
||||
occlusionMesh.cloud.get() &&
|
||||
occlusionMesh.cloud->size()) ||
|
||||
(blending_ &&
|
||||
gesture_camera_->GetCameraType()!=tango_gl::GestureCamera::kTopOrtho &&
|
||||
mapRendering_ && meshRendering_ &&
|
||||
(cloudsToDraw.size() > 1 || (renderBackgroundCamera && wireFrame_)));
|
||||
|
||||
if(onlineBlending && fboId_)
|
||||
{
|
||||
GLint originid = 0;
|
||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &originid);
|
||||
|
||||
// set the rendering destination to FBO
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fboId_);
|
||||
|
||||
glClearColor(0, 0, 0, 0);
|
||||
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||
|
||||
// Draw scene
|
||||
for(std::vector<PointCloudDrawable*>::const_iterator iter=cloudsToDraw.begin(); iter!=cloudsToDraw.end(); ++iter)
|
||||
{
|
||||
Eigen::Vector3f cloudToCamera(
|
||||
(*iter)->getPose().x() - openglCamera.x(),
|
||||
(*iter)->getPose().y() - openglCamera.y(),
|
||||
(*iter)->getPose().z() - openglCamera.z());
|
||||
float distanceToCameraSqr = cloudToCamera[0]*cloudToCamera[0] + cloudToCamera[1]*cloudToCamera[1] + cloudToCamera[2]*cloudToCamera[2];
|
||||
(*iter)->Render(projectionMatrix, viewMatrix, meshRendering_, pointSize_, false, false, distanceToCameraSqr, 0, 0, 0, 0, 0, true);
|
||||
}
|
||||
|
||||
if(!meshRendering_ && occlusionMesh.cloud.get() && occlusionMesh.cloud->size())
|
||||
{
|
||||
PointCloudDrawable drawable(occlusionMesh);
|
||||
drawable.Render(projectionMatrix, viewMatrix, true, pointSize_, false, false, 0, 0, 0, 0, 0, 0, true);
|
||||
}
|
||||
|
||||
// back to normal window-system-provided framebuffer
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, originid); // unbind
|
||||
}
|
||||
|
||||
if(doubleTapOn_ && gesture_camera_->GetCameraType() != tango_gl::GestureCamera::kFirstPerson)
|
||||
{
|
||||
glClearColor(0, 0, 0, 0);
|
||||
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||
|
||||
// FIXME: we could use the depthTexture if already computed!
|
||||
for(std::vector<PointCloudDrawable*>::const_iterator iter=cloudsToDraw.begin(); iter!=cloudsToDraw.end(); ++iter)
|
||||
{
|
||||
Eigen::Vector3f cloudToCamera(
|
||||
(*iter)->getPose().x() - openglCamera.x(),
|
||||
(*iter)->getPose().y() - openglCamera.y(),
|
||||
(*iter)->getPose().z() - openglCamera.z());
|
||||
float distanceToCameraSqr = cloudToCamera[0]*cloudToCamera[0] + cloudToCamera[1]*cloudToCamera[1] + cloudToCamera[2]*cloudToCamera[2];
|
||||
|
||||
(*iter)->Render(projectionMatrix, viewMatrix, meshRendering_, pointSize_*10.0f, false, false, distanceToCameraSqr, 0, 0, 0, 0, 0, true);
|
||||
}
|
||||
|
||||
GLubyte zValue[4];
|
||||
glReadPixels(doubleTapPos_.x*screenWidth_, screenHeight_-doubleTapPos_.y*screenHeight_, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, zValue);
|
||||
float zValueF = float(zValue[0]/255.0f) + float(zValue[1]/255.0f)/255.0f + float(zValue[2]/255.0f)/65025.0f + float(zValue[3]/255.0f)/160581375.0f;
|
||||
|
||||
if(zValueF != 0.0f)
|
||||
{
|
||||
zValueF = zValueF*2.0-1.0;//NDC
|
||||
glm::vec4 point = glm::inverse(projectionMatrix*viewMatrix)*glm::vec4(doubleTapPos_.x*2.0f-1.0f, (1.0f-doubleTapPos_.y)*2.0f-1.0f, zValueF, 1.0f);
|
||||
point /= point.w;
|
||||
gesture_camera_->SetAnchorOffset(glm::vec3(point.x, point.y, point.z) - position);
|
||||
}
|
||||
}
|
||||
doubleTapOn_ = false;
|
||||
|
||||
glClearColor(r_, g_, b_, 1.0f);
|
||||
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||
|
||||
if(renderBackgroundCamera && (!onlineBlending || !meshRendering_))
|
||||
{
|
||||
background_renderer_->Draw(uvsTransformed, 0, screenWidth_, screenHeight_, false);
|
||||
|
||||
//To debug occlusion image:
|
||||
//PointCloudDrawable drawable(occlusionMesh);
|
||||
//drawable.Render(projectionMatrix, viewMatrix, true, pointSize_, false, false, 999.0f);
|
||||
}
|
||||
|
||||
if(!currentPose_->isNull())
|
||||
{
|
||||
if (frustumVisible_ && gesture_camera_->GetCameraType() != tango_gl::GestureCamera::kFirstPerson)
|
||||
{
|
||||
frustum_->SetPosition(position);
|
||||
frustum_->SetRotation(rotation);
|
||||
// Set the frustum scale to 4:3, this doesn't necessarily match the physical
|
||||
// camera's aspect ratio, this is just for visualization purposes.
|
||||
frustum_->SetScale(kFrustumScale);
|
||||
frustum_->Render(projectionMatrix, viewMatrix);
|
||||
|
||||
rtabmap::Transform cameraFrame = *currentPose_*rtabmap::optical_T_opengl*rtabmap::CameraMobile::opticalRotationInv;
|
||||
glm::vec3 positionCamera(cameraFrame.x(), cameraFrame.y(), cameraFrame.z());
|
||||
Eigen::Quaternionf quatCamera = cameraFrame.getQuaternionf();
|
||||
glm::quat rotationCamera(quatCamera.w(), quatCamera.x(), quatCamera.y(), quatCamera.z());
|
||||
|
||||
axis_->SetPosition(positionCamera);
|
||||
axis_->SetRotation(rotationCamera);
|
||||
axis_->Render(projectionMatrix, viewMatrix);
|
||||
}
|
||||
|
||||
trace_->UpdateVertexArray(position);
|
||||
if(traceVisible_)
|
||||
{
|
||||
trace_->Render(projectionMatrix, viewMatrix);
|
||||
}
|
||||
else
|
||||
{
|
||||
trace_->ClearVertexArray();
|
||||
}
|
||||
}
|
||||
|
||||
if(gridVisible_ && !renderBackgroundCamera)
|
||||
{
|
||||
grid_->Render(projectionMatrix, viewMatrix);
|
||||
}
|
||||
|
||||
if(graphVisible_ && graph_)
|
||||
{
|
||||
graph_->Render(projectionMatrix, viewMatrix);
|
||||
}
|
||||
|
||||
|
||||
if(onlineBlending)
|
||||
{
|
||||
glEnable (GL_BLEND);
|
||||
glDepthMask(GL_FALSE);
|
||||
}
|
||||
|
||||
for(std::vector<PointCloudDrawable*>::const_iterator iter=cloudsToDraw.begin(); iter!=cloudsToDraw.end(); ++iter)
|
||||
{
|
||||
PointCloudDrawable * cloud = *iter;
|
||||
|
||||
if(boundingBoxRendering_)
|
||||
{
|
||||
box_->updateVertices(cloud->aabbMinWorld(), cloud->aabbMaxWorld());
|
||||
box_->Render(projectionMatrix, viewMatrix);
|
||||
}
|
||||
|
||||
Eigen::Vector3f cloudToCamera(
|
||||
cloud->getPose().x() - openglCamera.x(),
|
||||
cloud->getPose().y() - openglCamera.y(),
|
||||
cloud->getPose().z() - openglCamera.z());
|
||||
float distanceToCameraSqr = cloudToCamera[0]*cloudToCamera[0] + cloudToCamera[1]*cloudToCamera[1] + cloudToCamera[2]*cloudToCamera[2];
|
||||
|
||||
cloud->Render(projectionMatrix, viewMatrix, meshRendering_, pointSize_, meshRenderingTexture_, lighting_, distanceToCameraSqr, onlineBlending?depthTexture_:0, screenWidth_, screenHeight_, gesture_camera_->getNearClipPlane(), gesture_camera_->getFarClipPlane(), false, wireFrame_);
|
||||
}
|
||||
|
||||
if(onlineBlending)
|
||||
{
|
||||
if(renderBackgroundCamera && meshRendering_)
|
||||
{
|
||||
background_renderer_->Draw(uvsTransformed, depthTexture_, screenWidth_, screenHeight_, mapping);
|
||||
}
|
||||
|
||||
glDisable (GL_BLEND);
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
|
||||
//draw markers on foreground
|
||||
for(std::map<int, tango_gl::Axis*>::const_iterator iter=markers_.begin(); iter!=markers_.end(); ++iter)
|
||||
{
|
||||
iter->second->Render(projectionMatrix, viewMatrix);
|
||||
}
|
||||
|
||||
return (int)cloudsToDraw.size();
|
||||
}
|
||||
|
||||
void Scene::SetCameraType(tango_gl::GestureCamera::CameraType camera_type) {
|
||||
gesture_camera_->SetCameraType(camera_type);
|
||||
}
|
||||
|
||||
void Scene::SetCameraPose(const rtabmap::Transform & pose)
|
||||
{
|
||||
UASSERT(!pose.isNull());
|
||||
if(currentPose_ ==0)
|
||||
{
|
||||
currentPose_ = new rtabmap::Transform(0,0,0,0,0,-M_PI/2.0f);
|
||||
}
|
||||
*currentPose_ = pose;
|
||||
}
|
||||
|
||||
void Scene::setFOV(float angle)
|
||||
{
|
||||
gesture_camera_->SetFieldOfView(angle);
|
||||
}
|
||||
void Scene::setOrthoCropFactor(float value)
|
||||
{
|
||||
gesture_camera_->SetOrthoCropFactor(value);
|
||||
}
|
||||
void Scene::setGridRotation(float angleDeg)
|
||||
{
|
||||
float angleRad = angleDeg * DEGREE_2_RADIANS;
|
||||
if(grid_)
|
||||
{
|
||||
glm::quat rot = glm::rotate(glm::quat(1,0,0,0), angleRad, glm::vec3(0, 1, 0));
|
||||
grid_->SetRotation(rot);
|
||||
}
|
||||
}
|
||||
|
||||
rtabmap::Transform Scene::GetOpenGLCameraPose(float * fov) const
|
||||
{
|
||||
if(fov)
|
||||
{
|
||||
*fov = gesture_camera_->getFOV();
|
||||
}
|
||||
return rtabmap::glmToTransform(gesture_camera_->GetTransformationMatrix());
|
||||
}
|
||||
|
||||
void Scene::OnTouchEvent(int touch_count,
|
||||
tango_gl::GestureCamera::TouchEvent event, float x0,
|
||||
float y0, float x1, float y1) {
|
||||
UASSERT(gesture_camera_ != 0);
|
||||
if(touch_count == 3)
|
||||
{
|
||||
//doubletap
|
||||
if(!doubleTapOn_)
|
||||
{
|
||||
doubleTapPos_.x = x0;
|
||||
doubleTapPos_.y = y0;
|
||||
doubleTapOn_ = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// rotate/translate/zoom
|
||||
gesture_camera_->OnTouchEvent(touch_count, event, x0, y0, x1, y1);
|
||||
}
|
||||
}
|
||||
|
||||
void Scene::updateGraph(
|
||||
const std::map<int, rtabmap::Transform> & poses,
|
||||
const std::multimap<int, rtabmap::Link> & links)
|
||||
{
|
||||
LOGI("updateGraph");
|
||||
//create
|
||||
UASSERT(graph_shader_program_ != 0);
|
||||
delete graph_;
|
||||
graph_ = new GraphDrawable(graph_shader_program_, poses, links);
|
||||
}
|
||||
|
||||
void Scene::setGraphVisible(bool visible)
|
||||
{
|
||||
graphVisible_ = visible;
|
||||
}
|
||||
|
||||
void Scene::setGridVisible(bool visible)
|
||||
{
|
||||
gridVisible_ = visible;
|
||||
}
|
||||
|
||||
void Scene::setTraceVisible(bool visible)
|
||||
{
|
||||
traceVisible_ = visible;
|
||||
}
|
||||
|
||||
void Scene::setFrustumVisible(bool visible)
|
||||
{
|
||||
frustumVisible_ = visible;
|
||||
}
|
||||
|
||||
//Should only be called in OpenGL thread!
|
||||
void Scene::addMarker(
|
||||
int id,
|
||||
const rtabmap::Transform & pose)
|
||||
{
|
||||
LOGI("add marker %d", id);
|
||||
std::map<int, tango_gl::Axis*>::iterator iter=markers_.find(id);
|
||||
if(iter == markers_.end())
|
||||
{
|
||||
//create
|
||||
tango_gl::Axis * drawable = new tango_gl::Axis();
|
||||
drawable->SetScale(glm::vec3(0.05f,0.05f,0.05f));
|
||||
drawable->SetLineWidth(5);
|
||||
markers_.insert(std::make_pair(id, drawable));
|
||||
}
|
||||
setMarkerPose(id, pose);
|
||||
}
|
||||
void Scene::setMarkerPose(int id, const rtabmap::Transform & pose)
|
||||
{
|
||||
UASSERT(!pose.isNull());
|
||||
std::map<int, tango_gl::Axis*>::iterator iter=markers_.find(id);
|
||||
if(iter != markers_.end())
|
||||
{
|
||||
glm::vec3 position(pose.x(), pose.y(), pose.z());
|
||||
Eigen::Quaternionf quat = pose.getQuaternionf();
|
||||
glm::quat rotation(quat.w(), quat.x(), quat.y(), quat.z());
|
||||
iter->second->SetPosition(position);
|
||||
iter->second->SetRotation(rotation);
|
||||
}
|
||||
}
|
||||
bool Scene::hasMarker(int id) const
|
||||
{
|
||||
return markers_.find(id) != markers_.end();
|
||||
}
|
||||
void Scene::removeMarker(int id)
|
||||
{
|
||||
std::map<int, tango_gl::Axis*>::iterator iter=markers_.find(id);
|
||||
if(iter != markers_.end())
|
||||
{
|
||||
delete iter->second;
|
||||
markers_.erase(iter);
|
||||
}
|
||||
}
|
||||
std::set<int> Scene::getAddedMarkers() const
|
||||
{
|
||||
return uKeysSet(markers_);
|
||||
}
|
||||
|
||||
void Scene::addCloud(
|
||||
int id,
|
||||
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
|
||||
const pcl::IndicesPtr & indices,
|
||||
const rtabmap::Transform & pose)
|
||||
{
|
||||
LOGI("add cloud %d (%d points %d indices)", id, (int)cloud->size(), indices.get()?(int)indices->size():0);
|
||||
std::map<int, PointCloudDrawable*>::iterator iter=pointClouds_.find(id);
|
||||
if(iter != pointClouds_.end())
|
||||
{
|
||||
delete iter->second;
|
||||
pointClouds_.erase(iter);
|
||||
}
|
||||
|
||||
//create
|
||||
PointCloudDrawable * drawable = new PointCloudDrawable(cloud, indices);
|
||||
drawable->setPose(pose);
|
||||
pointClouds_.insert(std::make_pair(id, drawable));
|
||||
}
|
||||
|
||||
void Scene::addMesh(
|
||||
int id,
|
||||
const rtabmap::Mesh & mesh,
|
||||
const rtabmap::Transform & pose,
|
||||
bool createWireframe)
|
||||
{
|
||||
LOGI("add mesh %d", id);
|
||||
std::map<int, PointCloudDrawable*>::iterator iter=pointClouds_.find(id);
|
||||
if(iter != pointClouds_.end())
|
||||
{
|
||||
delete iter->second;
|
||||
pointClouds_.erase(iter);
|
||||
}
|
||||
|
||||
//create
|
||||
PointCloudDrawable * drawable = new PointCloudDrawable(mesh, createWireframe);
|
||||
drawable->setPose(pose);
|
||||
pointClouds_.insert(std::make_pair(id, drawable));
|
||||
|
||||
if(!mesh.pose.isNull() && mesh.cloud->size() && (!mesh.cloud->isOrganized() || mesh.indices->size()))
|
||||
{
|
||||
UTimer time;
|
||||
float height = 0.0f;
|
||||
Eigen::Affine3f affinePose = mesh.pose.toEigen3f();
|
||||
if(mesh.polygons.size())
|
||||
{
|
||||
for(unsigned int i=0; i<mesh.polygons.size(); ++i)
|
||||
{
|
||||
for(unsigned int j=0; j<mesh.polygons[i].vertices.size(); ++j)
|
||||
{
|
||||
pcl::PointXYZRGB pt = pcl::transformPoint(mesh.cloud->at(mesh.polygons[i].vertices[j]), affinePose);
|
||||
if(pt.z < height)
|
||||
{
|
||||
height = pt.z;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(mesh.cloud->isOrganized())
|
||||
{
|
||||
for(unsigned int i=0; i<mesh.indices->size(); ++i)
|
||||
{
|
||||
pcl::PointXYZRGB pt = pcl::transformPoint(mesh.cloud->at(mesh.indices->at(i)), affinePose);
|
||||
if(pt.z < height)
|
||||
{
|
||||
height = pt.z;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(unsigned int i=0; i<mesh.cloud->size(); ++i)
|
||||
{
|
||||
pcl::PointXYZRGB pt = pcl::transformPoint(mesh.cloud->at(i), affinePose);
|
||||
if(pt.z < height)
|
||||
{
|
||||
height = pt.z;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(grid_->GetPosition().y == kHeightOffset.y || grid_->GetPosition().y > height)
|
||||
{
|
||||
grid_->SetPosition(glm::vec3(0,height,0));
|
||||
}
|
||||
LOGD("compute min height %f s", time.ticks());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Scene::setCloudPose(int id, const rtabmap::Transform & pose)
|
||||
{
|
||||
UASSERT(!pose.isNull());
|
||||
std::map<int, PointCloudDrawable*>::iterator iter=pointClouds_.find(id);
|
||||
if(iter != pointClouds_.end())
|
||||
{
|
||||
iter->second->setPose(pose);
|
||||
}
|
||||
}
|
||||
|
||||
void Scene::setCloudVisible(int id, bool visible)
|
||||
{
|
||||
std::map<int, PointCloudDrawable*>::iterator iter=pointClouds_.find(id);
|
||||
if(iter != pointClouds_.end())
|
||||
{
|
||||
iter->second->setVisible(visible);
|
||||
}
|
||||
}
|
||||
|
||||
bool Scene::hasCloud(int id) const
|
||||
{
|
||||
return pointClouds_.find(id) != pointClouds_.end();
|
||||
}
|
||||
|
||||
bool Scene::hasMesh(int id) const
|
||||
{
|
||||
return pointClouds_.find(id) != pointClouds_.end() && pointClouds_.at(id)->hasMesh();
|
||||
}
|
||||
|
||||
bool Scene::hasTexture(int id) const
|
||||
{
|
||||
return pointClouds_.find(id) != pointClouds_.end() && pointClouds_.at(id)->hasTexture();
|
||||
}
|
||||
|
||||
std::set<int> Scene::getAddedClouds() const
|
||||
{
|
||||
return uKeysSet(pointClouds_);
|
||||
}
|
||||
|
||||
void Scene::updateCloudPolygons(int id, const std::vector<pcl::Vertices> & polygons)
|
||||
{
|
||||
std::map<int, PointCloudDrawable*>::iterator iter=pointClouds_.find(id);
|
||||
if(iter != pointClouds_.end())
|
||||
{
|
||||
iter->second->updatePolygons(polygons);
|
||||
}
|
||||
}
|
||||
|
||||
void Scene::updateMesh(int id, const rtabmap::Mesh & mesh)
|
||||
{
|
||||
std::map<int, PointCloudDrawable*>::iterator iter=pointClouds_.find(id);
|
||||
if(iter != pointClouds_.end())
|
||||
{
|
||||
iter->second->updateMesh(mesh);
|
||||
}
|
||||
}
|
||||
|
||||
void Scene::updateGains(int id, float gainR, float gainG, float gainB)
|
||||
{
|
||||
std::map<int, PointCloudDrawable*>::iterator iter=pointClouds_.find(id);
|
||||
if(iter != pointClouds_.end())
|
||||
{
|
||||
iter->second->setGains(gainR, gainG, gainB);
|
||||
}
|
||||
}
|
||||
|
||||
void Scene::setGridColor(float r, float g, float b)
|
||||
{
|
||||
if(grid_)
|
||||
{
|
||||
grid_->SetColor(r, g, b);
|
||||
}
|
||||
}
|
||||
218
app/android/jni/scene.h
Normal file
218
app/android/jni/scene.h
Normal file
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TANGO_POINT_CLOUD_SCENE_H_
|
||||
#define TANGO_POINT_CLOUD_SCENE_H_
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <jni.h>
|
||||
#endif
|
||||
#include <memory>
|
||||
#include <set>
|
||||
|
||||
#include "CameraMobile.h"
|
||||
#include <tango-gl/axis.h>
|
||||
#include <tango-gl/camera.h>
|
||||
#include <tango-gl/color.h>
|
||||
#include <tango-gl/gesture_camera.h>
|
||||
#include <tango-gl/grid.h>
|
||||
#include <tango-gl/frustum.h>
|
||||
#include <tango-gl/trace.h>
|
||||
#include <tango-gl/transform.h>
|
||||
#include <tango-gl/util.h>
|
||||
|
||||
#include <rtabmap/core/Transform.h>
|
||||
#include <rtabmap/core/Link.h>
|
||||
|
||||
#include "point_cloud_drawable.h"
|
||||
#include "graph_drawable.h"
|
||||
#include "bounding_box_drawable.h"
|
||||
#include "background_renderer.h"
|
||||
|
||||
#include <pcl/point_cloud.h>
|
||||
#include <pcl/point_types.h>
|
||||
|
||||
// Scene provides OpenGL drawable objects and renders them for visualization.
|
||||
class Scene {
|
||||
public:
|
||||
// Constructor and destructor.
|
||||
Scene();
|
||||
~Scene();
|
||||
|
||||
// Allocate OpenGL resources for rendering.
|
||||
void InitGLContent();
|
||||
|
||||
// Release non-OpenGL allocated resources.
|
||||
void DeleteResources();
|
||||
|
||||
// Setup GL view port.
|
||||
void SetupViewPort(int w, int h);
|
||||
int getViewPortWidth() const {return screenWidth_;}
|
||||
int getViewPortHeight() const {return screenHeight_;}
|
||||
|
||||
rtabmap::ScreenRotation getScreenRotation() const {return color_camera_to_display_rotation_;}
|
||||
void setScreenRotation(rtabmap::ScreenRotation colorCameraToDisplayRotation) {color_camera_to_display_rotation_ = colorCameraToDisplayRotation;}
|
||||
|
||||
void clear(); // removed all point clouds
|
||||
|
||||
// Render loop.
|
||||
// @param: cur_pose_transformation, latest pose's transformation.
|
||||
// @param: point_cloud_transformation, pose transformation at point cloud
|
||||
// frame's timestamp.
|
||||
// @param: point_cloud_vertices, point cloud's vertices of the current point
|
||||
// frame.
|
||||
int Render(const float * uvsTransformed = 0, glm::mat4 arViewMatrix = glm::mat4(0), glm::mat4 arProjectionMatrix=glm::mat4(0), const rtabmap::Mesh & occlusionMesh=rtabmap::Mesh(), bool mapping=false);
|
||||
|
||||
// Set render camera's viewing angle, first person, third person or top down.
|
||||
//
|
||||
// @param: camera_type, camera type includes first person, third person and
|
||||
// top down
|
||||
void SetCameraType(tango_gl::GestureCamera::CameraType camera_type);
|
||||
tango_gl::GestureCamera::CameraType GetCameraType() const {return gesture_camera_->GetCameraType();}
|
||||
|
||||
void SetCameraPose(const rtabmap::Transform & pose); // opengl camera
|
||||
rtabmap::Transform GetCameraPose() const {return currentPose_!=0?*currentPose_:rtabmap::Transform();}
|
||||
rtabmap::Transform GetOpenGLCameraPose(float * fov = 0) const;
|
||||
|
||||
// Touch event passed from android activity. This function only support two
|
||||
// touches.
|
||||
//
|
||||
// @param: touch_count, total count for touches.
|
||||
// @param: event, touch event of current touch.
|
||||
// @param: x0, normalized touch location for touch 0 on x axis.
|
||||
// @param: y0, normalized touch location for touch 0 on y axis.
|
||||
// @param: x1, normalized touch location for touch 1 on x axis.
|
||||
// @param: y1, normalized touch location for touch 1 on y axis.
|
||||
void OnTouchEvent(int touch_count, tango_gl::GestureCamera::TouchEvent event,
|
||||
float x0, float y0, float x1, float y1);
|
||||
|
||||
void updateGraph(
|
||||
const std::map<int, rtabmap::Transform> & poses,
|
||||
const std::multimap<int, rtabmap::Link> & links);
|
||||
|
||||
void setGraphVisible(bool visible);
|
||||
void setGridVisible(bool visible);
|
||||
void setTraceVisible(bool visible);
|
||||
void setFrustumVisible(bool visible);
|
||||
|
||||
void addMarker(int id, const rtabmap::Transform & pose);
|
||||
void setMarkerPose(int id, const rtabmap::Transform & pose);
|
||||
bool hasMarker(int id) const;
|
||||
void removeMarker(int id);
|
||||
std::set<int> getAddedMarkers() const;
|
||||
|
||||
void addCloud(
|
||||
int id,
|
||||
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
|
||||
const pcl::IndicesPtr & indices,
|
||||
const rtabmap::Transform & pose);
|
||||
void addMesh(
|
||||
int id,
|
||||
const rtabmap::Mesh & mesh,
|
||||
const rtabmap::Transform & pose,
|
||||
bool createWireframe = false);
|
||||
|
||||
void setCloudPose(int id, const rtabmap::Transform & pose);
|
||||
void setCloudVisible(int id, bool visible);
|
||||
bool hasCloud(int id) const;
|
||||
bool hasMesh(int id) const;
|
||||
bool hasTexture(int id) const;
|
||||
std::set<int> getAddedClouds() const;
|
||||
void updateCloudPolygons(int id, const std::vector<pcl::Vertices> & polygons);
|
||||
void updateMesh(int id, const rtabmap::Mesh & mesh);
|
||||
void updateGains(int id, float gainR, float gainG, float gainB);
|
||||
|
||||
void setBlending(bool enabled) {blending_ = enabled;}
|
||||
void setMapRendering(bool enabled) {mapRendering_ = enabled;}
|
||||
void setMeshRendering(bool enabled, bool withTexture) {meshRendering_ = enabled; meshRenderingTexture_ = withTexture;}
|
||||
void setPointSize(float size) {pointSize_ = size;}
|
||||
void setFOV(float angle);
|
||||
void setOrthoCropFactor(float value);
|
||||
void setGridRotation(float angleDeg);
|
||||
void setLighting(bool enabled) {lighting_ = enabled;}
|
||||
void setBackfaceCulling(bool enabled) {backfaceCulling_ = enabled;}
|
||||
void setWireframe(bool enabled) {wireFrame_ = enabled;}
|
||||
void setBackgroundColor(float r, float g, float b) {r_=r; g_=g; b_=b;} // 0.0f <> 1.0f
|
||||
void setGridColor(float r, float g, float b);
|
||||
|
||||
bool isBlending() const {return blending_;}
|
||||
bool isMapRendering() const {return mapRendering_;}
|
||||
bool isMeshRendering() const {return meshRendering_;}
|
||||
bool isMeshTexturing() const {return meshRendering_ && meshRenderingTexture_;}
|
||||
float getPointSize() const {return pointSize_;}
|
||||
bool isLighting() const {return lighting_;}
|
||||
bool isBackfaceCulling() const {return backfaceCulling_;}
|
||||
bool isWireframe() const {return wireFrame_;}
|
||||
|
||||
BackgroundRenderer * background_renderer_;
|
||||
|
||||
private:
|
||||
// Camera object that allows user to use touch input to interact with.
|
||||
tango_gl::GestureCamera* gesture_camera_;
|
||||
|
||||
// Device axis (in device frame of reference).
|
||||
tango_gl::Axis* axis_;
|
||||
|
||||
// Device frustum.
|
||||
tango_gl::Frustum* frustum_;
|
||||
|
||||
// Ground grid.
|
||||
tango_gl::Grid* grid_;
|
||||
|
||||
// Bounding box
|
||||
BoundingBoxDrawable * box_;
|
||||
|
||||
// Trace of pose data.
|
||||
tango_gl::Trace* trace_;
|
||||
GraphDrawable * graph_;
|
||||
bool graphVisible_;
|
||||
bool gridVisible_;
|
||||
bool traceVisible_;
|
||||
bool frustumVisible_;
|
||||
|
||||
std::map<int, tango_gl::Axis*> markers_;
|
||||
|
||||
rtabmap::ScreenRotation color_camera_to_display_rotation_;
|
||||
|
||||
std::map<int, PointCloudDrawable*> pointClouds_;
|
||||
|
||||
rtabmap::Transform * currentPose_;
|
||||
|
||||
// Shader to display point cloud.
|
||||
GLuint graph_shader_program_;
|
||||
|
||||
bool blending_;
|
||||
bool mapRendering_;
|
||||
bool meshRendering_;
|
||||
bool meshRenderingTexture_;
|
||||
float pointSize_;
|
||||
bool boundingBoxRendering_;
|
||||
bool lighting_;
|
||||
bool backfaceCulling_;
|
||||
bool wireFrame_;
|
||||
float r_;
|
||||
float g_;
|
||||
float b_;
|
||||
GLuint fboId_;
|
||||
GLuint rboId_;
|
||||
GLuint depthTexture_; // 0=objects+occlusion
|
||||
GLsizei screenWidth_;
|
||||
GLsizei screenHeight_;
|
||||
bool doubleTapOn_;
|
||||
cv::Point2f doubleTapPos_;
|
||||
};
|
||||
|
||||
#endif // TANGO_POINT_CLOUD_SCENE_H_
|
||||
75
app/android/jni/tango-gl/axis.cpp
Normal file
75
app/android/jni/tango-gl/axis.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "tango-gl/axis.h"
|
||||
#include "tango-gl/shaders.h"
|
||||
|
||||
namespace tango_gl {
|
||||
|
||||
static const float float_vertices[] = {0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f};
|
||||
|
||||
static const float float_colors[] = {
|
||||
1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
|
||||
0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f};
|
||||
|
||||
Axis::Axis() : Line(3.0f, GL_LINES) {
|
||||
// Implement SetShader here, not using the dedault one.
|
||||
shader_program_ =
|
||||
util::CreateProgram(shaders::GetColorVertexShader().c_str(),
|
||||
shaders::GetBasicFragmentShader().c_str());
|
||||
if (!shader_program_) {
|
||||
LOGE("Could not create program.");
|
||||
}
|
||||
uniform_mvp_mat_ = glGetUniformLocation(shader_program_, "mvp");
|
||||
attrib_colors_ = glGetAttribLocation(shader_program_, "color");
|
||||
attrib_vertices_ = glGetAttribLocation(shader_program_, "vertex");
|
||||
|
||||
size_t size = sizeof(float_vertices) / (sizeof(float) * 3);
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
vec_vertices_.push_back(glm::vec3(float_vertices[i * 3],
|
||||
float_vertices[i * 3 + 1],
|
||||
float_vertices[i * 3 + 2]));
|
||||
vec_colors_.push_back(
|
||||
glm::vec4(float_colors[i * 4], float_colors[i * 4 + 1],
|
||||
float_colors[i * 4 + 2], float_colors[i * 4 + 3]));
|
||||
}
|
||||
}
|
||||
|
||||
void Axis::Render(const glm::mat4& projection_mat,
|
||||
const glm::mat4& view_mat) const {
|
||||
glUseProgram(shader_program_);
|
||||
glLineWidth(line_width_);
|
||||
glm::mat4 model_mat = GetTransformationMatrix();
|
||||
glm::mat4 mvp_mat = projection_mat * view_mat * model_mat;
|
||||
glUniformMatrix4fv(uniform_mvp_mat_, 1, GL_FALSE, glm::value_ptr(mvp_mat));
|
||||
|
||||
glEnableVertexAttribArray(attrib_vertices_);
|
||||
glVertexAttribPointer(attrib_vertices_, 3, GL_FLOAT, GL_FALSE,
|
||||
sizeof(glm::vec3), &vec_vertices_[0]);
|
||||
|
||||
glEnableVertexAttribArray(attrib_colors_);
|
||||
glVertexAttribPointer(attrib_colors_, 4, GL_FLOAT, GL_FALSE,
|
||||
sizeof(glm::vec4), &vec_colors_[0]);
|
||||
|
||||
glDrawArrays(render_mode_, 0, vec_vertices_.size());
|
||||
|
||||
glDisableVertexAttribArray(attrib_vertices_);
|
||||
glDisableVertexAttribArray(attrib_colors_);
|
||||
glUseProgram(0);
|
||||
}
|
||||
} // namespace tango_gl
|
||||
149
app/android/jni/tango-gl/band.cpp
Normal file
149
app/android/jni/tango-gl/band.cpp
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "tango-gl/band.h"
|
||||
#include "tango-gl/util.h"
|
||||
|
||||
namespace tango_gl {
|
||||
|
||||
// Set band resolution to 0.01m(1cm) when using UpdateVertexArray()
|
||||
static const float kMinDistanceSquared = 0.0001f;
|
||||
|
||||
Band::Band(const unsigned int max_length)
|
||||
: band_width_(0.2), max_length_(max_length) {
|
||||
SetShader();
|
||||
vertices_v_.reserve(max_length);
|
||||
pivot_left = glm::vec3(0, 0, 0);
|
||||
pivot_right = glm::vec3(0, 0, 0);
|
||||
}
|
||||
|
||||
void Band::SetWidth(const float width) {
|
||||
band_width_ = width;
|
||||
}
|
||||
|
||||
void Band::UpdateVertexArray(const glm::mat4 m, BandMode mode) {
|
||||
// First 2 vertices of a band + 3 arrow head vertices.
|
||||
bool need_to_initialize = (vertices_v_.size() < 5);
|
||||
|
||||
bool sufficient_delta = false;
|
||||
if (!need_to_initialize) {
|
||||
// Band head is the first two vertices after arrow head.
|
||||
glm::vec3 band_front = 0.5f * (vertices_v_[vertices_v_.size() - 4] +
|
||||
vertices_v_[vertices_v_.size() - 5]);
|
||||
sufficient_delta = kMinDistanceSquared <
|
||||
util::DistanceSquared(band_front, util::GetTranslationFromMatrix(m));
|
||||
}
|
||||
|
||||
if (need_to_initialize || sufficient_delta) {
|
||||
glm::vec3 left = glm::vec3(-band_width_ * 0.5f, 0, 0);
|
||||
glm::vec3 right = glm::vec3(band_width_ * 0.5f, 0, 0);
|
||||
glm::vec3 arrow_left = glm::vec3(-band_width_ * 0.75f, 0, 0);
|
||||
glm::vec3 arrow_right = glm::vec3(band_width_ * 0.75f, 0, 0);
|
||||
glm::vec3 arrow_front = glm::vec3(0, 0, -band_width_ * 0.75f);
|
||||
|
||||
// If keep right pivot point, or normal mode,
|
||||
// then only update left pivot point.
|
||||
if (mode == BandMode::kNormal || mode == BandMode::kKeepRight) {
|
||||
pivot_left = util::ApplyTransform(m, left);
|
||||
}
|
||||
// If keep left pivot point, or normal mode,
|
||||
// then only update right pivot point.
|
||||
if (mode == BandMode::kNormal || mode == BandMode::kKeepLeft) {
|
||||
pivot_right = util::ApplyTransform(m, right);
|
||||
}
|
||||
|
||||
glm::mat4 head_m = m;
|
||||
|
||||
if (mode != BandMode::kNormal) {
|
||||
glm::vec3 up = glm::vec3(0, 1.0f, 0);
|
||||
glm::vec3 position = 0.5f * (pivot_left + pivot_right);
|
||||
glm::vec3 heading = glm::cross(up, pivot_right-pivot_left);
|
||||
head_m = glm::inverse(glm::lookAt(glm::vec3(0, 0, 0), heading, up));
|
||||
head_m[3][0] = position.x;
|
||||
head_m[3][1] = position.y;
|
||||
head_m[3][2] = position.z;
|
||||
}
|
||||
|
||||
if (need_to_initialize) {
|
||||
vertices_v_.resize(5);
|
||||
} else {
|
||||
vertices_v_.resize(vertices_v_.size() + 2);
|
||||
}
|
||||
|
||||
size_t insertion_start = vertices_v_.size() - 5;
|
||||
vertices_v_[insertion_start + 0] = pivot_left;
|
||||
vertices_v_[insertion_start + 1] = pivot_right;
|
||||
vertices_v_[insertion_start + 2] = util::ApplyTransform(head_m, arrow_left);
|
||||
vertices_v_[insertion_start + 3] = util::ApplyTransform(head_m, arrow_right);
|
||||
vertices_v_[insertion_start + 4] = util::ApplyTransform(head_m, arrow_front);
|
||||
|
||||
if (vertices_v_.size() > max_length_) {
|
||||
vertices_v_.erase(vertices_v_.begin(), vertices_v_.begin() + 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Band::UpdateVertexArray(const glm::mat4 m) {
|
||||
// Defualt to call update with normal mode.
|
||||
UpdateVertexArray(m, BandMode::kNormal);
|
||||
}
|
||||
|
||||
void Band::SetVertexArray(const std::vector<glm::vec3>& v,
|
||||
const glm::vec3& up) {
|
||||
vertices_v_.clear();
|
||||
vertices_v_.reserve(2 * v.size());
|
||||
if (v.size() < 2)
|
||||
return;
|
||||
|
||||
for (size_t i = 0; i < v.size() - 1; ++i) {
|
||||
glm::vec3 gl_p_world_a = v[i];
|
||||
glm::vec3 gl_p_world_b = v[i + 1];
|
||||
glm::vec3 dir = glm::normalize(gl_p_world_b - gl_p_world_a);
|
||||
glm::vec3 left = glm::cross(up, dir);
|
||||
glm::normalize(left);
|
||||
|
||||
vertices_v_.push_back(gl_p_world_a + (band_width_ / 2.0f * left));
|
||||
vertices_v_.push_back(gl_p_world_a - (band_width_ / 2.0f * left));
|
||||
|
||||
// Cap the end of the path.
|
||||
if (i == v.size() - 2) {
|
||||
vertices_v_.push_back(gl_p_world_b + (band_width_ / 2.0f * left));
|
||||
vertices_v_.push_back(gl_p_world_b - (band_width_ / 2.0f * left));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Band::ClearVertexArray() { vertices_v_.clear(); }
|
||||
|
||||
void Band::Render(const glm::mat4& projection_mat,
|
||||
const glm::mat4& view_mat) const {
|
||||
glUseProgram(shader_program_);
|
||||
glm::mat4 model_mat = GetTransformationMatrix();
|
||||
glm::mat4 mvp_mat = projection_mat * view_mat * model_mat;
|
||||
glUniformMatrix4fv(uniform_mvp_mat_, 1, GL_FALSE, glm::value_ptr(mvp_mat));
|
||||
|
||||
glUniform4f(uniform_color_, red_, green_, blue_, alpha_);
|
||||
|
||||
glEnableVertexAttribArray(attrib_vertices_);
|
||||
glVertexAttribPointer(attrib_vertices_, 3, GL_FLOAT, GL_FALSE,
|
||||
sizeof(glm::vec3), &vertices_v_[0]);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, vertices_v_.size());
|
||||
glDisableVertexAttribArray(attrib_vertices_);
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
} // namespace tango_gl
|
||||
62
app/android/jni/tango-gl/bounding_box.cpp
Normal file
62
app/android/jni/tango-gl/bounding_box.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
#include "tango-gl/bounding_box.h"
|
||||
|
||||
namespace tango_gl {
|
||||
BoundingBox::BoundingBox(const std::vector<float>& vertices) {
|
||||
// Set min and max to the first vertice.
|
||||
bounding_min_ = glm::vec3(vertices[0], vertices[1], vertices[2]);
|
||||
bounding_max_ = bounding_min_;
|
||||
size_t vertices_count = vertices.size() / 3;
|
||||
for (size_t i = 1; i < vertices_count; i += 3) {
|
||||
bounding_min_.x = std::min(vertices[i * 3], bounding_min_.x);
|
||||
bounding_min_.y = std::min(vertices[i * 3 + 1], bounding_min_.y);
|
||||
bounding_min_.z = std::min(vertices[i * 3 + 2], bounding_min_.z);
|
||||
|
||||
bounding_max_.x = std::max(vertices[i * 3], bounding_max_.x);
|
||||
bounding_max_.y = std::max(vertices[i * 3 + 1], bounding_max_.y);
|
||||
bounding_max_.z = std::max(vertices[i * 3 + 2], bounding_max_.z);
|
||||
}
|
||||
}
|
||||
|
||||
bool BoundingBox::IsIntersecting(const Segment& segment,
|
||||
const glm::quat& rotation,
|
||||
const glm::mat4& transformation) {
|
||||
// The current bounding box.
|
||||
glm::vec3 min, max;
|
||||
|
||||
// If the mesh has been rotated, we need to derive a new bounding box
|
||||
// based on the original one, if it just been translated or scaled,
|
||||
// we can still use the original one with current model matrix applied.
|
||||
if (rotation == glm::quat(1.0f, 0.0f, 0.0f, 0.0f)) {
|
||||
min = util::ApplyTransform(transformation, bounding_min_);
|
||||
max = util::ApplyTransform(transformation, bounding_max_);
|
||||
} else {
|
||||
std::vector<glm::vec3> box;
|
||||
// Derive 8 vertices of the new bounding box from original min and max.
|
||||
box.push_back(bounding_min_);
|
||||
box.push_back(bounding_max_);
|
||||
|
||||
box.push_back(glm::vec3(bounding_min_.x, bounding_max_.y, bounding_max_.z));
|
||||
box.push_back(glm::vec3(bounding_max_.x, bounding_min_.y, bounding_min_.z));
|
||||
|
||||
box.push_back(glm::vec3(bounding_min_.x, bounding_min_.y, bounding_max_.z));
|
||||
box.push_back(glm::vec3(bounding_max_.x, bounding_max_.y, bounding_min_.z));
|
||||
|
||||
box.push_back(glm::vec3(bounding_max_.x, bounding_min_.y, bounding_max_.z));
|
||||
box.push_back(glm::vec3(bounding_min_.x, bounding_max_.y, bounding_min_.z));
|
||||
|
||||
min = util::ApplyTransform(transformation, bounding_min_);
|
||||
max = min;
|
||||
for (size_t i = 1; i < box.size(); i++) {
|
||||
glm::vec3 temp = util::ApplyTransform(transformation, box[i]);
|
||||
min.x = std::min(temp.x, min.x);
|
||||
min.y = std::min(temp.y, min.y);
|
||||
min.z = std::min(temp.z, min.z);
|
||||
|
||||
max.x = std::max(temp.x, max.x);
|
||||
max.y = std::max(temp.y, max.y);
|
||||
max.z = std::max(temp.z, max.z);
|
||||
}
|
||||
}
|
||||
return util::SegmentAABBIntersect(min, max, segment.start, segment.end);
|
||||
}
|
||||
} // namespace tango_gl
|
||||
83
app/android/jni/tango-gl/camera.cpp
Normal file
83
app/android/jni/tango-gl/camera.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "tango-gl/camera.h"
|
||||
#include "tango-gl/util.h"
|
||||
|
||||
namespace tango_gl {
|
||||
|
||||
Camera::Camera() {
|
||||
field_of_view_ = 45.0f * DEGREE_2_RADIANS;
|
||||
aspect_ratio_ = 4.0f / 3.0f;
|
||||
width_ = 800.0f;
|
||||
height_ = 600.0f;
|
||||
near_clip_plane_ = 0.5f;
|
||||
far_clip_plane_ = 50.0f;
|
||||
ortho_ = false;
|
||||
orthoScale_ = 2.0f;
|
||||
orthoCropFactor_ = -1.0f;
|
||||
}
|
||||
|
||||
glm::mat4 Camera::GetViewMatrix() {
|
||||
return glm::inverse(GetTransformationMatrix());
|
||||
}
|
||||
|
||||
glm::mat4 Camera::GetProjectionMatrix() {
|
||||
if(ortho_)
|
||||
{
|
||||
return glm::ortho(-orthoScale_*aspect_ratio_, orthoScale_*aspect_ratio_, -orthoScale_, orthoScale_, orthoScale_ + orthoCropFactor_, far_clip_plane_);
|
||||
}
|
||||
return glm::perspective(field_of_view_, aspect_ratio_, near_clip_plane_, far_clip_plane_);
|
||||
}
|
||||
|
||||
void Camera::SetWindowSize(float width, float height) {
|
||||
width_ = width;
|
||||
height_ = height;
|
||||
aspect_ratio_ = width/height;
|
||||
}
|
||||
|
||||
void Camera::SetFieldOfView(float fov) {
|
||||
field_of_view_ = fov * DEGREE_2_RADIANS;
|
||||
}
|
||||
|
||||
void Camera::SetNearFarClipPlanes(const float near, const float far)
|
||||
{
|
||||
near_clip_plane_ = near;
|
||||
far_clip_plane_ = far;
|
||||
}
|
||||
|
||||
Camera::~Camera() {
|
||||
}
|
||||
|
||||
glm::mat4 Camera::ProjectionMatrixForCameraIntrinsics(float width, float height,
|
||||
float fx, float fy,
|
||||
float cx, float cy,
|
||||
float near, float far) {
|
||||
const float xscale = near / fx;
|
||||
const float yscale = near / fy;
|
||||
|
||||
const float xoffset = (cx - (width / 2.0)) * xscale;
|
||||
// Color camera's coordinates has y pointing downwards so we negate this term.
|
||||
const float yoffset = -(cy - (height / 2.0)) * yscale;
|
||||
|
||||
return glm::frustum(xscale * -width / 2.0f - xoffset,
|
||||
xscale * width / 2.0f - xoffset,
|
||||
yscale * -height / 2.0f - yoffset,
|
||||
yscale * height / 2.0f - yoffset,
|
||||
near, far);
|
||||
}
|
||||
|
||||
} // namespace tango_gl
|
||||
36
app/android/jni/tango-gl/circle.cpp
Normal file
36
app/android/jni/tango-gl/circle.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "tango-gl/circle.h"
|
||||
|
||||
namespace tango_gl {
|
||||
Circle::Circle(float radius, int resolution) : Mesh(GL_TRIANGLE_FAN){
|
||||
SetShader();
|
||||
std::vector<GLfloat> vertices;
|
||||
vertices.reserve(3 * (resolution + 2));
|
||||
vertices.push_back(0);
|
||||
vertices.push_back(0);
|
||||
vertices.push_back(0);
|
||||
float delta_theta = M_PI * 2.0f / static_cast<float>(resolution);
|
||||
for (int i = resolution; i >= 0; i--) {
|
||||
float theta = delta_theta * static_cast<float>(i);
|
||||
vertices.push_back(cos(theta) * radius);
|
||||
vertices.push_back(0);
|
||||
vertices.push_back(sin(theta) * radius);
|
||||
}
|
||||
SetVertices(vertices);
|
||||
}
|
||||
} // namespace tango_gl
|
||||
52
app/android/jni/tango-gl/conversions.cpp
Normal file
52
app/android/jni/tango-gl/conversions.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "tango-gl/conversions.h"
|
||||
|
||||
namespace tango_gl {
|
||||
namespace conversions {
|
||||
|
||||
glm::mat4 opengl_world_T_tango_world() {
|
||||
// Note glm is column-wise.
|
||||
return glm::mat4(1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, -1.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
glm::mat4 color_camera_T_opengl_camera() {
|
||||
// Note glm is column-wise.
|
||||
return glm::mat4(1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, -1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, -1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
glm::mat4 depth_camera_T_opengl_camera() {
|
||||
// Note glm is column-wise.
|
||||
return glm::mat4(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
||||
-1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
glm::quat QuatTangoToGl(const glm::quat& tango_q_frame) {
|
||||
const float kSqrt2Over2 = std::sqrt(2.0) / 2.0f;
|
||||
// Tango frame is a -90 degree rotation about +X from the GL frame.
|
||||
glm::quat gl_q_tango = glm::quat(kSqrt2Over2, -kSqrt2Over2, 0.0f, 0.0f);
|
||||
return gl_q_tango * tango_q_frame;
|
||||
}
|
||||
|
||||
} // namespace gl_tango_conversions
|
||||
} // namespace tango_gl
|
||||
54
app/android/jni/tango-gl/cube.cpp
Normal file
54
app/android/jni/tango-gl/cube.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "tango-gl/cube.h"
|
||||
|
||||
namespace tango_gl {
|
||||
|
||||
static const GLfloat const_vertices[] = {
|
||||
-1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f,
|
||||
1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
|
||||
-1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f,
|
||||
1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f,
|
||||
-1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f,
|
||||
1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f,
|
||||
-1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
|
||||
1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f,
|
||||
1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f};
|
||||
|
||||
static const GLfloat const_normals[] = {
|
||||
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
|
||||
-1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, -1.0f,
|
||||
0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
|
||||
-1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f,
|
||||
0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f};
|
||||
|
||||
Cube::Cube() {
|
||||
SetShader(true);
|
||||
std::vector<GLfloat> vertices(
|
||||
const_vertices,
|
||||
const_vertices + sizeof(const_vertices) / sizeof(GLfloat));
|
||||
std::vector<GLfloat> normals(
|
||||
const_normals, const_normals + sizeof(const_normals) / sizeof(GLfloat));
|
||||
SetVertices(vertices, normals);
|
||||
}
|
||||
} // namespace tango_gl
|
||||
66
app/android/jni/tango-gl/drawable_object.cpp
Normal file
66
app/android/jni/tango-gl/drawable_object.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "tango-gl/drawable_object.h"
|
||||
#include "tango-gl/shaders.h"
|
||||
|
||||
namespace tango_gl {
|
||||
|
||||
void DrawableObject::SetShader() {
|
||||
shader_program_ =
|
||||
util::CreateProgram(shaders::GetBasicVertexShader().c_str(),
|
||||
shaders::GetBasicFragmentShader().c_str());
|
||||
if (!shader_program_) {
|
||||
LOGE("Could not create program.");
|
||||
}
|
||||
uniform_mvp_mat_ = glGetUniformLocation(shader_program_, "mvp");
|
||||
attrib_vertices_ = glGetAttribLocation(shader_program_, "vertex");
|
||||
uniform_color_ = glGetUniformLocation(shader_program_, "color");
|
||||
}
|
||||
|
||||
void DrawableObject::DeleteGlResources() {
|
||||
if (shader_program_) {
|
||||
glDeleteShader(shader_program_);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawableObject::SetColor(float red, float green, float blue) {
|
||||
red_ = red;
|
||||
green_ = green;
|
||||
blue_ = blue;
|
||||
}
|
||||
void DrawableObject::SetColor(const Color& color) {
|
||||
SetColor(color.r, color.g, color.b);
|
||||
}
|
||||
|
||||
void DrawableObject::SetAlpha(const float alpha) { alpha_ = alpha; }
|
||||
|
||||
void DrawableObject::SetVertices(const std::vector<GLfloat>& vertices) {
|
||||
vertices_ = vertices;
|
||||
}
|
||||
|
||||
void DrawableObject::SetVertices(const std::vector<GLfloat>& vertices,
|
||||
const std::vector<GLushort>& indices) {
|
||||
vertices_ = vertices;
|
||||
indices_ = indices;
|
||||
}
|
||||
|
||||
void DrawableObject::SetVertices(const std::vector<GLfloat>& vertices,
|
||||
const std::vector<GLfloat>& normals) {
|
||||
vertices_ = vertices;
|
||||
normals_ = normals;
|
||||
}
|
||||
} // namespace tango_gl
|
||||
38
app/android/jni/tango-gl/frustum.cpp
Normal file
38
app/android/jni/tango-gl/frustum.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "tango-gl/frustum.h"
|
||||
|
||||
namespace tango_gl {
|
||||
|
||||
static const float float_vertices[] = {
|
||||
0.0f, 0.0f, 0.0f, -1.0f, 1.0f, -1.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f, 1.0f, -1.0f,
|
||||
0.0f, 0.0f, 0.0f, -1.0f, -1.0f, -1.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f, -1.0f, -1.0f,
|
||||
-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f,
|
||||
1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f,
|
||||
1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f,
|
||||
-1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f};
|
||||
|
||||
Frustum::Frustum() : Line(3.0f, GL_LINES) {
|
||||
SetShader();
|
||||
size_t size = sizeof(float_vertices) / sizeof(float);
|
||||
for (size_t i = 0; i < size; i += 3) {
|
||||
vec_vertices_.push_back(glm::vec3(float_vertices[i], float_vertices[i + 1],
|
||||
float_vertices[i + 2]));
|
||||
}
|
||||
}
|
||||
} // namespace tango_gl
|
||||
254
app/android/jni/tango-gl/gesture_camera.cpp
Normal file
254
app/android/jni/tango-gl/gesture_camera.cpp
Normal file
@@ -0,0 +1,254 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "tango-gl/gesture_camera.h"
|
||||
#include "tango-gl/util.h"
|
||||
#include "glm/gtx/quaternion.hpp"
|
||||
|
||||
namespace {
|
||||
// Render camera observation distance in third person camera mode.
|
||||
const float kThirdPersonCameraDist = 7.0f;
|
||||
|
||||
// Render camera observation distance in third person camera mode.
|
||||
const float kThirdPersonFollowCameraDist = 2.0f;
|
||||
|
||||
// Render camera observation distance in top down camera mode.
|
||||
const float kTopDownCameraDist = 5.0f;
|
||||
|
||||
// Zoom in speed.
|
||||
const float kZoomSpeed = 10.0f;
|
||||
|
||||
// Move speed
|
||||
const float kMoveSpeed = 10.0f;
|
||||
|
||||
// Rotation speed
|
||||
const float kRotationSpeed = 2.0f;
|
||||
|
||||
// Min/max clamp value of camera observation distance.
|
||||
const float kCamViewMinDist = .1f;
|
||||
const float kCamViewMaxDist = 100.f;
|
||||
|
||||
// FOV set up values.
|
||||
// Third and top down camera's FOV is 65 degrees.
|
||||
// First person camera's FOV is 85 degrees.
|
||||
const float kHighestFov = 120.0f;
|
||||
const float kHighFov = 85.0f;
|
||||
const float kLowFov = 65.0f;
|
||||
const float kLowestFov = 40.0f;
|
||||
}
|
||||
|
||||
namespace tango_gl {
|
||||
|
||||
GestureCamera::GestureCamera() :
|
||||
cam_cur_target_rot_(1,0,0,0),
|
||||
start_touch_dist_(0.0f),
|
||||
cur_touch_dist_(0.0f)
|
||||
{
|
||||
cam_parent_transform_ = new Transform();
|
||||
SetParent(cam_parent_transform_);
|
||||
}
|
||||
|
||||
GestureCamera::~GestureCamera() { delete cam_parent_transform_; }
|
||||
|
||||
void GestureCamera::OnTouchEvent(int touch_count, TouchEvent event, float x0,
|
||||
float y0, float x1, float y1) {
|
||||
|
||||
if (camera_type_!=kFirstPerson && touch_count == 1) {
|
||||
switch (event) {
|
||||
case kTouch0Down: {
|
||||
cam_start_angle_ = cam_cur_angle_;
|
||||
|
||||
touch0_start_position_.x = x0;
|
||||
touch0_start_position_.y = y0;
|
||||
break;
|
||||
}
|
||||
case kTouchMove: {
|
||||
glm::vec2 offset;
|
||||
|
||||
float rotation_x = (touch0_start_position_.y - y0) * kRotationSpeed;
|
||||
float rotation_y = (touch0_start_position_.x - x0) * kRotationSpeed;
|
||||
|
||||
if(camera_type_!=kTopOrtho)
|
||||
cam_cur_angle_.x = cam_start_angle_.x + rotation_x;
|
||||
cam_cur_angle_.y = cam_start_angle_.y + rotation_y;
|
||||
|
||||
StartCameraToCurrentTransform();
|
||||
|
||||
break;
|
||||
}
|
||||
default: { break; }
|
||||
}
|
||||
}
|
||||
if (touch_count == 2) {
|
||||
switch (event) {
|
||||
case kTouch1Down: {
|
||||
float abs_x = x0 - x1;
|
||||
float abs_y = y0 - y1;
|
||||
start_touch_dist_ = std::sqrt(abs_x * abs_x + abs_y * abs_y);
|
||||
cam_start_dist_ = GetPosition().z;
|
||||
cam_start_fov_ = this->getFOV();
|
||||
|
||||
// center touch
|
||||
touch0_start_position_.x = (x0+x1)/2.0f;
|
||||
touch0_start_position_.y = (y0+y1)/2.0f;
|
||||
break;
|
||||
}
|
||||
case kTouchMove: {
|
||||
float abs_x = x0 - x1;
|
||||
float abs_y = y0 - y1;
|
||||
float dist = start_touch_dist_ - std::sqrt(abs_x * abs_x + abs_y * abs_y);
|
||||
|
||||
if(camera_type_ == kFirstPerson)
|
||||
{
|
||||
this->SetFieldOfView(tango_gl::util::Clamp(cam_start_fov_ + dist * kZoomSpeed*10.0f, kLowestFov, kHighestFov));
|
||||
}
|
||||
else
|
||||
{
|
||||
cam_cur_dist_ = tango_gl::util::Clamp(cam_start_dist_ + dist * kZoomSpeed,
|
||||
kCamViewMinDist, kCamViewMaxDist);
|
||||
|
||||
this->SetOrthoMode(camera_type_ == kTopOrtho);
|
||||
if(camera_type_ == kTopOrtho)
|
||||
{
|
||||
this->SetOrthoScale(cam_cur_dist_);
|
||||
}
|
||||
|
||||
glm::vec2 touch_center_position((x0+x1)/2.0f, (y0+y1)/2.0f);
|
||||
glm::vec2 offset;
|
||||
offset.x = (touch_center_position.x - touch0_start_position_.x) * kMoveSpeed;
|
||||
offset.y = (touch_center_position.y - touch0_start_position_.y) * kMoveSpeed;
|
||||
touch0_start_position_ = touch_center_position;
|
||||
|
||||
StartCameraToCurrentTransform();
|
||||
|
||||
anchor_offset_ += glm::rotate(cam_parent_transform_->GetRotation(), glm::vec3(-offset.x, offset.y, 0));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: { break; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Segment GestureCamera::GetSegmentFromTouch(float normalized_x,
|
||||
float normalized_y,
|
||||
float touch_range) {
|
||||
float screen_height = touch_range * (2.0f * glm::tan(field_of_view_ * 0.5f));
|
||||
float screen_width = screen_height * aspect_ratio_;
|
||||
// normalized_x and normalized_x are from OnTouchEvent, top-left corner of the
|
||||
// screen
|
||||
// is [0, 0], transform it to opengl frame.
|
||||
normalized_x = normalized_x - 0.5f;
|
||||
normalized_y = 0.5f - normalized_y;
|
||||
glm::vec3 start =
|
||||
util::ApplyTransform(GetTransformationMatrix(), glm::vec3(0, 0, 0));
|
||||
glm::vec3 end = util::ApplyTransform(GetTransformationMatrix(),
|
||||
glm::vec3(normalized_x * screen_width, normalized_y * screen_height,
|
||||
-touch_range));
|
||||
Segment segment(start, end);
|
||||
return segment;
|
||||
}
|
||||
|
||||
void GestureCamera::SetAnchorPosition(const glm::vec3& pos, const glm::quat & rotation) {
|
||||
// Anchor position
|
||||
cam_parent_transform_->SetPosition(pos+anchor_offset_);
|
||||
|
||||
// Anchor rotation
|
||||
if(camera_type_ == kThirdPersonFollow)
|
||||
{
|
||||
cam_cur_target_rot_ = rotation;
|
||||
cam_cur_target_rot_.x = 0;
|
||||
cam_cur_target_rot_.z = 0;
|
||||
cam_cur_target_rot_ = glm::normalize(cam_cur_target_rot_);
|
||||
StartCameraToCurrentTransform();
|
||||
}
|
||||
}
|
||||
|
||||
void GestureCamera::SetCameraType(CameraType camera_index) {
|
||||
camera_type_ = camera_index;
|
||||
switch (camera_index) {
|
||||
case kFirstPerson:
|
||||
SetOrthoMode(false);
|
||||
SetFieldOfView(kLowestFov);
|
||||
SetNearFarClipPlanes(0.25, 25);
|
||||
SetPosition(glm::vec3(0.0f, 0.0f, 0.0f));
|
||||
SetRotation(glm::quat(1.0f, 0.0f, 0.0f, 0.0f));
|
||||
cam_cur_dist_ = 0.0f;
|
||||
anchor_offset_ = glm::vec3(0.0f,0.0f,0.0f);
|
||||
cam_cur_angle_.x = 0.0f;
|
||||
cam_cur_angle_.y = 0.0f;
|
||||
cam_cur_target_rot_ = glm::quat(1,0,0,0);
|
||||
cam_parent_transform_->SetPosition(glm::vec3(0.0f, 0.0f, 0.0f));
|
||||
StartCameraToCurrentTransform();
|
||||
break;
|
||||
case kThirdPerson:
|
||||
case kThirdPersonFollow:
|
||||
SetOrthoMode(false);
|
||||
SetFieldOfView(kLowFov);
|
||||
SetNearFarClipPlanes(1, 50);
|
||||
SetPosition(glm::vec3(0.0f, 0.0f, 0.0f));
|
||||
SetRotation(glm::quat(1.0f, 0.0f, 0.0f, 0.0f));
|
||||
cam_cur_dist_ = camera_index==kThirdPersonFollow?kThirdPersonFollowCameraDist:kThirdPersonCameraDist;
|
||||
anchor_offset_ = glm::vec3(0.0f,0.0f,0.0f);
|
||||
cam_cur_angle_.x = -M_PI / 12.0f;
|
||||
cam_cur_angle_.y = kThirdPersonFollow?0:M_PI / 2.0f;
|
||||
cam_cur_target_rot_ = glm::quat(1,0,0,0);
|
||||
StartCameraToCurrentTransform();
|
||||
break;
|
||||
case kTopDown:
|
||||
SetPosition(glm::vec3(0.0f, 0.0f, 0.0f));
|
||||
SetRotation(glm::quat(1.0f, 0.0f, 0.0f, 0.0f));
|
||||
SetOrthoMode(false);
|
||||
SetFieldOfView(kLowFov);
|
||||
SetNearFarClipPlanes(1, 50);
|
||||
cam_cur_dist_ = kTopDownCameraDist;
|
||||
anchor_offset_ = glm::vec3(0.0f,0.0f,0.0f);
|
||||
cam_cur_angle_.x = -M_PI / 2.0f;
|
||||
cam_cur_angle_.y = 0.0f;
|
||||
cam_cur_target_rot_ = glm::quat(1,0,0,0);
|
||||
StartCameraToCurrentTransform();
|
||||
break;
|
||||
case kTopOrtho:
|
||||
SetPosition(glm::vec3(0.0f, 0.0f, 0.0f));
|
||||
SetRotation(glm::quat(1.0f, 0.0f, 0.0f, 0.0f));
|
||||
SetOrthoMode(true);
|
||||
SetOrthoScale(kTopDownCameraDist);
|
||||
SetOrthoCropFactor(-1.0f);
|
||||
SetFieldOfView(kLowFov);
|
||||
SetNearFarClipPlanes(1, 50);
|
||||
cam_cur_dist_ = kTopDownCameraDist;
|
||||
anchor_offset_ = glm::vec3(0.0f,0.0f,0.0f);
|
||||
cam_cur_angle_.x = -M_PI / 2.0f;
|
||||
cam_cur_angle_.y = 0.0f;
|
||||
cam_cur_target_rot_ = glm::quat(1,0,0,0);
|
||||
StartCameraToCurrentTransform();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GestureCamera::StartCameraToCurrentTransform()
|
||||
{
|
||||
//Anchor rotation
|
||||
glm::quat parent_cam_rot = glm::rotate(cam_cur_target_rot_, cam_cur_angle_.y, glm::vec3(0, 1, 0));
|
||||
parent_cam_rot = glm::rotate(parent_cam_rot, cam_cur_angle_.x, glm::vec3(1, 0, 0));
|
||||
cam_parent_transform_->SetRotation(parent_cam_rot);
|
||||
|
||||
//Camera position
|
||||
SetPosition(glm::vec3(0, 0, cam_cur_dist_));
|
||||
}
|
||||
} // namespace tango_gl
|
||||
59
app/android/jni/tango-gl/goal_marker.cpp
Normal file
59
app/android/jni/tango-gl/goal_marker.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
* Distributed under the Project Tango Preview Development Kit (PDK) Agreement.
|
||||
* CONFIDENTIAL. AUTHORIZED USE ONLY. DO NOT REDISTRIBUTE.
|
||||
*/
|
||||
|
||||
#include "tango-gl/goal_marker.h"
|
||||
|
||||
namespace tango_gl {
|
||||
|
||||
static const GLfloat const_vertices[] = {
|
||||
-4.5298f, -0.2676f, 0.0, -4.3209f, -1.3857f, 0.0, -3.7242f,
|
||||
-11.1445f, 0.0, -5.6799f, -8.9811f, 0.0, -4.4540f, 0.8673f,
|
||||
0.0, -7.8376f, -6.4508f, 0.0, -9.5223f, -3.0538f, 0.0,
|
||||
-9.9826f, -0.5898f, 0.0, -9.8157f, 1.9113f, 0.0, -9.0320f,
|
||||
4.2923f, 0.0, -7.6808f, 6.4036f, 0.0, -5.8469f, 8.1125f,
|
||||
0.0, -3.6457f, 9.3117f, 0.0, -4.0984f, 1.9477f, 0.0,
|
||||
-1.2155f, 9.9259f, 0.0, -3.4853f, 2.9057f, 0.0, 1.2912f,
|
||||
9.9163f, 0.0, -2.6532f, 3.6812f, 0.0, 3.7167f, 9.2837f,
|
||||
0.0, -1.6543f, 4.2254f, 0.0, 5.9087f, 8.0677f, 0.0,
|
||||
-0.5515f, 4.5040f, 0.0, 7.7294f, 6.3448f, 0.0, 0.5859f,
|
||||
4.4997f, 0.0, 9.0645f, 4.2232f, 0.0, 1.6865f, 4.2126f,
|
||||
0.0, 9.8300f, 1.8363f, 0.0, 2.6812f, 3.6609f, 0.0,
|
||||
9.9778f, -0.6660f, 0.0, 3.5074f, 2.8791f, 0.0, 9.4987f,
|
||||
-3.1264f, 0.0, 4.1132f, 1.9164f, 0.0, 7.7964f, -6.5204f,
|
||||
0.0, 4.4605f, 0.8333f, 0.0, 5.6245f, -9.0444f, 0.0,
|
||||
4.5276f, -0.3022f, 0.0, 3.6572f, -11.1925f, 0.0, 4.3102f,
|
||||
-1.4187f, 0.0, 1.5165f, -13.5960f, 0.0, 3.8220f, -2.4460f,
|
||||
0.0, -0.0382f, -16.4245f, 0.0, 3.0936f, -3.3197f, 0.0,
|
||||
-1.5902f, -13.5657f, 0.0, 2.1709f, -3.9847f, 0.0, -3.8405f,
|
||||
-2.4168f, 0.0, -3.1189f, -3.2959f, 0.0, -2.2012f, -3.9680f,
|
||||
0.0, -1.1452f, -4.3908f, 0.0, -0.0173f, -4.5377f, 0.0,
|
||||
1.1117f, -4.3994f, 0.0};
|
||||
|
||||
static const GLushort const_indices[] = {
|
||||
1, 2, 3, 1, 3, 4, 5, 1, 4, 4, 6, 7, 5, 4, 7, 7, 8, 9, 9,
|
||||
10, 11, 7, 9, 11, 5, 7, 11, 5, 11, 12, 5, 12, 13, 14, 5, 13, 14, 13,
|
||||
15, 16, 14, 15, 16, 15, 17, 18, 16, 17, 18, 17, 19, 20, 18, 19, 20, 19, 21,
|
||||
22, 20, 21, 22, 21, 23, 24, 22, 23, 24, 23, 25, 26, 24, 25, 26, 25, 27, 28,
|
||||
26, 27, 28, 27, 29, 30, 28, 29, 30, 29, 31, 32, 30, 31, 32, 31, 33, 34, 32,
|
||||
33, 34, 33, 35, 36, 34, 35, 36, 35, 37, 38, 36, 37, 38, 37, 39, 40, 38, 39,
|
||||
40, 39, 41, 42, 40, 41, 42, 41, 43, 44, 42, 43, 44, 43, 3, 3, 2, 45, 3,
|
||||
45, 46, 3, 46, 47, 3, 47, 48, 3, 48, 49, 3, 49, 50, 44, 3, 50};
|
||||
|
||||
GoalMarker::GoalMarker() {
|
||||
SetShader();
|
||||
std::vector<GLfloat> vertices(
|
||||
const_vertices,
|
||||
const_vertices + sizeof(const_vertices) / sizeof(GLfloat));
|
||||
std::vector<GLushort> indices(
|
||||
const_indices, const_indices + sizeof(const_indices) / sizeof(GLushort));
|
||||
// Change indices so they are zero-indexed.
|
||||
for (size_t i = 0; i < indices.size(); ++i) {
|
||||
indices[i] = indices[i] - 1;
|
||||
}
|
||||
SetVertices(vertices, indices);
|
||||
}
|
||||
} // namespace tango_gl
|
||||
47
app/android/jni/tango-gl/grid.cpp
Normal file
47
app/android/jni/tango-gl/grid.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "tango-gl/grid.h"
|
||||
|
||||
namespace tango_gl {
|
||||
|
||||
// Initialize Grid with x and y grid count,
|
||||
// qx, quantity in x
|
||||
// qy, quantity in y.
|
||||
Grid::Grid(float density, int qx, int qy) : Line(1.0f, GL_LINES) {
|
||||
SetShader();
|
||||
|
||||
// 3 float in 1 vertex, 2 vertices form a line.
|
||||
// Horizontal line and vertical line forms the grid.
|
||||
float width = density * qx / 2;
|
||||
float height = density * qy / 2;
|
||||
|
||||
// Horizontal line.
|
||||
for (int i = 0; i < (qy + 1); i++) {
|
||||
for (int j = 0; j < (qx + 1); j++) {
|
||||
vec_vertices_.push_back(glm::vec3(-width + j*density, 0.0f, -height + i * density));
|
||||
vec_vertices_.push_back(glm::vec3(-width+ + (j+1)*density, 0.0f, -height + i * density));
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < (qx + 1); i++) {
|
||||
for (int j = 0; j < (qy + 1); j++) {
|
||||
vec_vertices_.push_back(glm::vec3(-width + i * density, 0.0f, -height + j*density));
|
||||
vec_vertices_.push_back(glm::vec3(-width + i * density, 0.0f, -height + (j+1)*density));
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace tango_gl
|
||||
32
app/android/jni/tango-gl/include/tango-gl/axis.h
Normal file
32
app/android/jni/tango-gl/include/tango-gl/axis.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TANGO_GL_AXIS_H_
|
||||
#define TANGO_GL_AXIS_H_
|
||||
|
||||
#include "tango-gl/line.h"
|
||||
|
||||
namespace tango_gl {
|
||||
class Axis : public Line {
|
||||
public:
|
||||
Axis();
|
||||
void Render(const glm::mat4& projection_mat, const glm::mat4& view_mat) const;
|
||||
private:
|
||||
GLuint attrib_colors_;
|
||||
std::vector<glm::vec4> vec_colors_;
|
||||
};
|
||||
} // namespace tango_gl
|
||||
#endif // TANGO_GL_AXIS_H_
|
||||
55
app/android/jni/tango-gl/include/tango-gl/band.h
Normal file
55
app/android/jni/tango-gl/include/tango-gl/band.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TANGO_GL_BAND_H_
|
||||
#define TANGO_GL_BAND_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <vector>
|
||||
|
||||
#include "tango-gl/drawable_object.h"
|
||||
|
||||
namespace tango_gl {
|
||||
class Band : public DrawableObject {
|
||||
public:
|
||||
enum BandMode {
|
||||
kNormal = 0,
|
||||
kKeepLeft = 1,
|
||||
kKeepRight = 2
|
||||
};
|
||||
|
||||
Band(const unsigned int max_legnth);
|
||||
|
||||
void SetWidth(const float width);
|
||||
// Render a Band with arrow head, pass in the mode for rendering,
|
||||
// kKeepLeft is left turn, kKeepRight is right turn,
|
||||
// when making a turn, vertices only get updated in one side to avoid overlapping.
|
||||
void UpdateVertexArray(const glm::mat4 m, BandMode mode);
|
||||
void UpdateVertexArray(const glm::mat4 m);
|
||||
void SetVertexArray(const std::vector<glm::vec3>& v, const glm::vec3& up);
|
||||
void ClearVertexArray();
|
||||
void Render(const glm::mat4& projection_mat, const glm::mat4& view_mat) const;
|
||||
|
||||
private:
|
||||
float band_width_;
|
||||
unsigned int max_length_;
|
||||
std::vector<glm::vec3> vertices_v_;
|
||||
// Current band head's left and right position in world frame.
|
||||
glm::vec3 pivot_left;
|
||||
glm::vec3 pivot_right;
|
||||
};
|
||||
} // namespace tango_gl
|
||||
#endif // TANGO_GL_BAND_H_
|
||||
42
app/android/jni/tango-gl/include/tango-gl/bounding_box.h
Normal file
42
app/android/jni/tango-gl/include/tango-gl/bounding_box.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TANGO_GL_BOUNDING_BOX_H_
|
||||
#define TANGO_GL_BOUNDING_BOX_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "tango-gl/segment.h"
|
||||
#include "tango-gl/util.h"
|
||||
|
||||
namespace tango_gl {
|
||||
class BoundingBox {
|
||||
public:
|
||||
BoundingBox()
|
||||
: bounding_min_(glm::vec3(0, 0, 0)), bounding_max_(glm::vec3(0, 0, 0)) {}
|
||||
BoundingBox(const std::vector<float>& vertices);
|
||||
BoundingBox(const glm::vec3& min, const glm::vec3& max)
|
||||
: bounding_min_(min), bounding_max_(max) {}
|
||||
bool IsIntersecting(const Segment& segment, const glm::quat& rotation,
|
||||
const glm::mat4& transformation);
|
||||
|
||||
private:
|
||||
// Axis-aligned bounding box minimum and maximum point.
|
||||
glm::vec3 bounding_min_;
|
||||
glm::vec3 bounding_max_;
|
||||
};
|
||||
} // namespace tango_gl
|
||||
#endif // TANGO_GL_BOUNDING_BOX_H_
|
||||
69
app/android/jni/tango-gl/include/tango-gl/camera.h
Normal file
69
app/android/jni/tango-gl/include/tango-gl/camera.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TANGO_GL_CAMERA_H_
|
||||
#define TANGO_GL_CAMERA_H_
|
||||
|
||||
#include "tango-gl/transform.h"
|
||||
|
||||
namespace tango_gl {
|
||||
class Camera : public Transform {
|
||||
public:
|
||||
Camera();
|
||||
Camera(const Camera& other) = delete;
|
||||
Camera& operator=(const Camera&) = delete;
|
||||
~Camera();
|
||||
|
||||
void SetWindowSize(const float width, const float height);
|
||||
void SetFieldOfView(const float fov);
|
||||
void SetOrthoMode(bool enabled) {ortho_ = enabled;}
|
||||
void SetOrthoScale(float scale) {orthoScale_ = scale;}
|
||||
void SetOrthoCropFactor(float value) {orthoCropFactor_ = value;}
|
||||
void SetNearFarClipPlanes(const float near, const float far);
|
||||
|
||||
glm::mat4 GetViewMatrix();
|
||||
glm::mat4 GetProjectionMatrix();
|
||||
float getNearClipPlane() const {return near_clip_plane_;}
|
||||
float getFarClipPlane() const {return far_clip_plane_;}
|
||||
|
||||
/**
|
||||
* Create an OpenGL perspective matrix from window size, camera intrinsics, and clip settings.
|
||||
*
|
||||
* @param width - The width of the camera image.
|
||||
* @param height - The height of the camera image.
|
||||
* @param fx - The x-axis focal length of the camera.
|
||||
* @param fy - The y-axis focal length of the camera.
|
||||
* @param cx - The x-coordinate principal point in pixels.
|
||||
* @param cy - The y-coordinate principal point in pixels.
|
||||
* @param near - The desired near z-clipping plane.
|
||||
* @param far - The desired far z-clipping plane.
|
||||
*/
|
||||
static glm::mat4 ProjectionMatrixForCameraIntrinsics(float width, float height,
|
||||
float fx, float fy,
|
||||
float cx, float cy,
|
||||
float near, float far);
|
||||
protected:
|
||||
float field_of_view_;
|
||||
float aspect_ratio_;
|
||||
float width_;
|
||||
float height_;
|
||||
float near_clip_plane_, far_clip_plane_;
|
||||
bool ortho_;
|
||||
float orthoScale_;
|
||||
float orthoCropFactor_;
|
||||
};
|
||||
} // namespace tango_gl
|
||||
#endif // TANGO_GL_CAMERA_H_
|
||||
28
app/android/jni/tango-gl/include/tango-gl/circle.h
Normal file
28
app/android/jni/tango-gl/include/tango-gl/circle.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TANGO_GL_CIRCLE_H_
|
||||
#define TANGO_GL_CIRCLE_H_
|
||||
|
||||
#include "tango-gl/mesh.h"
|
||||
|
||||
namespace tango_gl {
|
||||
class Circle : public Mesh {
|
||||
public:
|
||||
Circle(float radius, int resolution);
|
||||
};
|
||||
} // namespace tango_gl
|
||||
#endif // TANGO_GL_CIRCLE_H_
|
||||
33
app/android/jni/tango-gl/include/tango-gl/color.h
Normal file
33
app/android/jni/tango-gl/include/tango-gl/color.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TANGO_GL_COLOR_H_
|
||||
#define TANGO_GL_COLOR_H_
|
||||
|
||||
namespace tango_gl {
|
||||
class Color {
|
||||
public:
|
||||
Color() : r(0), g(0), b(0) {}
|
||||
Color(float red, float green, float blue) : r(red), g(green), b(blue) {}
|
||||
Color(const Color&) = default;
|
||||
Color& operator=(const Color&) = default;
|
||||
|
||||
float r;
|
||||
float g;
|
||||
float b;
|
||||
};
|
||||
} // namespace tango_gl
|
||||
#endif // TANGO_GL_COLOR_H_
|
||||
132
app/android/jni/tango-gl/include/tango-gl/conversions.h
Normal file
132
app/android/jni/tango-gl/include/tango-gl/conversions.h
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TANGO_GL_GL_TANGO_CONVERSIONS_H_
|
||||
#define TANGO_GL_GL_TANGO_CONVERSIONS_H_
|
||||
|
||||
#define GLM_FORCE_RADIANS
|
||||
|
||||
#include "glm/glm.hpp"
|
||||
#include "glm/gtc/matrix_transform.hpp"
|
||||
#include "glm/gtc/quaternion.hpp"
|
||||
|
||||
namespace tango_gl {
|
||||
namespace conversions {
|
||||
|
||||
/**
|
||||
* @brief Creates a glm::vec3 from double[3] = {x, y, z}. This is designed to
|
||||
* work with the TangoPoseData.translation field.
|
||||
*/
|
||||
inline glm::vec3 Vec3FromArray(const double* array) {
|
||||
return glm::vec3(array[0], array[1], array[2]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates a glm::quat from double[4] = {x, y, z, w}. This is designed to
|
||||
* work with the TangoPoseData.orientation field.
|
||||
*/
|
||||
inline glm::quat QuatFromArray(const double* array) {
|
||||
// Note GLM expects arguments in order {w, x, y, z}.
|
||||
return glm::quat(array[3], array[0], array[1], array[2]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates a glm::mat4 rigid-frame transformation matrix from two arrays.
|
||||
* This is designed for the TangoPoseData translation and orientation fields.
|
||||
* @param A_p_B Position [x, y, z] of B_origin from A_origin, expressed in A.
|
||||
* @param A_q_B The quaternion representation [x, y, z, w] of the rotation
|
||||
* matrix A_R_B.
|
||||
* @return The transformation matrix A_T_B.
|
||||
*/
|
||||
inline glm::mat4 TransformFromArrays(const double* A_p_B, const double* A_q_B) {
|
||||
glm::vec3 glm_A_p_B = Vec3FromArray(A_p_B);
|
||||
glm::quat glm_A_q_B = QuatFromArray(A_q_B);
|
||||
return glm::translate(glm::mat4(1.0f), glm_A_p_B) * glm::mat4_cast(glm_A_q_B);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates a glm::mat4 rigid-frame transformation matrix from glm::vec3 and glm::quat.
|
||||
* This is designed for the TangoPoseData translation and orientation fields.
|
||||
* @param A_p_B A position vector of B_origin from A_origin, expressed in A.
|
||||
* @param A_q_B A quaternion representation of the rotation.
|
||||
* matrix A_R_B.
|
||||
* @return The transformation matrix A_T_B.
|
||||
*/
|
||||
inline glm::mat4 TransformFromVecAndQuat(const glm::vec3& A_p_B, const glm::quat& A_q_B) {
|
||||
return glm::translate(glm::mat4(1.0f), A_p_B) * glm::mat4_cast(A_q_B);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert (re-express, or rotate) a vector from the Tango ADF (or start-
|
||||
* of-service) frame convention [right, forward, up] to the typical OpenGl world
|
||||
* frame convention [right, up, backward]. Note this assumes the two frames are
|
||||
* coincident, and it doesn't know about any additional offsets between a
|
||||
* particular OpenGl scene and the Tango service frames.
|
||||
* @param tango_vec A vector expressed in the Tango ADF frame convention.
|
||||
* @return The same vector expressed using the Opengl frame convention.
|
||||
*/
|
||||
inline glm::vec3 Vec3TangoToGl(const glm::vec3& tango_vec) {
|
||||
return glm::vec3(tango_vec.x, tango_vec.z, -tango_vec.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert (re-express, or rotate) a vector from the typical OpenGl world
|
||||
* frame convention [right, up, backward] to the Tango ADF (or start-of-service)
|
||||
* frame convention [right, forward, up]. Note this assumes the two frames are
|
||||
* coincident, and it doesn't know about any additional offsets between a
|
||||
* particular OpenGl scene and the Tango service frames.
|
||||
* @param gl_vec A vector expressed in the Opengl world frame convention.
|
||||
* @return The same vector expressed using the Tango ADF frame convention.
|
||||
*/
|
||||
inline glm::vec3 Vec3GlToTango(const glm::vec3& gl_vec) {
|
||||
return glm::vec3(gl_vec.x, -gl_vec.z, gl_vec.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Given a quaternion representing the rotation matrix tango_R_any,
|
||||
* returns the quaternion representing gl_R_any, where "any" is an arbitrary
|
||||
* frame. Note the gl base frame is rotated by 90-degrees about +X from the
|
||||
* Tango ADF/start-of-service frame, so this is equivalent to applying such a
|
||||
* rotation to the quaternion.
|
||||
* @param tango_q_any A quaternion representing rotation matrix tango_R_any.
|
||||
* @return The quaternion representing gl_R_any.
|
||||
*/
|
||||
glm::quat QuatTangoToGl(const glm::quat& tango_q_any);
|
||||
|
||||
/**
|
||||
* Get the fixed transformation matrix relating the opengl frame convention
|
||||
* (with Y-up, X-right) and the tango frame convention for the start-of-service
|
||||
* and ADF frames (with Z-up, X-right), termed "world" here.
|
||||
*/
|
||||
glm::mat4 opengl_world_T_tango_world();
|
||||
|
||||
/**
|
||||
* Get the fixed transformation matrix relating the frame convention of the
|
||||
* device's color camera frame (with Z-forward, X-right) and the opengl camera
|
||||
* frame (with Z-backward, X-right).
|
||||
*/
|
||||
glm::mat4 color_camera_T_opengl_camera();
|
||||
|
||||
/**
|
||||
* Get the fixed transformation matrix relating the frame convention of the
|
||||
* device's depth camera frame (with Z-forward, X-right) and the opengl camera
|
||||
* frame (with Z-backward, X-right).
|
||||
*/
|
||||
glm::mat4 depth_camera_T_opengl_camera();
|
||||
|
||||
} // namespace conversions
|
||||
} // namespace tango_gl
|
||||
#endif // TANGO_GL_GL_TANGO_CONVERSIONS_H_
|
||||
28
app/android/jni/tango-gl/include/tango-gl/cube.h
Normal file
28
app/android/jni/tango-gl/include/tango-gl/cube.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TANGO_GL_CUBE_H_
|
||||
#define TANGO_GL_CUBE_H_
|
||||
|
||||
#include "tango-gl/mesh.h"
|
||||
|
||||
namespace tango_gl {
|
||||
class Cube : public Mesh {
|
||||
public:
|
||||
Cube();
|
||||
};
|
||||
} // namespace tango_gl
|
||||
#endif // TANGO_GL_CUBE_H_
|
||||
63
app/android/jni/tango-gl/include/tango-gl/drawable_object.h
Normal file
63
app/android/jni/tango-gl/include/tango-gl/drawable_object.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TANGO_GL_DRAWABLE_OBJECT_H_
|
||||
#define TANGO_GL_DRAWABLE_OBJECT_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "tango-gl/color.h"
|
||||
#include "tango-gl/transform.h"
|
||||
#include "tango-gl/util.h"
|
||||
|
||||
namespace tango_gl {
|
||||
class DrawableObject : public Transform {
|
||||
public:
|
||||
DrawableObject() : red_(0), green_(0), blue_(0), alpha_(1.0f) {};
|
||||
DrawableObject(const DrawableObject& other) = delete;
|
||||
const DrawableObject& operator=(const DrawableObject&) = delete;
|
||||
|
||||
void DeleteGlResources();
|
||||
void SetShader();
|
||||
void SetColor(const Color& color);
|
||||
void SetColor(const float red, const float green, const float blue);
|
||||
void SetAlpha(const float alpha);
|
||||
void SetVertices(const std::vector<GLfloat>& vertices);
|
||||
void SetVertices(const std::vector<GLfloat>& vertices,
|
||||
const std::vector<GLushort>& indices);
|
||||
void SetVertices(const std::vector<GLfloat>& vertices,
|
||||
const std::vector<GLfloat>& normals);
|
||||
virtual void Render(const glm::mat4& projection_mat,
|
||||
const glm::mat4& view_mat) const = 0;
|
||||
|
||||
protected:
|
||||
float red_;
|
||||
float green_;
|
||||
float blue_;
|
||||
float alpha_;
|
||||
std::vector<GLushort> indices_;
|
||||
std::vector<GLfloat> vertices_;
|
||||
std::vector<GLfloat> normals_;
|
||||
|
||||
GLenum render_mode_;
|
||||
GLuint shader_program_;
|
||||
GLuint uniform_color_;
|
||||
GLuint uniform_mvp_mat_;
|
||||
GLuint attrib_vertices_;
|
||||
GLuint attrib_normals_;
|
||||
};
|
||||
} // namespace tango_gl
|
||||
#endif // TANGO_GL_DRAWABLE_OBJECT_H_
|
||||
28
app/android/jni/tango-gl/include/tango-gl/frustum.h
Normal file
28
app/android/jni/tango-gl/include/tango-gl/frustum.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TANGO_GL_FRUSTUM_H_
|
||||
#define TANGO_GL_FRUSTUM_H_
|
||||
|
||||
#include "tango-gl/line.h"
|
||||
|
||||
namespace tango_gl {
|
||||
class Frustum : public Line {
|
||||
public:
|
||||
Frustum();
|
||||
};
|
||||
} // namespace tango_gl
|
||||
#endif // TANGO_GL_FRUSTUM_H_
|
||||
94
app/android/jni/tango-gl/include/tango-gl/gesture_camera.h
Normal file
94
app/android/jni/tango-gl/include/tango-gl/gesture_camera.h
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TANGO_GL_GESTURE_CAMERA_H_
|
||||
#define TANGO_GL_GESTURE_CAMERA_H_
|
||||
|
||||
#include "tango-gl/camera.h"
|
||||
#include "tango-gl/segment.h"
|
||||
#include "tango-gl/transform.h"
|
||||
#include "tango-gl/util.h"
|
||||
|
||||
namespace tango_gl {
|
||||
class GestureCamera : public Camera {
|
||||
public:
|
||||
enum CameraType {
|
||||
kFirstPerson = 0,
|
||||
kThirdPersonFollow = 1,
|
||||
kTopDown = 2,
|
||||
kTopOrtho = 3,
|
||||
kThirdPerson = 4
|
||||
};
|
||||
|
||||
enum TouchEvent {
|
||||
kTouch0Down = 0,
|
||||
kTouch0Up = 1,
|
||||
kTouchMove = 2,
|
||||
kTouch1Down = 5,
|
||||
kTouch1Up = 6,
|
||||
kTouchNone = -1
|
||||
};
|
||||
|
||||
GestureCamera();
|
||||
~GestureCamera();
|
||||
|
||||
void OnTouchEvent(int touch_count, TouchEvent event, float x0, float y0,
|
||||
float x1, float y1);
|
||||
|
||||
// Get the ray in opengl world frame given the 2d touch position on screen,
|
||||
// normalized touch_x and normalized touch_y should be the same value get from
|
||||
// OnTouchEvent, x0 and y0, touch_range is the depth of the touch in
|
||||
// camera frame.
|
||||
Segment GetSegmentFromTouch(float normalized_x, float normalized_y,
|
||||
float touch_range);
|
||||
|
||||
void SetAnchorPosition(const glm::vec3& pos, const glm::quat & rotation);
|
||||
void SetAnchorOffset(const glm::vec3& pos) {anchor_offset_ = pos;}
|
||||
const glm::vec3& GetAnchorOffset() const {return anchor_offset_;}
|
||||
|
||||
void SetCameraDistance(float cameraDistance) {cam_cur_dist_ = cameraDistance;}
|
||||
float GetCameraDistance() const {return cam_cur_dist_;}
|
||||
|
||||
// Set camera type, set render camera's parent position and rotation.
|
||||
void SetCameraType(CameraType camera_index);
|
||||
|
||||
CameraType GetCameraType() const { return camera_type_; }
|
||||
float getFOV() const {return field_of_view_ * RADIAN_2_DEGREE;}
|
||||
|
||||
private:
|
||||
void StartCameraToCurrentTransform();
|
||||
|
||||
// Render camera's parent transformation.
|
||||
Transform* cam_parent_transform_;
|
||||
|
||||
CameraType camera_type_;
|
||||
|
||||
glm::vec2 cam_start_angle_;
|
||||
glm::vec2 cam_cur_angle_;
|
||||
glm::quat cam_cur_target_rot_;
|
||||
|
||||
float cam_start_dist_;
|
||||
float cam_start_fov_;
|
||||
float cam_cur_dist_;
|
||||
glm::vec3 anchor_offset_;
|
||||
|
||||
float start_touch_dist_;
|
||||
float cur_touch_dist_;
|
||||
|
||||
glm::vec2 touch0_start_position_;
|
||||
};
|
||||
} // namespace tango_gl
|
||||
#endif // TANGO_GL_GESTURE_CAMERA_H_
|
||||
18
app/android/jni/tango-gl/include/tango-gl/goal_marker.h
Normal file
18
app/android/jni/tango-gl/include/tango-gl/goal_marker.h
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
* Distributed under the Project Tango Preview Development Kit (PDK) Agreement.
|
||||
* CONFIDENTIAL. AUTHORIZED USE ONLY. DO NOT REDISTRIBUTE.
|
||||
*/
|
||||
|
||||
#ifndef TANGO_GL_GOAL_MARKER_H_
|
||||
#define TANGO_GL_GOAL_MARKER_H_
|
||||
|
||||
#include <tango-gl/mesh.h>
|
||||
|
||||
namespace tango_gl {
|
||||
class GoalMarker : public Mesh {
|
||||
public:
|
||||
GoalMarker();
|
||||
};
|
||||
} // namespace tango_gl
|
||||
#endif // TANGO_GL_GOAL_MARKER_H_
|
||||
28
app/android/jni/tango-gl/include/tango-gl/grid.h
Normal file
28
app/android/jni/tango-gl/include/tango-gl/grid.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TANGO_GL_GRID_H_
|
||||
#define TANGO_GL_GRID_H_
|
||||
|
||||
#include "tango-gl/line.h"
|
||||
|
||||
namespace tango_gl {
|
||||
class Grid : public Line {
|
||||
public:
|
||||
Grid(float density = 1.0f, int qx = 50, int qy = 50);
|
||||
};
|
||||
} // namespace tango_gl
|
||||
#endif // TANGO_GL_GRID_H_
|
||||
37
app/android/jni/tango-gl/include/tango-gl/line.h
Normal file
37
app/android/jni/tango-gl/include/tango-gl/line.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TANGO_GL_LINE_H_
|
||||
#define TANGO_GL_LINE_H_
|
||||
|
||||
#include "tango-gl/drawable_object.h"
|
||||
|
||||
namespace tango_gl {
|
||||
class Line : public DrawableObject {
|
||||
public:
|
||||
Line(float line_width, GLenum render_mode);
|
||||
void SetLineWidth(const float pixels);
|
||||
void Render(const glm::mat4& projection_mat, const glm::mat4& view_mat) const;
|
||||
void UpdateLineVertices(const std::vector<glm::vec3>& vec_vertices) {
|
||||
vec_vertices_ = vec_vertices;
|
||||
}
|
||||
|
||||
protected:
|
||||
float line_width_;
|
||||
std::vector<glm::vec3> vec_vertices_;
|
||||
};
|
||||
} // namespace tango_gl
|
||||
#endif // TANGO_GL_LINE_H_
|
||||
45
app/android/jni/tango-gl/include/tango-gl/mesh.h
Normal file
45
app/android/jni/tango-gl/include/tango-gl/mesh.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TANGO_GL_MESH_H_
|
||||
#define TANGO_GL_MESH_H_
|
||||
|
||||
#include "tango-gl/bounding_box.h"
|
||||
#include "tango-gl/drawable_object.h"
|
||||
#include "tango-gl/segment.h"
|
||||
|
||||
namespace tango_gl {
|
||||
class Mesh : public DrawableObject {
|
||||
public:
|
||||
Mesh();
|
||||
Mesh(GLenum render_mode);
|
||||
void SetShader();
|
||||
void SetShader(bool is_lighting_on);
|
||||
void SetBoundingBox();
|
||||
void SetLightDirection(const glm::vec3& light_direction);
|
||||
void Render(const glm::mat4& projection_mat, const glm::mat4& view_mat) const;
|
||||
bool IsIntersecting(const Segment& segment);
|
||||
|
||||
protected:
|
||||
BoundingBox* bounding_box_;
|
||||
bool is_lighting_on_;
|
||||
bool is_bounding_box_on_;
|
||||
glm::vec3 light_direction_;
|
||||
GLuint uniform_mv_mat_;
|
||||
GLuint uniform_light_vec_;
|
||||
};
|
||||
} // namespace tango_gl
|
||||
#endif // TANGO_GL_MESH_H_
|
||||
61
app/android/jni/tango-gl/include/tango-gl/obj_loader.h
Normal file
61
app/android/jni/tango-gl/include/tango-gl/obj_loader.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TANGO_GL_OBJ_LOADER_H
|
||||
#define TANGO_GL_OBJ_LOADER_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "tango-gl/util.h"
|
||||
|
||||
namespace tango_gl {
|
||||
namespace obj_loader {
|
||||
// Load standard .obj file into vertices, indices or normals vectors,
|
||||
// OBJ file can be exported from 3D tools like 3ds Max or Blender.
|
||||
// A readable file with only vertices should look like
|
||||
// "v 1.00 2.00 3.00
|
||||
// ...
|
||||
// f 1 2 3
|
||||
// f 1 2 3 4
|
||||
// ..."
|
||||
//
|
||||
// If exported with normals, file should look like
|
||||
// "v 1.00 2.00 3.00
|
||||
// ...
|
||||
// f 1//1 2//3 3//4
|
||||
// f 1//1 2//3 3//4 4//6
|
||||
// ...
|
||||
// vn 1.00 2.00 3.00
|
||||
// ..."
|
||||
// this can be used with Mesh:
|
||||
//
|
||||
// std::vector<GLfloat> vertices;
|
||||
// std::vector<GLushort> indices;
|
||||
// std::vector<GLfloat> normals;
|
||||
// tango_gl::obj_loader::LoadOBJData("/sdcard/model.obj", vertices, indices);
|
||||
// mesh->SetVertices(vertices, indices);
|
||||
// or
|
||||
// tango_gl::obj_loader::LoadOBJData("/sdcard/model.obj", vertices, normals);
|
||||
// mesh->SetVertices(vertices, normals);
|
||||
|
||||
bool LoadOBJData(const char* path, std::vector<GLfloat>& vertices,
|
||||
std::vector<GLushort>& indices);
|
||||
|
||||
bool LoadOBJData(const char* path, std::vector<GLfloat>& vertices,
|
||||
std::vector<GLfloat>& normals);
|
||||
} // namespace obj_loader
|
||||
} // namespace tango_gl
|
||||
#endif // TANGO_GL_OBJ_LOADER
|
||||
44
app/android/jni/tango-gl/include/tango-gl/quad.h
Normal file
44
app/android/jni/tango-gl/include/tango-gl/quad.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TANGO_GL_QUAD_H_
|
||||
#define TANGO_GL_QUAD_H_
|
||||
|
||||
#include "tango-gl/drawable_object.h"
|
||||
|
||||
namespace tango_gl {
|
||||
class Quad : public DrawableObject {
|
||||
public:
|
||||
Quad();
|
||||
Quad(const Quad& other) = delete;
|
||||
Quad& operator=(const Quad&) = delete;
|
||||
~Quad();
|
||||
|
||||
void Render(const glm::mat4& projection_mat, const glm::mat4& view_mat) const;
|
||||
void SetTextureId(GLuint texture_id);
|
||||
|
||||
private:
|
||||
GLuint vertex_buffer_;
|
||||
GLuint shader_program_;
|
||||
GLuint attrib_vertices_;
|
||||
GLuint texture_coords_;
|
||||
GLuint texture_handle;
|
||||
GLuint uniform_mvp_mat_;
|
||||
|
||||
GLuint texture_id_;
|
||||
};
|
||||
} // namespace tango_gl
|
||||
#endif // TANGO_GL_QUAD_H_
|
||||
35
app/android/jni/tango-gl/include/tango-gl/segment.h
Normal file
35
app/android/jni/tango-gl/include/tango-gl/segment.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TANGO_GL_SEGMENT_H_
|
||||
#define TANGO_GL_SEGMENT_H_
|
||||
|
||||
#include "glm/glm.hpp"
|
||||
|
||||
namespace tango_gl {
|
||||
class Segment {
|
||||
public:
|
||||
Segment() : start(glm::vec3(0, 0, 0)), end(glm::vec3(0, 0, 0)) {}
|
||||
Segment(const glm::vec3& segment_start, const glm::vec3& segment_end)
|
||||
: start(segment_start), end(segment_end) {}
|
||||
Segment(const Segment&) = default;
|
||||
Segment& operator=(const Segment&) = default;
|
||||
|
||||
glm::vec3 start;
|
||||
glm::vec3 end;
|
||||
};
|
||||
} // namespace tango_gl
|
||||
#endif // TANGO_GL_SEGMENT_H_
|
||||
30
app/android/jni/tango-gl/include/tango-gl/segment_drawable.h
Normal file
30
app/android/jni/tango-gl/include/tango-gl/segment_drawable.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TANGO_GL_SEGMENT_DRAWABLE_H_
|
||||
#define TANGO_GL_SEGMENT_DRAWABLE_H_
|
||||
|
||||
#include "tango-gl/line.h"
|
||||
#include "tango-gl/segment.h"
|
||||
|
||||
namespace tango_gl {
|
||||
class SegmentDrawable : public Line {
|
||||
public:
|
||||
SegmentDrawable();
|
||||
void UpdateSegment(const Segment& segment);
|
||||
};
|
||||
} // namespace tango_gl
|
||||
#endif // TANGO_GL_SEGMENT_DRAWABLE_H_
|
||||
32
app/android/jni/tango-gl/include/tango-gl/shaders.h
Normal file
32
app/android/jni/tango-gl/include/tango-gl/shaders.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TANGO_GL_SHADERS_H_
|
||||
#define TANGO_GL_SHADERS_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace tango_gl {
|
||||
namespace shaders {
|
||||
std::string GetBasicVertexShader();
|
||||
std::string GetBasicFragmentShader();
|
||||
std::string GetColorVertexShader();
|
||||
std::string GetVideoOverlayVertexShader();
|
||||
std::string GetVideoOverlayFragmentShader();
|
||||
std::string GetShadedVertexShader();
|
||||
} // namespace shaders
|
||||
} // namespace tango_gl
|
||||
#endif // TANGO_GL_SHADERS_H_
|
||||
50
app/android/jni/tango-gl/include/tango-gl/texture.h
Normal file
50
app/android/jni/tango-gl/include/tango-gl/texture.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TANGO_GL_TEXTURE_H_
|
||||
#define TANGO_GL_TEXTURE_H_
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <png.h>
|
||||
#endif
|
||||
|
||||
#include "tango-gl/util.h"
|
||||
|
||||
namespace tango_gl {
|
||||
class Texture {
|
||||
public:
|
||||
Texture(const char* file_path);
|
||||
Texture(const Texture& other) = delete;
|
||||
Texture& operator=(const Texture&) = delete;
|
||||
~Texture();
|
||||
|
||||
#ifdef __ANDROID__
|
||||
bool LoadFromPNG(const char* file_path);
|
||||
#endif
|
||||
GLuint GetTextureID() const;
|
||||
|
||||
private:
|
||||
#ifdef __ANDROID__
|
||||
png_uint_32 width_, height_;
|
||||
#endif
|
||||
int bit_depth_, color_type_;
|
||||
char* byte_data_;
|
||||
GLuint texture_id_;
|
||||
};
|
||||
} // namespace tango_gl
|
||||
#endif // TANGO_GL_TEXTURE_H_
|
||||
30
app/android/jni/tango-gl/include/tango-gl/trace.h
Normal file
30
app/android/jni/tango-gl/include/tango-gl/trace.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TANGO_GL_TRACE_H_
|
||||
#define TANGO_GL_TRACE_H_
|
||||
|
||||
#include "tango-gl/line.h"
|
||||
|
||||
namespace tango_gl {
|
||||
class Trace : public Line {
|
||||
public:
|
||||
Trace();
|
||||
void UpdateVertexArray(const glm::vec3& v);
|
||||
void ClearVertexArray();
|
||||
};
|
||||
} // namespace tango_gl
|
||||
#endif // TANGO_GL_TRACE_H_
|
||||
59
app/android/jni/tango-gl/include/tango-gl/transform.h
Normal file
59
app/android/jni/tango-gl/include/tango-gl/transform.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TANGO_GL_TRANSFORM_H_
|
||||
#define TANGO_GL_TRANSFORM_H_
|
||||
|
||||
#include "glm/glm.hpp"
|
||||
#include "glm/gtc/quaternion.hpp"
|
||||
|
||||
namespace tango_gl {
|
||||
class Transform {
|
||||
public:
|
||||
Transform();
|
||||
virtual ~Transform();
|
||||
|
||||
Transform(const Transform& other) = delete;
|
||||
const Transform& operator=(const Transform& rhs) = delete;
|
||||
|
||||
void SetPosition(const glm::vec3& position);
|
||||
glm::vec3 GetPosition() const;
|
||||
|
||||
void SetRotation(const glm::quat& rotation);
|
||||
glm::quat GetRotation() const;
|
||||
|
||||
void SetScale(const glm::vec3& scale);
|
||||
glm::vec3 GetScale() const;
|
||||
|
||||
void Translate(const glm::vec3& translation);
|
||||
|
||||
void SetTransformationMatrix(const glm::mat4& transform_mat);
|
||||
glm::mat4 GetTransformationMatrix() const;
|
||||
|
||||
void SetParent(Transform* transform);
|
||||
|
||||
const Transform* GetParent() const ;
|
||||
Transform* GetParent() ;
|
||||
|
||||
private:
|
||||
Transform* parent_;
|
||||
|
||||
glm::vec3 position_;
|
||||
glm::quat rotation_;
|
||||
glm::vec3 scale_;
|
||||
};
|
||||
} // namespace tango_gl
|
||||
#endif // TANGO_GL_TRANSFORM_H_
|
||||
28
app/android/jni/tango-gl/include/tango-gl/triangle.h
Normal file
28
app/android/jni/tango-gl/include/tango-gl/triangle.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TANGO_GL_TRIANGLE_H_
|
||||
#define TANGO_GL_TRIANGLE_H_
|
||||
|
||||
#include "tango-gl/mesh.h"
|
||||
|
||||
namespace tango_gl {
|
||||
class Triangle : public Mesh {
|
||||
public:
|
||||
Triangle();
|
||||
};
|
||||
} // namespace tango_gl
|
||||
#endif // TANGO_GL_TRIANGLE_H_
|
||||
106
app/android/jni/tango-gl/include/tango-gl/util.h
Normal file
106
app/android/jni/tango-gl/include/tango-gl/util.h
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TANGO_GL_GL_UTIL_H_
|
||||
#define TANGO_GL_GL_UTIL_H_
|
||||
#define GLM_FORCE_RADIANS
|
||||
|
||||
#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642
|
||||
|
||||
#include <stdlib.h>
|
||||
#ifdef __ANDROID__
|
||||
#include <jni.h>
|
||||
#include <android/log.h>
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
#else // __APPLE__
|
||||
#include <OpenGLES/ES2/gl.h>
|
||||
#include <OpenGLES/ES2/glext.h>
|
||||
#include <syslog.h>
|
||||
#endif
|
||||
|
||||
#include "glm/glm.hpp"
|
||||
#include "glm/gtc/matrix_transform.hpp"
|
||||
#include "glm/gtc/quaternion.hpp"
|
||||
#include "glm/gtc/type_ptr.hpp"
|
||||
#include "glm/gtx/matrix_decompose.hpp"
|
||||
|
||||
#define LOG_TAG "rtabmap"
|
||||
#if defined(DISABLE_LOG)
|
||||
#define LOGD(...) ;
|
||||
#define LOGI(...) ;
|
||||
#define LOGW(...) ;
|
||||
#else
|
||||
#ifdef __APPLE__
|
||||
#define LOGD(...) fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n")
|
||||
#define LOGI(...) fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n")
|
||||
#define LOGW(...) fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n")
|
||||
#else
|
||||
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
|
||||
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
|
||||
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__)
|
||||
#endif
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
#define LOGE(...) fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n")
|
||||
#define LOGF(...) fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n")
|
||||
#else
|
||||
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
|
||||
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,LOG_TAG,__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.1415926f
|
||||
#endif
|
||||
|
||||
#define RADIAN_2_DEGREE 57.2957795f
|
||||
#define DEGREE_2_RADIANS 0.0174532925f
|
||||
|
||||
namespace tango_gl {
|
||||
namespace util {
|
||||
void CheckGlError(const char* operation);
|
||||
|
||||
GLuint CreateProgram(const char* vertex_source,
|
||||
const char* fragment_source);
|
||||
|
||||
void DecomposeMatrix(const glm::mat4& transform_mat,
|
||||
glm::vec3& translation,
|
||||
glm::quat& rotation,
|
||||
glm::vec3& scale);
|
||||
|
||||
// Get a 3x1 column from the upper 3x4 of a transformation matrix. Columns
|
||||
// 0, 1, 2 are the rotation/scale portion, and column 3 is the translation.
|
||||
glm::vec3 GetColumnFromMatrix(const glm::mat4& mat, const int col);
|
||||
|
||||
// Get the translation component of a transformation matrix.
|
||||
glm::vec3 GetTranslationFromMatrix(const glm::mat4& mat);
|
||||
|
||||
float Clamp(float value, float min, float max);
|
||||
void PrintMatrix(const glm::mat4& matrix);
|
||||
void PrintVector(const glm::vec3& vector);
|
||||
void PrintQuaternion(const glm::quat& quat);
|
||||
|
||||
glm::vec3 LerpVector(const glm::vec3& x, const glm::vec3& y, float a);
|
||||
float DistanceSquared(const glm::vec3& v1, const glm::vec3& v2);
|
||||
|
||||
bool SegmentAABBIntersect(const glm::vec3& aabb_min, const glm::vec3& aabb_max,
|
||||
const glm::vec3& start, const glm::vec3& end);
|
||||
|
||||
glm::vec3 ApplyTransform(const glm::mat4& mat, const glm::vec3& vec);
|
||||
|
||||
} // namespace util
|
||||
} // namespace tango_gl
|
||||
#endif // TANGO_GL_RENDERER_GL_UTIL
|
||||
39
app/android/jni/tango-gl/include/tango-gl/video_overlay.h
Normal file
39
app/android/jni/tango-gl/include/tango-gl/video_overlay.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TANGO_GL_RENDERER_VIDEO_OVERLAY_H_
|
||||
#define TANGO_GL_RENDERER_VIDEO_OVERLAY_H_
|
||||
|
||||
#include "tango-gl/drawable_object.h"
|
||||
|
||||
namespace tango_gl {
|
||||
class VideoOverlay : public DrawableObject {
|
||||
public:
|
||||
VideoOverlay();
|
||||
void Render(const glm::mat4& projection_mat, const glm::mat4& view_mat) const;
|
||||
GLuint GetTextureId() const { return texture_id_; }
|
||||
void SetTextureId(GLuint texture_id) { texture_id_ = texture_id; }
|
||||
|
||||
private:
|
||||
// This id is populated on construction, and is passed to the tango service.
|
||||
GLuint texture_id_;
|
||||
|
||||
GLuint attrib_texture_coords_;
|
||||
GLuint uniform_texture_;
|
||||
GLuint vertex_buffers_[3];
|
||||
};
|
||||
} // namespace tango_gl
|
||||
#endif // TANGO_GL_RENDERER_VIDEO_OVERLAY_H_
|
||||
44
app/android/jni/tango-gl/line.cpp
Normal file
44
app/android/jni/tango-gl/line.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "tango-gl/line.h"
|
||||
|
||||
namespace tango_gl {
|
||||
Line::Line(float line_width, GLenum render_mode) {
|
||||
line_width_ = line_width;
|
||||
render_mode_ = render_mode;
|
||||
}
|
||||
void Line::SetLineWidth(const float pixels) { line_width_ = pixels; }
|
||||
void Line::Render(const glm::mat4& projection_mat,
|
||||
const glm::mat4& view_mat) const {
|
||||
glUseProgram(shader_program_);
|
||||
glLineWidth(line_width_);
|
||||
glm::mat4 model_mat = GetTransformationMatrix();
|
||||
glm::mat4 mvp_mat = projection_mat * view_mat * model_mat;
|
||||
glUniformMatrix4fv(uniform_mvp_mat_, 1, GL_FALSE, glm::value_ptr(mvp_mat));
|
||||
|
||||
glUniform4f(uniform_color_, red_, green_, blue_, alpha_);
|
||||
|
||||
glEnableVertexAttribArray(attrib_vertices_);
|
||||
glVertexAttribPointer(attrib_vertices_, 3, GL_FLOAT, GL_FALSE,
|
||||
sizeof(glm::vec3), &vec_vertices_[0]);
|
||||
glDrawArrays(render_mode_, 0, vec_vertices_.size());
|
||||
|
||||
glDisableVertexAttribArray(attrib_vertices_);
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
} // namespace tango_gl
|
||||
124
app/android/jni/tango-gl/mesh.cpp
Normal file
124
app/android/jni/tango-gl/mesh.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "tango-gl/mesh.h"
|
||||
#include "tango-gl/shaders.h"
|
||||
|
||||
namespace tango_gl {
|
||||
Mesh::Mesh() {
|
||||
render_mode_ = GL_TRIANGLES;
|
||||
}
|
||||
Mesh::Mesh(GLenum render_mode) {
|
||||
render_mode_ = render_mode;
|
||||
}
|
||||
|
||||
void Mesh::SetShader() {
|
||||
DrawableObject::SetShader();
|
||||
// Default mode set to no lighting.
|
||||
is_lighting_on_ = false;
|
||||
// Default mode set to without bounding box detection.
|
||||
is_bounding_box_on_ = false;
|
||||
}
|
||||
|
||||
void Mesh::SetShader(bool is_lighting_on) {
|
||||
if (is_lighting_on) {
|
||||
shader_program_ =
|
||||
util::CreateProgram(shaders::GetShadedVertexShader().c_str(),
|
||||
shaders::GetBasicFragmentShader().c_str());
|
||||
if (!shader_program_) {
|
||||
LOGE("Could not create program.");
|
||||
}
|
||||
uniform_mvp_mat_ = glGetUniformLocation(shader_program_, "mvp");
|
||||
uniform_mv_mat_ = glGetUniformLocation(shader_program_, "mv");
|
||||
uniform_light_vec_ = glGetUniformLocation(shader_program_, "lightVec");
|
||||
uniform_color_ = glGetUniformLocation(shader_program_, "color");
|
||||
|
||||
attrib_vertices_ = glGetAttribLocation(shader_program_, "vertex");
|
||||
attrib_normals_ = glGetAttribLocation(shader_program_, "normal");
|
||||
is_lighting_on_ = true;
|
||||
// Set a defualt direction for directional light.
|
||||
light_direction_ = glm::vec3(-1.0f, -3.0f, -1.0f);
|
||||
light_direction_ = glm::normalize(light_direction_);
|
||||
} else {
|
||||
SetShader();
|
||||
}
|
||||
}
|
||||
|
||||
void Mesh::SetBoundingBox(){
|
||||
// Traverse all the vertices to define an axis-aligned
|
||||
// bounding box for this mesh, needs to be called after SetVertices().
|
||||
if(vertices_.size()==0){
|
||||
LOGE("Please set up vertices first!");
|
||||
return;
|
||||
}
|
||||
is_bounding_box_on_ = true;
|
||||
bounding_box_ = new BoundingBox(vertices_);
|
||||
}
|
||||
|
||||
void Mesh::SetLightDirection(const glm::vec3& light_direction) {
|
||||
light_direction_ = light_direction;
|
||||
}
|
||||
|
||||
bool Mesh::IsIntersecting(const Segment& segment) {
|
||||
// If there is no bounding box defined based on all vertices,
|
||||
// we can not calculate intersection.
|
||||
if (!is_bounding_box_on_) {
|
||||
LOGE("Mesh::IsIntersecting, bounding box is not available.");
|
||||
return false;
|
||||
}
|
||||
return bounding_box_->IsIntersecting(segment, GetRotation(),
|
||||
GetTransformationMatrix());
|
||||
}
|
||||
|
||||
void Mesh::Render(const glm::mat4& projection_mat,
|
||||
const glm::mat4& view_mat) const {
|
||||
glUseProgram(shader_program_);
|
||||
glm::mat4 model_mat = GetTransformationMatrix();
|
||||
glm::mat4 mv_mat = view_mat * model_mat;
|
||||
glm::mat4 mvp_mat = projection_mat * mv_mat;
|
||||
glUniformMatrix4fv(uniform_mvp_mat_, 1, GL_FALSE, glm::value_ptr(mvp_mat));
|
||||
glUniform4f(uniform_color_, red_, green_, blue_, alpha_);
|
||||
|
||||
if (is_lighting_on_) {
|
||||
glUniformMatrix4fv(uniform_mv_mat_, 1, GL_FALSE, glm::value_ptr(mv_mat));
|
||||
|
||||
glEnableVertexAttribArray(attrib_normals_);
|
||||
glVertexAttribPointer(attrib_normals_, 3, GL_FLOAT, GL_FALSE,
|
||||
3 * sizeof(GLfloat), &normals_[0]);
|
||||
glm::vec3 light_direction = glm::mat3(view_mat) * light_direction_;
|
||||
glUniform3fv(uniform_light_vec_, 1, glm::value_ptr(light_direction));
|
||||
}
|
||||
|
||||
glEnableVertexAttribArray(attrib_vertices_);
|
||||
|
||||
if (!indices_.empty()) {
|
||||
glVertexAttribPointer(attrib_vertices_, 3, GL_FLOAT, GL_FALSE,
|
||||
3 * sizeof(GLfloat), vertices_.data());
|
||||
glDrawElements(render_mode_, indices_.size(), GL_UNSIGNED_SHORT,
|
||||
indices_.data());
|
||||
} else {
|
||||
glVertexAttribPointer(attrib_vertices_, 3, GL_FLOAT, GL_FALSE,
|
||||
3 * sizeof(GLfloat), &vertices_[0]);
|
||||
glDrawArrays(render_mode_, 0, vertices_.size() / 3);
|
||||
}
|
||||
|
||||
glDisableVertexAttribArray(attrib_vertices_);
|
||||
if (is_lighting_on_) {
|
||||
glDisableVertexAttribArray(attrib_normals_);
|
||||
}
|
||||
glUseProgram(0);
|
||||
}
|
||||
} // namespace tango_gl
|
||||
156
app/android/jni/tango-gl/obj_loader.cpp
Normal file
156
app/android/jni/tango-gl/obj_loader.cpp
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include <string>
|
||||
|
||||
#include "tango-gl/obj_loader.h"
|
||||
|
||||
namespace tango_gl {
|
||||
bool obj_loader::LoadOBJData(const char* path, std::vector<GLfloat>& vertices,
|
||||
std::vector<GLushort>& indices) {
|
||||
FILE *file = fopen(path, "r");
|
||||
if (file == NULL) {
|
||||
LOGE("Failed to open file: %s", path);
|
||||
return false;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
char lineHeader[128];
|
||||
int res = fscanf(file, "%s", lineHeader);
|
||||
if (res == EOF) break;
|
||||
if (strcmp(lineHeader, "v") == 0) {
|
||||
GLfloat vertex[3];
|
||||
int matches =
|
||||
fscanf(file, "%f %f %f\n", &vertex[0], &vertex[1], &vertex[2]);
|
||||
if (matches != 3) {
|
||||
LOGE("Format of 'v float float float' required for each vertice line");
|
||||
return false;
|
||||
}
|
||||
vertices.push_back(vertex[0]);
|
||||
vertices.push_back(vertex[1]);
|
||||
vertices.push_back(vertex[2]);
|
||||
} else if (strcmp(lineHeader, "f") == 0) {
|
||||
GLushort vertexIndex[3];
|
||||
int matches = fscanf(file, "%hu %hu %hu\n", &vertexIndex[0],
|
||||
&vertexIndex[1], &vertexIndex[2]);
|
||||
if (matches != 3) {
|
||||
LOGE("Format of 'f int int int' required for each face line");
|
||||
return false;
|
||||
}
|
||||
indices.push_back(vertexIndex[0] - 1);
|
||||
indices.push_back(vertexIndex[1] - 1);
|
||||
indices.push_back(vertexIndex[2] - 1);
|
||||
}
|
||||
else {
|
||||
char comments_buffer[1000];
|
||||
fgets(comments_buffer, 1000, file);
|
||||
}
|
||||
}
|
||||
fclose(file);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool obj_loader::LoadOBJData(const char* path, std::vector<GLfloat>& vertices,
|
||||
std::vector<GLfloat>& normals) {
|
||||
std::vector<unsigned int> vertexIndices, normalIndices;
|
||||
std::vector<GLfloat> temp_vertices, temp_normals;
|
||||
|
||||
FILE* file = fopen(path, "r");
|
||||
if (file == NULL) {
|
||||
LOGE("Failed to open file: %s", path);
|
||||
return false;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
char lineHeader[128];
|
||||
int res = fscanf(file, "%s", lineHeader);
|
||||
if (res == EOF) break;
|
||||
if (strcmp(lineHeader, "v") == 0) {
|
||||
GLfloat vertex[3];
|
||||
int matches =
|
||||
fscanf(file, "%f %f %f\n", &vertex[0], &vertex[1], &vertex[2]);
|
||||
if (matches != 3) {
|
||||
LOGE("Format of 'v float float float' required for each vertice line");
|
||||
return false;
|
||||
}
|
||||
temp_vertices.push_back(vertex[0]);
|
||||
temp_vertices.push_back(vertex[1]);
|
||||
temp_vertices.push_back(vertex[2]);
|
||||
} else if (strcmp(lineHeader, "vn") == 0) {
|
||||
GLfloat normal[3];
|
||||
int matches =
|
||||
fscanf(file, "%f %f %f\n", &normal[0], &normal[1], &normal[2]);
|
||||
if (matches != 3) {
|
||||
LOGE("Format of 'vn float float float' required for each normal line");
|
||||
return false;
|
||||
}
|
||||
temp_normals.push_back(normal[0]);
|
||||
temp_normals.push_back(normal[1]);
|
||||
temp_normals.push_back(normal[2]);
|
||||
} else if (strcmp(lineHeader, "f") == 0) {
|
||||
GLushort vertexIndex[4];
|
||||
GLushort normalIndex[4];
|
||||
int matches = fscanf(file, "%hu//%hu %hu//%hu %hu//%hu %hu//%hu\n",
|
||||
&vertexIndex[0], &normalIndex[0], &vertexIndex[1], &normalIndex[1],
|
||||
&vertexIndex[2], &normalIndex[2], &vertexIndex[3], &normalIndex[3]);
|
||||
|
||||
// .obj file is 1-indexed, so subtract 1 from all indices.
|
||||
if (matches == 6) {
|
||||
// If triangles provided.
|
||||
vertexIndices.push_back(vertexIndex[0] - 1);
|
||||
vertexIndices.push_back(vertexIndex[1] - 1);
|
||||
vertexIndices.push_back(vertexIndex[2] - 1);
|
||||
normalIndices.push_back(normalIndex[0] - 1);
|
||||
normalIndices.push_back(normalIndex[1] - 1);
|
||||
normalIndices.push_back(normalIndex[2] - 1);
|
||||
} else if(matches == 8) {
|
||||
// If quads provided.
|
||||
vertexIndices.push_back(vertexIndex[0] - 1);
|
||||
vertexIndices.push_back(vertexIndex[1] - 1);
|
||||
vertexIndices.push_back(vertexIndex[2] - 1);
|
||||
vertexIndices.push_back(vertexIndex[0] - 1);
|
||||
vertexIndices.push_back(vertexIndex[2] - 1);
|
||||
vertexIndices.push_back(vertexIndex[3] - 1);
|
||||
normalIndices.push_back(normalIndex[0] - 1);
|
||||
normalIndices.push_back(normalIndex[1] - 1);
|
||||
normalIndices.push_back(normalIndex[2] - 1);
|
||||
normalIndices.push_back(normalIndex[0] - 1);
|
||||
normalIndices.push_back(normalIndex[2] - 1);
|
||||
normalIndices.push_back(normalIndex[3] - 1);
|
||||
} else {
|
||||
LOGE("Format of 'f int//int int//int int//int' required for each face");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
char comments_buffer[1000];
|
||||
fgets(comments_buffer, 1000, file);
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < vertexIndices.size(); i++) {
|
||||
unsigned int vertexIndex = vertexIndices[i];
|
||||
unsigned int normalIndex = normalIndices[i];
|
||||
|
||||
vertices.push_back(temp_vertices[vertexIndex * 3]);
|
||||
vertices.push_back(temp_vertices[vertexIndex * 3 + 1]);
|
||||
vertices.push_back(temp_vertices[vertexIndex * 3 + 2]);
|
||||
normals.push_back(temp_normals[normalIndex * 3]);
|
||||
normals.push_back(temp_normals[normalIndex * 3 + 1]);
|
||||
normals.push_back(temp_normals[normalIndex * 3 + 2]);
|
||||
}
|
||||
fclose(file);
|
||||
return true;
|
||||
}
|
||||
} // namespace tango_gl
|
||||
91
app/android/jni/tango-gl/quad.cpp
Normal file
91
app/android/jni/tango-gl/quad.cpp
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "tango-gl/quad.h"
|
||||
#include "tango-gl/util.h"
|
||||
|
||||
namespace tango_gl {
|
||||
|
||||
static const char kVertexShader[] =
|
||||
"attribute vec4 vertex;\n"
|
||||
"attribute vec2 inputTextureCoordinate;\n"
|
||||
"varying vec2 textureCoordinate;\n"
|
||||
"uniform mat4 mvp;\n"
|
||||
"void main() {\n"
|
||||
" gl_Position = mvp*vertex;\n"
|
||||
" textureCoordinate = inputTextureCoordinate.xy;\n"
|
||||
"}\n";
|
||||
|
||||
static const char kFragmentShader[] =
|
||||
"varying vec2 textureCoordinate;\n"
|
||||
"uniform sampler2D inputTexture;\n"
|
||||
"void main() {\n"
|
||||
" gl_FragColor = texture2D(inputTexture, textureCoordinate);\n"
|
||||
"}\n";
|
||||
|
||||
static const float vertices[] = {-0.5f, -0.5f, 0.5f, -0.5f,
|
||||
-0.5f, 0.5f, 0.5f, 0.5f};
|
||||
|
||||
static const GLfloat texture_coords[] = {0.0f, 1.0f, 1.0f, 1.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f, };
|
||||
|
||||
Quad::Quad() {
|
||||
shader_program_ = util::CreateProgram(kVertexShader, kFragmentShader);
|
||||
if (!shader_program_) {
|
||||
LOGE("Could not create program.");
|
||||
}
|
||||
uniform_mvp_mat_ = glGetUniformLocation(shader_program_, "mvp");
|
||||
attrib_vertices_ = glGetAttribLocation(shader_program_, "vertex");
|
||||
texture_coords_ =
|
||||
glGetAttribLocation(shader_program_, "inputTextureCoordinate");
|
||||
texture_handle = glGetUniformLocation(shader_program_, "inputTexture");
|
||||
glGenBuffers(1, &vertex_buffer_);
|
||||
}
|
||||
|
||||
Quad::~Quad() { glDeleteShader(shader_program_); }
|
||||
|
||||
void Quad::SetTextureId(GLuint texture_id) { texture_id_ = texture_id; }
|
||||
|
||||
void Quad::Render(const glm::mat4& projection_mat,
|
||||
const glm::mat4& view_mat) const {
|
||||
glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glUseProgram(shader_program_);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texture_id_);
|
||||
glUniform1i(texture_handle, 0);
|
||||
|
||||
// Calculate MVP matrix and pass it to shader.
|
||||
glm::mat4 model_mat = GetTransformationMatrix();
|
||||
glm::mat4 mvp_mat = projection_mat * view_mat * model_mat;
|
||||
glUniformMatrix4fv(uniform_mvp_mat_, 1, GL_FALSE, glm::value_ptr(mvp_mat));
|
||||
|
||||
// Vertice binding
|
||||
glEnableVertexAttribArray(attrib_vertices_);
|
||||
glVertexAttribPointer(attrib_vertices_, 2, GL_FLOAT, GL_FALSE, 0, vertices);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
glEnableVertexAttribArray(texture_coords_);
|
||||
glVertexAttribPointer(texture_coords_, 2, GL_FLOAT, GL_FALSE, 0,
|
||||
texture_coords);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glUseProgram(0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
} // namespace tango_gl
|
||||
29
app/android/jni/tango-gl/segment_drawable.cpp
Normal file
29
app/android/jni/tango-gl/segment_drawable.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "tango-gl/segment_drawable.h"
|
||||
|
||||
namespace tango_gl {
|
||||
SegmentDrawable::SegmentDrawable() : tango_gl::Line(5.0f, GL_LINES) {
|
||||
SetShader();
|
||||
vec_vertices_.push_back(glm::vec3(0, 0, 0));
|
||||
vec_vertices_.push_back(glm::vec3(1.f, 1.f, 1.f));
|
||||
}
|
||||
void SegmentDrawable::UpdateSegment(const Segment& segment) {
|
||||
vec_vertices_[0] = segment.start;
|
||||
vec_vertices_[1] = segment.end;
|
||||
}
|
||||
} // namespace tango_gl
|
||||
95
app/android/jni/tango-gl/shaders.cpp
Normal file
95
app/android/jni/tango-gl/shaders.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "tango-gl/shaders.h"
|
||||
|
||||
namespace tango_gl {
|
||||
namespace shaders {
|
||||
std::string GetBasicVertexShader() {
|
||||
return "precision mediump float;\n"
|
||||
"precision mediump int;\n"
|
||||
"attribute vec4 vertex;\n"
|
||||
"uniform mat4 mvp;\n"
|
||||
"uniform vec4 color;\n"
|
||||
"varying vec4 v_color;\n"
|
||||
"void main() {\n"
|
||||
" gl_Position = mvp*vertex;\n"
|
||||
" v_color = color;\n"
|
||||
"}\n";
|
||||
}
|
||||
|
||||
std::string GetBasicFragmentShader() {
|
||||
return "precision mediump float;\n"
|
||||
"varying vec4 v_color;\n"
|
||||
"void main() {\n"
|
||||
" gl_FragColor = v_color;\n"
|
||||
"}\n";
|
||||
}
|
||||
|
||||
std::string GetColorVertexShader() {
|
||||
return "precision mediump float;\n"
|
||||
"precision mediump int;\n"
|
||||
"attribute vec4 vertex;\n"
|
||||
"attribute vec4 color;\n"
|
||||
"uniform mat4 mvp;\n"
|
||||
"varying vec4 v_color;\n"
|
||||
"void main() {\n"
|
||||
" gl_Position = mvp*vertex;\n"
|
||||
" v_color = color;\n"
|
||||
"}\n";
|
||||
}
|
||||
|
||||
std::string GetVideoOverlayVertexShader() {
|
||||
return "precision highp float;\n"
|
||||
"precision highp int;\n"
|
||||
"attribute vec4 vertex;\n"
|
||||
"attribute vec2 textureCoords;\n"
|
||||
"varying vec2 f_textureCoords;\n"
|
||||
"uniform mat4 mvp;\n"
|
||||
"void main() {\n"
|
||||
" f_textureCoords = textureCoords;\n"
|
||||
" gl_Position = mvp * vertex;\n"
|
||||
"}\n";
|
||||
}
|
||||
|
||||
std::string GetVideoOverlayFragmentShader() {
|
||||
return "#extension GL_OES_EGL_image_external : require\n"
|
||||
"precision highp float;\n"
|
||||
"precision highp int;\n"
|
||||
"uniform samplerExternalOES texture;\n"
|
||||
"varying vec2 f_textureCoords;\n"
|
||||
"void main() {\n"
|
||||
" gl_FragColor = texture2D(texture, f_textureCoords);\n"
|
||||
"}\n";
|
||||
}
|
||||
|
||||
std::string GetShadedVertexShader() {
|
||||
return "attribute vec4 vertex;\n"
|
||||
"attribute vec3 normal;\n"
|
||||
"uniform mat4 mvp;\n"
|
||||
"uniform mat4 mv;\n"
|
||||
"uniform vec4 color;\n"
|
||||
"uniform vec3 lightVec;\n"
|
||||
"varying vec4 v_color;\n"
|
||||
"void main() {\n"
|
||||
" vec3 mvNormal = vec3(mv * vec4(normal, 0.0));\n"
|
||||
" float diffuse = max(-dot(mvNormal, lightVec), 0.0);\n"
|
||||
" v_color.a = color.a;\n"
|
||||
" v_color.xyz = color.xyz * diffuse + color.xyz * 0.3;\n"
|
||||
" gl_Position = mvp*vertex;\n"
|
||||
"}\n";
|
||||
}
|
||||
} // namespace shaders
|
||||
} // namespace tango_gl
|
||||
109
app/android/jni/tango-gl/texture.cpp
Normal file
109
app/android/jni/tango-gl/texture.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "tango-gl/texture.h"
|
||||
#include "tango-gl/util.h"
|
||||
|
||||
namespace tango_gl {
|
||||
|
||||
static const int kMaxExponentiation = 12;
|
||||
|
||||
static int RoundUpPowerOfTwo(int w) {
|
||||
int start = 2;
|
||||
for (int i = 0; i <= kMaxExponentiation; ++i) {
|
||||
if (w < start) {
|
||||
w = start;
|
||||
break;
|
||||
} else {
|
||||
start = start << 1;
|
||||
}
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
Texture::Texture(const char* file_path) {
|
||||
#ifdef __ANDROID__
|
||||
if (!LoadFromPNG(file_path)) {
|
||||
LOGE("Texture initialing error");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifdef __ANDROID__
|
||||
bool Texture::LoadFromPNG(const char* file_path) {
|
||||
FILE* file = fopen(file_path, "rb");
|
||||
|
||||
if (file == NULL) {
|
||||
LOGE("fp not loaded: %s", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
fseek(file, 8, SEEK_CUR);
|
||||
|
||||
png_structp png_ptr =
|
||||
png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
png_infop info_ptr = png_create_info_struct(png_ptr);
|
||||
|
||||
png_init_io(png_ptr, file);
|
||||
png_set_sig_bytes(png_ptr, 8);
|
||||
png_read_info(png_ptr, info_ptr);
|
||||
png_get_IHDR(png_ptr, info_ptr, &width_, &height_, &bit_depth_, &color_type_,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
width_ = RoundUpPowerOfTwo(width_);
|
||||
height_ = RoundUpPowerOfTwo(height_);
|
||||
int row = width_ * (color_type_ == PNG_COLOR_TYPE_RGBA ? 4 : 3);
|
||||
byte_data_ = new char[row * height_];
|
||||
|
||||
png_bytep* row_pointers = new png_bytep[height_];
|
||||
for (uint i = 0; i < height_; ++i) {
|
||||
row_pointers[i] = (png_bytep)(byte_data_ + i * row);
|
||||
}
|
||||
png_read_image(png_ptr, row_pointers);
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, 0);
|
||||
|
||||
glGenTextures(1, &texture_id_);
|
||||
glBindTexture(GL_TEXTURE_2D, texture_id_);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
util::CheckGlError("glBindTexture");
|
||||
if (color_type_ == PNG_COLOR_TYPE_RGBA) {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_, 0, GL_RGBA,
|
||||
GL_UNSIGNED_BYTE, byte_data_);
|
||||
} else {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width_, height_, 0, GL_RGB,
|
||||
GL_UNSIGNED_BYTE, byte_data_);
|
||||
}
|
||||
util::CheckGlError("glTexImage2D");
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
fclose(file);
|
||||
delete[] row_pointers;
|
||||
delete[] byte_data_;
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
GLuint Texture::GetTextureID() const { return texture_id_; }
|
||||
|
||||
Texture::~Texture() {
|
||||
if (byte_data_ != NULL) {
|
||||
delete[] byte_data_;
|
||||
}
|
||||
byte_data_ = NULL;
|
||||
}
|
||||
|
||||
} // namespace tango_gl
|
||||
38
app/android/jni/tango-gl/trace.cpp
Normal file
38
app/android/jni/tango-gl/trace.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "tango-gl/trace.h"
|
||||
|
||||
namespace tango_gl {
|
||||
|
||||
static const int kMaxTraceLength = 5000;
|
||||
static const float kDistanceCheck = 0.05f;
|
||||
|
||||
Trace::Trace() : Line(3.0f, GL_LINE_STRIP) { SetShader(); }
|
||||
|
||||
void Trace::UpdateVertexArray(const glm::vec3& v) {
|
||||
if (vec_vertices_.size() == 0) {
|
||||
vec_vertices_.push_back(v);
|
||||
} else {
|
||||
float dist = glm::distance(vec_vertices_[vec_vertices_.size() - 1], v);
|
||||
if (dist >= kDistanceCheck) {
|
||||
vec_vertices_.push_back(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Trace::ClearVertexArray() { vec_vertices_.clear(); }
|
||||
} // namespace tango_gl
|
||||
92
app/android/jni/tango-gl/transform.cpp
Normal file
92
app/android/jni/tango-gl/transform.cpp
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "tango-gl/transform.h"
|
||||
#include "tango-gl/util.h"
|
||||
|
||||
#define nullptr 0
|
||||
|
||||
namespace tango_gl {
|
||||
|
||||
Transform::Transform()
|
||||
: parent_(nullptr),
|
||||
position_(0.0f, 0.0f, 0.0f),
|
||||
rotation_(1.0f, 0.0f, 0.0f, 0.0f),
|
||||
scale_(1.0f, 1.0f, 1.0f) {
|
||||
}
|
||||
|
||||
Transform::~Transform() {
|
||||
// Objects are not responsible for deleting their parents.
|
||||
}
|
||||
|
||||
void Transform::SetPosition(const glm::vec3& position) {
|
||||
position_ = position;
|
||||
}
|
||||
|
||||
glm::vec3 Transform::GetPosition() const {
|
||||
return position_;
|
||||
}
|
||||
|
||||
void Transform::SetRotation(const glm::quat& rotation) {
|
||||
rotation_ = rotation;
|
||||
}
|
||||
|
||||
glm::quat Transform::GetRotation() const {
|
||||
return rotation_;
|
||||
}
|
||||
|
||||
void Transform::SetScale(const glm::vec3& scale) {
|
||||
scale_ = scale;
|
||||
}
|
||||
|
||||
glm::vec3 Transform::GetScale() const {
|
||||
return scale_;
|
||||
}
|
||||
|
||||
void Transform::Translate(const glm::vec3& translation) {
|
||||
position_ += translation;
|
||||
}
|
||||
|
||||
void Transform::SetTransformationMatrix(const glm::mat4& transform_mat) {
|
||||
util::DecomposeMatrix(transform_mat, position_, rotation_, scale_);
|
||||
}
|
||||
|
||||
glm::mat4 Transform::GetTransformationMatrix() const {
|
||||
glm::mat4 trans_mat = glm::scale(glm::mat4_cast(rotation_), scale_);
|
||||
trans_mat[3][0] = position_.x;
|
||||
trans_mat[3][1] = position_.y;
|
||||
trans_mat[3][2] = position_.z;
|
||||
glm::mat4 parent_mat = glm::mat4(1.0f);
|
||||
if (parent_ != NULL) {
|
||||
parent_mat = parent_->GetTransformationMatrix();
|
||||
trans_mat = parent_mat * trans_mat;
|
||||
}
|
||||
return trans_mat;
|
||||
}
|
||||
|
||||
void Transform::SetParent(Transform* transform) {
|
||||
parent_ = transform;
|
||||
}
|
||||
|
||||
const Transform* Transform::GetParent() const {
|
||||
return parent_;
|
||||
}
|
||||
|
||||
Transform* Transform::GetParent() {
|
||||
return parent_;
|
||||
}
|
||||
|
||||
} // namespace tango_gl
|
||||
35
app/android/jni/tango-gl/triangle.cpp
Normal file
35
app/android/jni/tango-gl/triangle.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "tango-gl/triangle.h"
|
||||
|
||||
namespace tango_gl {
|
||||
|
||||
static const GLfloat const_vertices[]
|
||||
= {-0.15f, 0.0f, 0.0f, 0.15f, 0.0f, 0.0f, 0.0f, 0.0f, -0.2f};
|
||||
|
||||
static const GLushort const_indices[] = {0, 1, 2};
|
||||
|
||||
Triangle::Triangle() {
|
||||
SetShader();
|
||||
std::vector<GLfloat> vertices(
|
||||
const_vertices,
|
||||
const_vertices + sizeof(const_vertices) / sizeof(GLfloat));
|
||||
std::vector<GLushort> indices(
|
||||
const_indices, const_indices + sizeof(const_indices) / sizeof(GLushort));
|
||||
SetVertices(vertices, indices);
|
||||
}
|
||||
} // namespace tango_gl
|
||||
241
app/android/jni/tango-gl/util.cpp
Normal file
241
app/android/jni/tango-gl/util.cpp
Normal file
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "tango-gl/util.h"
|
||||
#include <rtabmap/utilite/ULogger.h>
|
||||
|
||||
namespace tango_gl {
|
||||
|
||||
namespace {
|
||||
int NormalizedColorCameraRotation(int camera_rotation) {
|
||||
int camera_n = 0;
|
||||
switch (camera_rotation) {
|
||||
case 90:
|
||||
camera_n = 1;
|
||||
break;
|
||||
case 180:
|
||||
camera_n = 2;
|
||||
break;
|
||||
case 270:
|
||||
camera_n = 3;
|
||||
break;
|
||||
default:
|
||||
camera_n = 0;
|
||||
break;
|
||||
}
|
||||
return camera_n;
|
||||
}
|
||||
} // annonymous namespace
|
||||
|
||||
void util::CheckGlError(const char* operation) {
|
||||
for (GLint error = glGetError(); error; error = glGetError()) {
|
||||
LOGE("after %s() glError (0x%x)\n", operation, error);
|
||||
}
|
||||
}
|
||||
|
||||
// Convenience function used in CreateProgram below.
|
||||
static GLuint LoadShader(GLenum shader_type, const char* shader_source) {
|
||||
GLuint shader = glCreateShader(shader_type);
|
||||
if (shader) {
|
||||
glShaderSource(shader, 1, &shader_source, NULL);
|
||||
glCompileShader(shader);
|
||||
GLint compiled = 0;
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
|
||||
if (!compiled) {
|
||||
GLint info_len = 0;
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_len);
|
||||
if (info_len) {
|
||||
char* buf = (char*) malloc(info_len);
|
||||
if (buf) {
|
||||
glGetShaderInfoLog(shader, info_len, NULL, buf);
|
||||
LOGE("Could not compile shader %d:\n%s\n", shader_type, buf);
|
||||
free(buf);
|
||||
}
|
||||
glDeleteShader(shader);
|
||||
shader = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return shader;
|
||||
}
|
||||
|
||||
GLuint util::CreateProgram(const char* vertex_source,
|
||||
const char* fragment_source) {
|
||||
GLuint vertexShader = LoadShader(GL_VERTEX_SHADER, vertex_source);
|
||||
if (!vertexShader) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLuint fragment_shader = LoadShader(GL_FRAGMENT_SHADER, fragment_source);
|
||||
if (!fragment_shader) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
GLuint program = glCreateProgram();
|
||||
if (program) {
|
||||
glAttachShader(program, vertexShader);
|
||||
CheckGlError("glAttachShader");
|
||||
glAttachShader(program, fragment_shader);
|
||||
CheckGlError("glAttachShader");
|
||||
glLinkProgram(program);
|
||||
GLint link_status = GL_FALSE;
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &link_status);
|
||||
if (link_status != GL_TRUE) {
|
||||
GLint buf_length = 0;
|
||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &buf_length);
|
||||
if (buf_length) {
|
||||
char* buf = (char*) malloc(buf_length);
|
||||
if (buf) {
|
||||
glGetProgramInfoLog(program, buf_length, NULL, buf);
|
||||
LOGE("Could not link program:\n%s\n", buf);
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
glDeleteProgram(program);
|
||||
program = 0;
|
||||
}
|
||||
}
|
||||
CheckGlError("CreateProgram");
|
||||
return program;
|
||||
}
|
||||
|
||||
void util::DecomposeMatrix (const glm::mat4& transform_mat,
|
||||
glm::vec3& translation,
|
||||
glm::quat& rotation,
|
||||
glm::vec3& scale) {
|
||||
float scale_x = glm::length( glm::vec3( transform_mat[0][0], transform_mat[1][0], transform_mat[2][0] ) );
|
||||
float scale_y = glm::length( glm::vec3( transform_mat[0][1], transform_mat[1][1], transform_mat[2][1] ) );
|
||||
float scale_z = glm::length( glm::vec3( transform_mat[0][2], transform_mat[1][2], transform_mat[2][2] ) );
|
||||
|
||||
|
||||
float determinant = glm::determinant( transform_mat );
|
||||
if( determinant < 0.0 )
|
||||
scale_x = -scale_x;
|
||||
|
||||
translation.x = transform_mat[3][0];
|
||||
translation.y = transform_mat[3][1];
|
||||
translation.z = transform_mat[3][2];
|
||||
|
||||
float inverse_scale_x = 1.0 / scale_x;
|
||||
float inverse_scale_y = 1.0 / scale_y;
|
||||
float inverse_scale_z = 1.0 / scale_z;
|
||||
|
||||
glm::mat4 transform_unscaled = transform_mat;
|
||||
|
||||
transform_unscaled[0][0] *= inverse_scale_x;
|
||||
transform_unscaled[1][0] *= inverse_scale_x;
|
||||
transform_unscaled[2][0] *= inverse_scale_x;
|
||||
|
||||
transform_unscaled[0][1] *= inverse_scale_y;
|
||||
transform_unscaled[1][1] *= inverse_scale_y;
|
||||
transform_unscaled[2][1] *= inverse_scale_y;
|
||||
|
||||
transform_unscaled[0][2] *= inverse_scale_z;
|
||||
transform_unscaled[1][2] *= inverse_scale_z;
|
||||
transform_unscaled[2][2] *= inverse_scale_z;
|
||||
|
||||
rotation = glm::quat_cast( transform_mat );
|
||||
|
||||
scale.x = scale_x;
|
||||
scale.y = scale_y;
|
||||
scale.z = scale_z;
|
||||
}
|
||||
|
||||
glm::vec3 util::GetColumnFromMatrix(const glm::mat4& mat, const int col) {
|
||||
return glm::vec3(mat[col][0], mat[col][1], mat[col][2]);
|
||||
}
|
||||
|
||||
glm::vec3 util::GetTranslationFromMatrix(const glm::mat4& mat) {
|
||||
return glm::vec3(mat[3][0], mat[3][1], mat[3][2]);
|
||||
}
|
||||
|
||||
float util::Clamp(float value, float min, float max) {
|
||||
return value < min ? min : (value > max ? max : value);
|
||||
}
|
||||
|
||||
// Print out a column major matrix.
|
||||
void util::PrintMatrix(const glm::mat4& matrix) {
|
||||
int i;
|
||||
for (i = 0; i < 4; i++) {
|
||||
LOGI("[ %f, %f, %f, %f ]", matrix[0][i], matrix[1][i], matrix[2][i],
|
||||
matrix[3][i]);
|
||||
}
|
||||
LOGI(" ");
|
||||
}
|
||||
|
||||
void util::PrintVector(const glm::vec3& vector) {
|
||||
LOGI("[ %f, %f, %f ]", vector[0], vector[1], vector[2]);
|
||||
LOGI(" ");
|
||||
}
|
||||
|
||||
void util::PrintQuaternion(const glm::quat& quat) {
|
||||
LOGI("[ %f, %f, %f, %f ]", quat[0], quat[1], quat[2], quat[3]);
|
||||
LOGI(" ");
|
||||
}
|
||||
|
||||
glm::vec3 util::LerpVector(const glm::vec3& x, const glm::vec3& y, float a) {
|
||||
return x * (1.0f - a) + y * a;
|
||||
}
|
||||
|
||||
float util::DistanceSquared(const glm::vec3& v1, const glm::vec3& v2) {
|
||||
glm::vec3 delta = v2 - v1;
|
||||
return glm::dot(delta, delta);
|
||||
}
|
||||
|
||||
bool util::SegmentAABBIntersect(const glm::vec3& aabb_min,
|
||||
const glm::vec3& aabb_max,
|
||||
const glm::vec3& start,
|
||||
const glm::vec3& end) {
|
||||
float tmin, tmax, tymin, tymax, tzmin, tzmax;
|
||||
glm::vec3 direction = end - start;
|
||||
if (direction.x >= 0) {
|
||||
tmin = (aabb_min.x - start.x) / direction.x;
|
||||
tmax = (aabb_max.x - start.x) / direction.x;
|
||||
} else {
|
||||
tmin = (aabb_max.x - start.x) / direction.x;
|
||||
tmax = (aabb_min.x - start.x) / direction.x;
|
||||
}
|
||||
if (direction.y >= 0) {
|
||||
tymin = (aabb_min.y - start.y) / direction.y;
|
||||
tymax = (aabb_max.y - start.y) / direction.y;
|
||||
} else {
|
||||
tymin = (aabb_max.y - start.y) / direction.y;
|
||||
tymax = (aabb_min.y - start.y) / direction.y;
|
||||
}
|
||||
if ((tmin > tymax) || (tymin > tmax)) return false;
|
||||
|
||||
if (tymin > tmin) tmin = tymin;
|
||||
if (tymax < tmax) tmax = tymax;
|
||||
if (direction.z >= 0) {
|
||||
tzmin = (aabb_min.z - start.z) / direction.z;
|
||||
tzmax = (aabb_max.z - start.z) / direction.z;
|
||||
} else {
|
||||
tzmin = (aabb_max.z - start.z) / direction.z;
|
||||
tzmax = (aabb_min.z - start.z) / direction.z;
|
||||
}
|
||||
if ((tmin > tzmax) || (tzmin > tmax)) return false;
|
||||
|
||||
if (tzmin > tmin) tmin = tzmin;
|
||||
if (tzmax < tmax) tmax = tzmax;
|
||||
// Use the full length of the segment.
|
||||
return ((tmin < 1.0f) && (tmax > 0));
|
||||
}
|
||||
|
||||
glm::vec3 util::ApplyTransform(const glm::mat4& mat, const glm::vec3& vec) {
|
||||
return glm::vec3(mat * glm::vec4(vec, 1.0f));
|
||||
}
|
||||
|
||||
} // namespace tango_gl
|
||||
121
app/android/jni/tango-gl/video_overlay.cpp
Normal file
121
app/android/jni/tango-gl/video_overlay.cpp
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright 2014 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "tango-gl/video_overlay.h"
|
||||
#include "tango-gl/shaders.h"
|
||||
|
||||
namespace tango_gl {
|
||||
|
||||
static const GLfloat kVertices[] =
|
||||
{-1.0, 1.0, 0.0,
|
||||
-1.0, -1.0, 0.0,
|
||||
1.0, 1.0, 0.0,
|
||||
1.0, -1.0, 0.0};
|
||||
|
||||
static const GLushort kIndices[] =
|
||||
{0, 1, 2, 2, 1, 3};
|
||||
|
||||
static const GLfloat kTextureCoords[] =
|
||||
{0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0};
|
||||
|
||||
VideoOverlay::VideoOverlay() {
|
||||
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
|
||||
shader_program_ =
|
||||
util::CreateProgram(shaders::GetVideoOverlayVertexShader().c_str(),
|
||||
shaders::GetVideoOverlayFragmentShader().c_str());
|
||||
if (!shader_program_) {
|
||||
LOGE("Could not create program.");
|
||||
}
|
||||
|
||||
glGenTextures(1, &texture_id_);
|
||||
glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_id_);
|
||||
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
uniform_texture_ = glGetUniformLocation(shader_program_, "texture");
|
||||
|
||||
glGenBuffers(3, vertex_buffers_);
|
||||
// Allocate vertices buffer.
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffers_[0]);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * 4, kVertices,
|
||||
GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
// Allocate triangle indices buffer.
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vertex_buffers_[1]);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * 6, kIndices,
|
||||
GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
|
||||
// Allocate texture coordinates buufer.
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffers_[2]);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 2 * 4, kTextureCoords,
|
||||
GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
// Assign the vertices attribute data.
|
||||
attrib_vertices_ = glGetAttribLocation(shader_program_, "vertex");
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffers_[0]);
|
||||
glEnableVertexAttribArray(attrib_vertices_);
|
||||
glVertexAttribPointer(attrib_vertices_, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
// Assign the texture coordinates attribute data.
|
||||
attrib_texture_coords_ = glGetAttribLocation(shader_program_, "textureCoords");
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffers_[2]);
|
||||
glEnableVertexAttribArray(attrib_texture_coords_);
|
||||
glVertexAttribPointer(attrib_texture_coords_, 2, GL_FLOAT, GL_FALSE, 0,
|
||||
nullptr);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
uniform_mvp_mat_ = glGetUniformLocation(shader_program_, "mvp");
|
||||
}
|
||||
|
||||
void VideoOverlay::Render(const glm::mat4& projection_mat,
|
||||
const glm::mat4& view_mat) const {
|
||||
glUseProgram(shader_program_);
|
||||
|
||||
glUniform1i(uniform_texture_, 0);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture_id_);
|
||||
|
||||
glm::mat4 model_mat = GetTransformationMatrix();
|
||||
glm::mat4 mvp_mat = projection_mat * view_mat * model_mat;
|
||||
glUniformMatrix4fv(uniform_mvp_mat_, 1, GL_FALSE, glm::value_ptr(mvp_mat));
|
||||
|
||||
// Bind vertices buffer.
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffers_[0]);
|
||||
glEnableVertexAttribArray(attrib_vertices_);
|
||||
glVertexAttribPointer(attrib_vertices_, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
// Bind texture coordinates buffer.
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffers_[2]);
|
||||
glEnableVertexAttribArray(attrib_texture_coords_);
|
||||
glVertexAttribPointer(attrib_texture_coords_, 2, GL_FLOAT, GL_FALSE, 0,
|
||||
nullptr);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
// Bind element array buffer.
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vertex_buffers_[1]);
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
|
||||
util::CheckGlError("glDrawElements");
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
|
||||
glUseProgram(0);
|
||||
util::CheckGlError("glUseProgram()");
|
||||
}
|
||||
|
||||
} // namespace tango_gl
|
||||
31
app/android/jni/third-party/include/glm/common.hpp
vendored
Normal file
31
app/android/jni/third-party/include/glm/common.hpp
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
/// OpenGL Mathematics (glm.g-truc.net)
|
||||
///
|
||||
/// Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net)
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
/// of this software and associated documentation files (the "Software"), to deal
|
||||
/// in the Software without restriction, including without limitation the rights
|
||||
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
/// copies of the Software, and to permit persons to whom the Software is
|
||||
/// furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// 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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
/// THE SOFTWARE.
|
||||
///
|
||||
/// @ref core
|
||||
/// @file glm/common.hpp
|
||||
/// @date 2013-12-24 / 2013-12-24
|
||||
/// @author Christophe Riccio
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "detail/func_common.hpp"
|
||||
424
app/android/jni/third-party/include/glm/detail/_features.hpp
vendored
Normal file
424
app/android/jni/third-party/include/glm/detail/_features.hpp
vendored
Normal file
@@ -0,0 +1,424 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
/// OpenGL Mathematics (glm.g-truc.net)
|
||||
///
|
||||
/// Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net)
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
/// of this software and associated documentation files (the "Software"), to deal
|
||||
/// in the Software without restriction, including without limitation the rights
|
||||
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
/// copies of the Software, and to permit persons to whom the Software is
|
||||
/// furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// 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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
/// THE SOFTWARE.
|
||||
///
|
||||
/// @ref core
|
||||
/// @file glm/core/_features.hpp
|
||||
/// @date 2013-02-20 / 2013-02-20
|
||||
/// @author Christophe Riccio
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
// #define GLM_CXX98_EXCEPTIONS
|
||||
// #define GLM_CXX98_RTTI
|
||||
|
||||
// #define GLM_CXX11_RVALUE_REFERENCES
|
||||
// Rvalue references - GCC 4.3
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2118.html
|
||||
|
||||
// GLM_CXX11_TRAILING_RETURN
|
||||
// Rvalue references for *this - GCC not supported
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2439.htm
|
||||
|
||||
// GLM_CXX11_NONSTATIC_MEMBER_INIT
|
||||
// Initialization of class objects by rvalues - GCC any
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1610.html
|
||||
|
||||
// GLM_CXX11_NONSTATIC_MEMBER_INIT
|
||||
// Non-static data member initializers - GCC 4.7
|
||||
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2756.htm
|
||||
|
||||
// #define GLM_CXX11_VARIADIC_TEMPLATE
|
||||
// Variadic templates - GCC 4.3
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2242.pdf
|
||||
|
||||
//
|
||||
// Extending variadic template template parameters - GCC 4.4
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2555.pdf
|
||||
|
||||
// #define GLM_CXX11_GENERALIZED_INITIALIZERS
|
||||
// Initializer lists - GCC 4.4
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2672.htm
|
||||
|
||||
// #define GLM_CXX11_STATIC_ASSERT
|
||||
// Static assertions - GCC 4.3
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1720.html
|
||||
|
||||
// #define GLM_CXX11_AUTO_TYPE
|
||||
// auto-typed variables - GCC 4.4
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1984.pdf
|
||||
|
||||
// #define GLM_CXX11_AUTO_TYPE
|
||||
// Multi-declarator auto - GCC 4.4
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1737.pdf
|
||||
|
||||
// #define GLM_CXX11_AUTO_TYPE
|
||||
// Removal of auto as a storage-class specifier - GCC 4.4
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2546.htm
|
||||
|
||||
// #define GLM_CXX11_AUTO_TYPE
|
||||
// New function declarator syntax - GCC 4.4
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2541.htm
|
||||
|
||||
// #define GLM_CXX11_LAMBDAS
|
||||
// New wording for C++0x lambdas - GCC 4.5
|
||||
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2927.pdf
|
||||
|
||||
// #define GLM_CXX11_DECLTYPE
|
||||
// Declared type of an expression - GCC 4.3
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2343.pdf
|
||||
|
||||
//
|
||||
// Right angle brackets - GCC 4.3
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html
|
||||
|
||||
//
|
||||
// Default template arguments for function templates DR226 GCC 4.3
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#226
|
||||
|
||||
//
|
||||
// Solving the SFINAE problem for expressions DR339 GCC 4.4
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2634.html
|
||||
|
||||
// #define GLM_CXX11_ALIAS_TEMPLATE
|
||||
// Template aliases N2258 GCC 4.7
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf
|
||||
|
||||
//
|
||||
// Extern templates N1987 Yes
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1987.htm
|
||||
|
||||
// #define GLM_CXX11_NULLPTR
|
||||
// Null pointer constant N2431 GCC 4.6
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2431.pdf
|
||||
|
||||
// #define GLM_CXX11_STRONG_ENUMS
|
||||
// Strongly-typed enums N2347 GCC 4.4
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2347.pdf
|
||||
|
||||
//
|
||||
// Forward declarations for enums N2764 GCC 4.6
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2764.pdf
|
||||
|
||||
//
|
||||
// Generalized attributes N2761 GCC 4.8
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2761.pdf
|
||||
|
||||
//
|
||||
// Generalized constant expressions N2235 GCC 4.6
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2235.pdf
|
||||
|
||||
//
|
||||
// Alignment support N2341 GCC 4.8
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2341.pdf
|
||||
|
||||
// #define GLM_CXX11_DELEGATING_CONSTRUCTORS
|
||||
// Delegating constructors N1986 GCC 4.7
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1986.pdf
|
||||
|
||||
//
|
||||
// Inheriting constructors N2540 GCC 4.8
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2540.htm
|
||||
|
||||
// #define GLM_CXX11_EXPLICIT_CONVERSIONS
|
||||
// Explicit conversion operators N2437 GCC 4.5
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2437.pdf
|
||||
|
||||
//
|
||||
// New character types N2249 GCC 4.4
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2249.html
|
||||
|
||||
//
|
||||
// Unicode string literals N2442 GCC 4.5
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2442.htm
|
||||
|
||||
//
|
||||
// Raw string literals N2442 GCC 4.5
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2442.htm
|
||||
|
||||
//
|
||||
// Universal character name literals N2170 GCC 4.5
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2170.html
|
||||
|
||||
// #define GLM_CXX11_USER_LITERALS
|
||||
// User-defined literals N2765 GCC 4.7
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2765.pdf
|
||||
|
||||
//
|
||||
// Standard Layout Types N2342 GCC 4.5
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2342.htm
|
||||
|
||||
// #define GLM_CXX11_DEFAULTED_FUNCTIONS
|
||||
// #define GLM_CXX11_DELETED_FUNCTIONS
|
||||
// Defaulted and deleted functions N2346 GCC 4.4
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm
|
||||
|
||||
//
|
||||
// Extended friend declarations N1791 GCC 4.7
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1791.pdf
|
||||
|
||||
//
|
||||
// Extending sizeof N2253 GCC 4.4
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2253.html
|
||||
|
||||
// #define GLM_CXX11_INLINE_NAMESPACES
|
||||
// Inline namespaces N2535 GCC 4.4
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2535.htm
|
||||
|
||||
// #define GLM_CXX11_UNRESTRICTED_UNIONS
|
||||
// Unrestricted unions N2544 GCC 4.6
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2544.pdf
|
||||
|
||||
// #define GLM_CXX11_LOCAL_TYPE_TEMPLATE_ARGS
|
||||
// Local and unnamed types as template arguments N2657 GCC 4.5
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm
|
||||
|
||||
// #define GLM_CXX11_RANGE_FOR
|
||||
// Range-based for N2930 GCC 4.6
|
||||
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2930.html
|
||||
|
||||
// #define GLM_CXX11_OVERRIDE_CONTROL
|
||||
// Explicit virtual overrides N2928 N3206 N3272 GCC 4.7
|
||||
// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2928.htm
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3206.htm
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3272.htm
|
||||
|
||||
//
|
||||
// Minimal support for garbage collection and reachability-based leak detection N2670 No
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2670.htm
|
||||
|
||||
// #define GLM_CXX11_NOEXCEPT
|
||||
// Allowing move constructors to throw [noexcept] N3050 GCC 4.6 (core language only)
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3050.html
|
||||
|
||||
//
|
||||
// Defining move special member functions N3053 GCC 4.6
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3053.html
|
||||
|
||||
//
|
||||
// Sequence points N2239 Yes
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2239.html
|
||||
|
||||
//
|
||||
// Atomic operations N2427 GCC 4.4
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2239.html
|
||||
|
||||
//
|
||||
// Strong Compare and Exchange N2748 GCC 4.5
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html
|
||||
|
||||
//
|
||||
// Bidirectional Fences N2752 GCC 4.8
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2752.htm
|
||||
|
||||
//
|
||||
// Memory model N2429 GCC 4.8
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2429.htm
|
||||
|
||||
//
|
||||
// Data-dependency ordering: atomics and memory model N2664 GCC 4.4
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2664.htm
|
||||
|
||||
//
|
||||
// Propagating exceptions N2179 GCC 4.4
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2179.html
|
||||
|
||||
//
|
||||
// Abandoning a process and at_quick_exit N2440 GCC 4.8
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2440.htm
|
||||
|
||||
//
|
||||
// Allow atomics use in signal handlers N2547 Yes
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2547.htm
|
||||
|
||||
//
|
||||
// Thread-local storage N2659 GCC 4.8
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2659.htm
|
||||
|
||||
//
|
||||
// Dynamic initialization and destruction with concurrency N2660 GCC 4.3
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2660.htm
|
||||
|
||||
//
|
||||
// __func__ predefined identifier N2340 GCC 4.3
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2340.htm
|
||||
|
||||
//
|
||||
// C99 preprocessor N1653 GCC 4.3
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1653.htm
|
||||
|
||||
//
|
||||
// long long N1811 GCC 4.3
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1811.pdf
|
||||
|
||||
//
|
||||
// Extended integral types N1988 Yes
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1988.pdf
|
||||
|
||||
#if(GLM_COMPILER & GLM_COMPILER_GCC)
|
||||
|
||||
# if(GLM_COMPILER >= GLM_COMPILER_GCC43)
|
||||
# define GLM_CXX11_STATIC_ASSERT
|
||||
# endif
|
||||
|
||||
#elif(GLM_COMPILER & GLM_COMPILER_CLANG)
|
||||
# if(__has_feature(cxx_exceptions))
|
||||
# define GLM_CXX98_EXCEPTIONS
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_rtti))
|
||||
# define GLM_CXX98_RTTI
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_access_control_sfinae))
|
||||
# define GLM_CXX11_ACCESS_CONTROL_SFINAE
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_alias_templates))
|
||||
# define GLM_CXX11_ALIAS_TEMPLATE
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_alignas))
|
||||
# define GLM_CXX11_ALIGNAS
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_attributes))
|
||||
# define GLM_CXX11_ATTRIBUTES
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_constexpr))
|
||||
# define GLM_CXX11_CONSTEXPR
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_decltype))
|
||||
# define GLM_CXX11_DECLTYPE
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_default_function_template_args))
|
||||
# define GLM_CXX11_DEFAULT_FUNCTION_TEMPLATE_ARGS
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_defaulted_functions))
|
||||
# define GLM_CXX11_DEFAULTED_FUNCTIONS
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_delegating_constructors))
|
||||
# define GLM_CXX11_DELEGATING_CONSTRUCTORS
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_deleted_functions))
|
||||
# define GLM_CXX11_DELETED_FUNCTIONS
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_explicit_conversions))
|
||||
# define GLM_CXX11_EXPLICIT_CONVERSIONS
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_generalized_initializers))
|
||||
# define GLM_CXX11_GENERALIZED_INITIALIZERS
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_implicit_moves))
|
||||
# define GLM_CXX11_IMPLICIT_MOVES
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_inheriting_constructors))
|
||||
# define GLM_CXX11_INHERITING_CONSTRUCTORS
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_inline_namespaces))
|
||||
# define GLM_CXX11_INLINE_NAMESPACES
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_lambdas))
|
||||
# define GLM_CXX11_LAMBDAS
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_local_type_template_args))
|
||||
# define GLM_CXX11_LOCAL_TYPE_TEMPLATE_ARGS
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_noexcept))
|
||||
# define GLM_CXX11_NOEXCEPT
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_nonstatic_member_init))
|
||||
# define GLM_CXX11_NONSTATIC_MEMBER_INIT
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_nullptr))
|
||||
# define GLM_CXX11_NULLPTR
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_override_control))
|
||||
# define GLM_CXX11_OVERRIDE_CONTROL
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_reference_qualified_functions))
|
||||
# define GLM_CXX11_REFERENCE_QUALIFIED_FUNCTIONS
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_range_for))
|
||||
# define GLM_CXX11_RANGE_FOR
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_raw_string_literals))
|
||||
# define GLM_CXX11_RAW_STRING_LITERALS
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_rvalue_references))
|
||||
# define GLM_CXX11_RVALUE_REFERENCES
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_static_assert))
|
||||
# define GLM_CXX11_STATIC_ASSERT
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_auto_type))
|
||||
# define GLM_CXX11_AUTO_TYPE
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_strong_enums))
|
||||
# define GLM_CXX11_STRONG_ENUMS
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_trailing_return))
|
||||
# define GLM_CXX11_TRAILING_RETURN
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_unicode_literals))
|
||||
# define GLM_CXX11_UNICODE_LITERALS
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_unrestricted_unions))
|
||||
# define GLM_CXX11_UNRESTRICTED_UNIONS
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_user_literals))
|
||||
# define GLM_CXX11_USER_LITERALS
|
||||
# endif
|
||||
|
||||
# if(__has_feature(cxx_variadic_templates))
|
||||
# define GLM_CXX11_VARIADIC_TEMPLATES
|
||||
# endif
|
||||
|
||||
#endif//(GLM_COMPILER & GLM_COMPILER_CLANG)
|
||||
55
app/android/jni/third-party/include/glm/detail/_fixes.hpp
vendored
Normal file
55
app/android/jni/third-party/include/glm/detail/_fixes.hpp
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
/// OpenGL Mathematics (glm.g-truc.net)
|
||||
///
|
||||
/// Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net)
|
||||
/// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
/// of this software and associated documentation files (the "Software"), to deal
|
||||
/// in the Software without restriction, including without limitation the rights
|
||||
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
/// copies of the Software, and to permit persons to whom the Software is
|
||||
/// furnished to do so, subject to the following conditions:
|
||||
///
|
||||
/// The above copyright notice and this permission notice shall be included in
|
||||
/// all copies or substantial portions of the Software.
|
||||
///
|
||||
/// 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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
/// THE SOFTWARE.
|
||||
///
|
||||
/// @ref core
|
||||
/// @file glm/core/_fixes.hpp
|
||||
/// @date 2011-02-21 / 2011-11-22
|
||||
/// @author Christophe Riccio
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <cmath>
|
||||
|
||||
//! Workaround for compatibility with other libraries
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
|
||||
//! Workaround for compatibility with other libraries
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
|
||||
//! Workaround for Android
|
||||
#ifdef isnan
|
||||
#undef isnan
|
||||
#endif
|
||||
|
||||
//! Workaround for Android
|
||||
#ifdef isinf
|
||||
#undef isinf
|
||||
#endif
|
||||
|
||||
//! Workaround for Chrone Native Client
|
||||
#ifdef log2
|
||||
#undef log2
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user