Compare commits
577 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7bc65421a9 | ||
|
|
736514cf37 | ||
|
|
db0158dae8 | ||
|
|
e706695ed1 | ||
|
|
e8877ffe2d | ||
|
|
300e853646 | ||
|
|
a403279fa6 | ||
|
|
1fd5d9dae6 | ||
|
|
8f6f831d5b | ||
|
|
599077b54c | ||
|
|
9b7414b60c | ||
|
|
78430858fe | ||
|
|
fe8528a963 | ||
|
|
f365cb965b | ||
|
|
2b38cf4c65 | ||
|
|
2e9080a179 | ||
|
|
0a50ee989e | ||
|
|
c9c9103ede | ||
|
|
1ce9e96490 | ||
|
|
1f9c802e10 | ||
|
|
c6fda8385a | ||
|
|
d0664bc119 | ||
|
|
e7ed85ec94 | ||
|
|
5d1d4ff4d6 | ||
|
|
57040ebb22 | ||
|
|
03b018e7f3 | ||
|
|
04ada346b0 | ||
|
|
f53c7723fb | ||
|
|
cd48089318 | ||
|
|
0a6a74c78c | ||
|
|
b40982d579 | ||
|
|
2605633e1e | ||
|
|
6379ab22c9 | ||
|
|
0bf02b75d5 | ||
|
|
2f7e873137 | ||
|
|
bb9e23519d | ||
|
|
c4259b5598 | ||
|
|
acfae2882d | ||
|
|
180eb61620 | ||
|
|
a92bb87cd8 | ||
|
|
2c967b821b | ||
|
|
abe9a9731d | ||
|
|
2837a48001 | ||
|
|
4aef84342d | ||
|
|
9be6153875 | ||
|
|
444640afb7 | ||
|
|
122908587b | ||
|
|
c1654537e2 | ||
|
|
984a172cec | ||
|
|
ee2767875c | ||
|
|
fa0a41e62e | ||
|
|
edaf718281 | ||
|
|
7cd5963d3a | ||
|
|
60f5512c5f | ||
|
|
6b3c1179bc | ||
|
|
d1b9a1b996 | ||
|
|
1bd91e7e94 | ||
|
|
5e2f73c74e | ||
|
|
4a269e37c5 | ||
|
|
3eceaf20a2 | ||
|
|
bbc4f4f21d | ||
|
|
c5ef1d6252 | ||
|
|
a4280881d5 | ||
|
|
8ef4c54712 | ||
|
|
5ebc8c3e1a | ||
|
|
c1a0e61e8e | ||
|
|
cbcb3e95c6 | ||
|
|
fc06298ed4 | ||
|
|
4ca87b188c | ||
|
|
f1f60c3e0d | ||
|
|
76d21b56af | ||
|
|
02a8cffb18 | ||
|
|
d53f7ecd6a | ||
|
|
e297f65d8c | ||
|
|
5356f65040 | ||
|
|
5056abc357 | ||
|
|
46029acd14 | ||
|
|
28e414c9a5 | ||
|
|
29c036d826 | ||
|
|
831a6d9480 | ||
|
|
fb2a95470a | ||
|
|
4d73583f86 | ||
|
|
9a24c4001f | ||
|
|
4c9ae9dd91 | ||
|
|
384d6921f6 | ||
|
|
0ab0e50a4f | ||
|
|
e0a8284fcf | ||
|
|
eafbf699a2 | ||
|
|
4d3f10477a | ||
|
|
9a83805f19 | ||
|
|
6fcc2b579d | ||
|
|
e04a3d7d3a | ||
|
|
34f4c06a5c | ||
|
|
6de36f1e53 | ||
|
|
be61ea2dc8 | ||
|
|
c594d6a07e | ||
|
|
2a9a3b1ac2 | ||
|
|
ee7feff9cc | ||
|
|
02ce911405 | ||
|
|
f12ee8f54c | ||
|
|
81a98c6769 | ||
|
|
e3f626934f | ||
|
|
94ff2ea6b1 | ||
|
|
cc6201b0db | ||
|
|
d079df9ce5 | ||
|
|
6a2c944bbd | ||
|
|
266fea5e6c | ||
|
|
6da3f85362 | ||
|
|
1d58892fed | ||
|
|
ff1b6d28a8 | ||
|
|
ff935e05f2 | ||
|
|
d378f5e4bb | ||
|
|
44eee6550c | ||
|
|
260b8fb672 | ||
|
|
2f240acc43 | ||
|
|
189b528b3d | ||
|
|
2b265d54a1 | ||
|
|
c61d67301f | ||
|
|
5f3d8096f3 | ||
|
|
6e5b05d0b5 | ||
|
|
6bbae681ef | ||
|
|
097fac4cca | ||
|
|
97515b0d7d | ||
|
|
3500101816 | ||
|
|
1cebf51672 | ||
|
|
3b59dff577 | ||
|
|
cd01ad06fd | ||
|
|
84b73a3770 | ||
|
|
662a10e273 | ||
|
|
331332fab0 | ||
|
|
f3572876a1 | ||
|
|
ecce02502e | ||
|
|
c827004821 | ||
|
|
786eee4eb9 | ||
|
|
92d2de5279 | ||
|
|
f4070f3fb5 | ||
|
|
856a6567a1 | ||
|
|
363edb1427 | ||
|
|
c209232950 | ||
|
|
3f9120b129 | ||
|
|
d17875aea1 | ||
|
|
b1f0f905e5 | ||
|
|
c71c7c70d4 | ||
|
|
613ae56cc1 | ||
|
|
6607002939 | ||
|
|
2e40bb46e7 | ||
|
|
b8897a68f9 | ||
|
|
720288c420 | ||
|
|
97651a0ff4 | ||
|
|
84efd4871e | ||
|
|
3125c44ce1 | ||
|
|
d909b38d57 | ||
|
|
5572ef8574 | ||
|
|
3c4192bd0e | ||
|
|
3fc9dc3684 | ||
|
|
85ea5a6b70 | ||
|
|
77891acb92 | ||
|
|
a06e01a196 | ||
|
|
034b6892f4 | ||
|
|
74fe102035 | ||
|
|
25cc554925 | ||
|
|
bd8ea711fd | ||
|
|
c1347e55cb | ||
|
|
afbd6e6606 | ||
|
|
d6c5cb7778 | ||
|
|
43d47745dd | ||
|
|
f0d99070e4 | ||
|
|
6a49d67c6c | ||
|
|
6b7c1b21cb | ||
|
|
b7d1b4ca1a | ||
|
|
8a04d5761b | ||
|
|
8d8729be8e | ||
|
|
d4325de47d | ||
|
|
e29c76465b | ||
|
|
a220407aef | ||
|
|
4df214003e | ||
|
|
182250b9c0 | ||
|
|
59a6758fce | ||
|
|
73aa996444 | ||
|
|
d787a521b5 | ||
|
|
46e52c71e1 | ||
|
|
08769ec35e | ||
|
|
3aa18eafb3 | ||
|
|
8d4a0e5aa9 | ||
|
|
e8183d09c2 | ||
|
|
5f1da1dfc0 | ||
|
|
1dad27a172 | ||
|
|
c1c5776439 | ||
|
|
da418fc7f2 | ||
|
|
fcaae825b7 | ||
|
|
f5ee074674 | ||
|
|
0c787b94b8 | ||
|
|
02f5f07db0 | ||
|
|
a97591a193 | ||
|
|
60d230b380 | ||
|
|
d7cb38e706 | ||
|
|
80485bf520 | ||
|
|
ce00cca6ee | ||
|
|
401bd8ce73 | ||
|
|
c23a7343d4 | ||
|
|
75a24ee41f | ||
|
|
7e9a69df64 | ||
|
|
12bf8d9659 | ||
|
|
d1c8d42bd2 | ||
|
|
c0fe2d1c09 | ||
|
|
812f0d577b | ||
|
|
4a25ba1111 | ||
|
|
0b4f3f76fc | ||
|
|
e7e19a88e6 | ||
|
|
4295eaa311 | ||
|
|
43e78f7a93 | ||
|
|
d627d57bad | ||
|
|
0a305a710a | ||
|
|
ef45d695d0 | ||
|
|
ac50cb69f7 | ||
|
|
9fc6e398c6 | ||
|
|
e06b948343 | ||
|
|
28ca9df5a0 | ||
|
|
c66915209e | ||
|
|
cb4ffe39f4 | ||
|
|
e07f91ce8b | ||
|
|
03fcbfea62 | ||
|
|
f9d05a879a | ||
|
|
8ffc776f1c | ||
|
|
7a8dd52c4c | ||
|
|
ef48cad322 | ||
|
|
c39d692757 | ||
|
|
4c1d8f310a | ||
|
|
1e1542fe16 | ||
|
|
647ac34c8c | ||
|
|
ea34691625 | ||
|
|
4557255ce1 | ||
|
|
4cb951461b | ||
|
|
750dcbb9d8 | ||
|
|
459f70f7b4 | ||
|
|
61748fa7dc | ||
|
|
be032b52c1 | ||
|
|
4388e81e5f | ||
|
|
a36d432b88 | ||
|
|
b3f43eea13 | ||
|
|
71a185d139 | ||
|
|
df3c7e2c1c | ||
|
|
cbc4c75a7e | ||
|
|
e068d8b698 | ||
|
|
06e9a3d31f | ||
|
|
e5ac49f86d | ||
|
|
7fdc63b6ae | ||
|
|
808abdb6d7 | ||
|
|
037982a0ef | ||
|
|
5f86233218 | ||
|
|
8bd73a44c9 | ||
|
|
f1984b19cc | ||
|
|
c2330fe55a | ||
|
|
dc56408d5f | ||
|
|
f5adbbddb8 | ||
|
|
036bfa9b20 | ||
|
|
2d9064d2bf | ||
|
|
6f948c101f | ||
|
|
9c123a59ab | ||
|
|
4006018907 | ||
|
|
02c1e1dc60 | ||
|
|
03d74f1313 | ||
|
|
d2cf5985ac | ||
|
|
debcbb8e5c | ||
|
|
4f2460a23c | ||
|
|
f68dbe1902 | ||
|
|
b9dd62c7d3 | ||
|
|
d589634968 | ||
|
|
dc2b430f34 | ||
|
|
9914eb84a4 | ||
|
|
0a6886e43b | ||
|
|
bcd4b65f7d | ||
|
|
820717df0e | ||
|
|
6178ba4a6b | ||
|
|
6f14c1fa91 | ||
|
|
6a94c77b1e | ||
|
|
c3d6c853ab | ||
|
|
9575a7453e | ||
|
|
cfd9689444 | ||
|
|
c819265597 | ||
|
|
0427787cb7 | ||
|
|
e372cc25f2 | ||
|
|
b98d9dcff3 | ||
|
|
91b08705da | ||
|
|
503abb3c94 | ||
|
|
4b8d98af8c | ||
|
|
ced6c3de1f | ||
|
|
f8ced1170e | ||
|
|
a166fcdcdf | ||
|
|
faac96730a | ||
|
|
4929f11793 | ||
|
|
b1d877e7db | ||
|
|
3f09e62f23 | ||
|
|
03bc9926dd | ||
|
|
e64e8927ce | ||
|
|
0643b9e7dd | ||
|
|
e5ef4e8868 | ||
|
|
032ce5ff83 | ||
|
|
c0d6cd3ac3 | ||
|
|
b63ab2dc19 | ||
|
|
623833a5d6 | ||
|
|
f7eb55f2f5 | ||
|
|
b095e65e28 | ||
|
|
98fd95440f | ||
|
|
5f00e715ea | ||
|
|
64187ebe8a | ||
|
|
1ab127ff03 | ||
|
|
3c09d8784a | ||
|
|
31ec6550ec | ||
|
|
24b88219fa | ||
|
|
5c437d9163 | ||
|
|
09bda8a1dc | ||
|
|
f76084213c | ||
|
|
b8ed546555 | ||
|
|
9553786cd5 | ||
|
|
7ef79ad626 | ||
|
|
0ac2fe02dc | ||
|
|
c994ab9f60 | ||
|
|
600600b9af | ||
|
|
1b870a55e2 | ||
|
|
965e845133 | ||
|
|
7107afbf0f | ||
|
|
cbb809e535 | ||
|
|
c5169a431b | ||
|
|
6b798ec274 | ||
|
|
1cde9b326c | ||
|
|
5d8dad561c | ||
|
|
8933be1ae2 | ||
|
|
6b66b48b1d | ||
|
|
9c23eb6e33 | ||
|
|
baea54a3fc | ||
|
|
4b9ab66ce7 | ||
|
|
ba7ebf5ea6 | ||
|
|
afdc3d068c | ||
|
|
941e81b3aa | ||
|
|
de7075ff8f | ||
|
|
5deed8dc5a | ||
|
|
93f0d0576d | ||
|
|
ec339b0282 | ||
|
|
a67505bbe2 | ||
|
|
8fd1cefcdf | ||
|
|
03f7ac6ef4 | ||
|
|
274e227f49 | ||
|
|
9302a2e711 | ||
|
|
ee9d87b543 | ||
|
|
391cf2487a | ||
|
|
914503a30e | ||
|
|
17b8717557 | ||
|
|
4f49cdbd1e | ||
|
|
24c5cbac68 | ||
|
|
befc1de389 | ||
|
|
45522f24c9 | ||
|
|
1bd0bb9b81 | ||
|
|
4229610f05 | ||
|
|
c062cd9914 | ||
|
|
449a5907d1 | ||
|
|
9130ef5451 | ||
|
|
82fcb656d9 | ||
|
|
a139d7fc01 | ||
|
|
3242fbaf20 | ||
|
|
037a783e07 | ||
|
|
8c714d5a1f | ||
|
|
3fbc4f2915 | ||
|
|
d9f800454c | ||
|
|
f9ee0de07a | ||
|
|
2786d0a9f7 | ||
|
|
491e8032e6 | ||
|
|
ef3f13f5d3 | ||
|
|
bcb5b2d790 | ||
|
|
e29bfc2c86 | ||
|
|
8a34f3c289 | ||
|
|
951802dd73 | ||
|
|
b95d91a65e | ||
|
|
fe94f935f1 | ||
|
|
6b529bb231 | ||
|
|
c2fabbf9d9 | ||
|
|
7d604cd05b | ||
|
|
57f1932744 | ||
|
|
891fb65daa | ||
|
|
f35be05e76 | ||
|
|
bd4a207b37 | ||
|
|
e19dff18c3 | ||
|
|
deee5d2815 | ||
|
|
53f5fd91b7 | ||
|
|
0969cec45d | ||
|
|
ded542a543 | ||
|
|
385a17b8a5 | ||
|
|
0a0588aec8 | ||
|
|
9af62251b6 | ||
|
|
819878a1da | ||
|
|
e7364cdcb3 | ||
|
|
e5bfe81d0c | ||
|
|
c4eb790065 | ||
|
|
ac56efcd95 | ||
|
|
9fcb8ccb9e | ||
|
|
67a936d845 | ||
|
|
d11f3f7d5a | ||
|
|
625c4d8968 | ||
|
|
239b933d5e | ||
|
|
3161f6a8f1 | ||
|
|
d2bff95c90 | ||
|
|
a0e7c26a63 | ||
|
|
02de3f2e2a | ||
|
|
5bfa9633d2 | ||
|
|
0e7bb53c07 | ||
|
|
759109d478 | ||
|
|
ff5ecb17ea | ||
|
|
83ba56d3e7 | ||
|
|
54d5af6edf | ||
|
|
2d398c2398 | ||
|
|
38fbe47ced | ||
|
|
cf070c6bc7 | ||
|
|
3c577b6191 | ||
|
|
acb2da7759 | ||
|
|
a0c2edd1a2 | ||
|
|
ad555d897d | ||
|
|
4a6e62070b | ||
|
|
0c081d4295 | ||
|
|
04ff2fb806 | ||
|
|
4fb9ee4470 | ||
|
|
3d2734b163 | ||
|
|
c4a12fe48a | ||
|
|
40b8667aef | ||
|
|
cb9578327b | ||
|
|
7b0a8cf2c2 | ||
|
|
4197afba49 | ||
|
|
495fb14b9c | ||
|
|
4de1b0de2d | ||
|
|
abcf4010dd | ||
|
|
65928612b1 | ||
|
|
a33c85bdd4 | ||
|
|
3ec3f222c5 | ||
|
|
e9a43e7344 | ||
|
|
fc835aebc6 | ||
|
|
a3504bd9b6 | ||
|
|
7c604623e6 | ||
|
|
3d3f19aa71 | ||
|
|
f066c925ba | ||
|
|
00f4b45df6 | ||
|
|
07140cf2fa | ||
|
|
994fdf4e1d | ||
|
|
50b50d65e3 | ||
|
|
28acd0fa6a | ||
|
|
0b91f3d785 | ||
|
|
1bb18f5f0a | ||
|
|
2e1d88caae | ||
|
|
a59f4dd3fc | ||
|
|
0aaa985649 | ||
|
|
46b356cb2c | ||
|
|
a20ae75d11 | ||
|
|
8d78b1f2e1 | ||
|
|
9030abaa89 | ||
|
|
e8b16d600e | ||
|
|
24121a4734 | ||
|
|
6eabe0491c | ||
|
|
20b0972130 | ||
|
|
98da09b247 | ||
|
|
cc13420e31 | ||
|
|
29564f8eae | ||
|
|
c15db68a5b | ||
|
|
fd55da0319 | ||
|
|
240d9d0919 | ||
|
|
3452fb3e56 | ||
|
|
41634a301e | ||
|
|
cf75b11cba | ||
|
|
81bba4644a | ||
|
|
35eb8e7be1 | ||
|
|
f7e92b0ee3 | ||
|
|
1e58fd4842 | ||
|
|
fa7ad8d867 | ||
|
|
834b774128 | ||
|
|
eb40fa753f | ||
|
|
dc36b228d6 | ||
|
|
11e3eff009 | ||
|
|
52abe75cfd | ||
|
|
8065d18f54 | ||
|
|
1b3684933d | ||
|
|
e657921b5a | ||
|
|
91ce5c785b | ||
|
|
676b0542c4 | ||
|
|
dced766999 | ||
|
|
eb0b5d16bf | ||
|
|
2845f37ac7 | ||
|
|
922ce83f48 | ||
|
|
7445d80202 | ||
|
|
4d6f3ad392 | ||
|
|
c4ac8a9f06 | ||
|
|
b554a68186 | ||
|
|
b7ad20249d | ||
|
|
65f4b600bc | ||
|
|
03945b88c8 | ||
|
|
24583332a2 | ||
|
|
5aa0eb9f9d | ||
|
|
d9a6e2e649 | ||
|
|
ce26801a91 | ||
|
|
7fd5b65f3b | ||
|
|
cb823b16a1 | ||
|
|
61b1542468 | ||
|
|
d740378277 | ||
|
|
0815adf722 | ||
|
|
ef1eacf22e | ||
|
|
fc896f81f0 | ||
|
|
884d5c1b87 | ||
|
|
627186abc8 | ||
|
|
30b0f39a36 | ||
|
|
c3c2a732cd | ||
|
|
5cc8ebd3e1 | ||
|
|
9ceb3b016c | ||
|
|
76e18475d3 | ||
|
|
2964e99175 | ||
|
|
1189c9e294 | ||
|
|
50799f3760 | ||
|
|
4b580b6eb1 | ||
|
|
8d6e794486 | ||
|
|
0bd41e877e | ||
|
|
ecc3e73967 | ||
|
|
464b4c24f9 | ||
|
|
7fa2053c55 | ||
|
|
cb7f81ccd6 | ||
|
|
32367516e8 | ||
|
|
6227496478 | ||
|
|
74aa7d3c87 | ||
|
|
bc107e7def | ||
|
|
09e05ae00d | ||
|
|
1709a55606 | ||
|
|
1921536f90 | ||
|
|
1a9334e818 | ||
|
|
bc6acd5c5a | ||
|
|
3a15756c78 | ||
|
|
f1fd96983b | ||
|
|
58b4455979 | ||
|
|
ea1dede19c | ||
|
|
1f000bd10d | ||
|
|
ce2c49217f | ||
|
|
20ea3381fa | ||
|
|
ec9640695c | ||
|
|
f2ed3480d8 | ||
|
|
5d9384fca7 | ||
|
|
22d16c1910 | ||
|
|
7aa6fccd7c | ||
|
|
adbd54f4f8 | ||
|
|
9d54261f18 | ||
|
|
a97757c9ae | ||
|
|
7c79d9f89d | ||
|
|
20dadf06f1 | ||
|
|
b3a4788e56 | ||
|
|
811e7c59cf | ||
|
|
be22360903 | ||
|
|
2b68665cd8 | ||
|
|
6297ef9193 | ||
|
|
68e99240d0 | ||
|
|
bf0914f813 | ||
|
|
7bf04e1f71 | ||
|
|
939f3b975c | ||
|
|
e247ffad9b | ||
|
|
fb29ae9fa5 | ||
|
|
706a685ca6 | ||
|
|
4ad947f0ad | ||
|
|
a1939189ea | ||
|
|
fe49c1eb82 | ||
|
|
4d18c0d61c | ||
|
|
6fa8f48be5 | ||
|
|
ba32cef717 | ||
|
|
e6d3d26c6b | ||
|
|
180cf24b58 | ||
|
|
0f9cee0b83 | ||
|
|
317c82711b | ||
|
|
3f32146849 | ||
|
|
9da69dac46 | ||
|
|
1516b135fd | ||
|
|
06538145b5 | ||
|
|
ec486b888c | ||
|
|
7b7d63a91f | ||
|
|
466629d967 | ||
|
|
c4d0dcf639 | ||
|
|
ad90fa1183 | ||
|
|
ed57d6a40f |
2
.github/workflows/linux-continuous.yml
vendored
2
.github/workflows/linux-continuous.yml
vendored
@@ -10,7 +10,7 @@ on:
|
||||
jobs:
|
||||
build-linux:
|
||||
name: build-linux
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-18.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2.0.0
|
||||
|
||||
10
.github/workflows/presubmit.yml
vendored
10
.github/workflows/presubmit.yml
vendored
@@ -1,6 +1,12 @@
|
||||
name: Presubmit
|
||||
|
||||
on: [pull_request]
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
build-desktop:
|
||||
@@ -9,7 +15,7 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-latest, ubuntu-latest]
|
||||
os: [macos-latest, ubuntu-18.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2.0.0
|
||||
|
||||
18
.github/workflows/release.yml
vendored
18
.github/workflows/release.yml
vendored
@@ -20,7 +20,7 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-latest, ubuntu-latest]
|
||||
os: [macos-latest, ubuntu-18.04]
|
||||
|
||||
steps:
|
||||
- name: Decide Git ref
|
||||
@@ -96,6 +96,20 @@ jobs:
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/android && printf "y" | ./build.sh release
|
||||
- name: Sign sample-gltf-viewer
|
||||
run: |
|
||||
echo "${APK_KEYSTORE_BASE64}" > filament.jks.base64
|
||||
base64 --decode filament.jks.base64 > filament.jks
|
||||
BUILD_TOOLS_VERSION=$(ls ${ANDROID_HOME}/build-tools | sort -V | tail -n 1)
|
||||
APKSIGNER=${ANDROID_HOME}/build-tools/${BUILD_TOOLS_VERSION}/apksigner
|
||||
IN_FILE="out/sample-gltf-viewer-release.apk"
|
||||
OUT_FILE="out/filament-gltf-viewer-${TAG}-android.apk"
|
||||
${APKSIGNER} sign --ks filament.jks --key-pass=pass:${APK_KEYSTORE_PASS} --ks-pass=pass:${APK_KEYSTORE_PASS} --in ${IN_FILE} --out ${OUT_FILE}
|
||||
rm "${IN_FILE}"
|
||||
env:
|
||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||
APK_KEYSTORE_BASE64: ${{ secrets.APK_KEYSTORE_BASE64 }}
|
||||
APK_KEYSTORE_PASS: ${{ secrets.APK_KEYSTORE_PASS }}
|
||||
- name: Upload release assets
|
||||
run: |
|
||||
pip3 install setuptools
|
||||
@@ -107,7 +121,7 @@ jobs:
|
||||
mv out/gltfio-android-lite-release.aar out/gltfio-${TAG}-lite-android.aar
|
||||
mv out/filament-utils-android-release.aar out/filament-utils-${TAG}-android.aar
|
||||
mv out/filament-utils-android-lite-release.aar out/filament-utils-${TAG}-lite-android.aar
|
||||
python3 build/common/upload-assets.py ${TAG} out/*.aar
|
||||
python3 build/common/upload-assets.py ${TAG} out/*.aar out/*.apk
|
||||
env:
|
||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||
GITHUB_API_KEY: ${{ secrets.GITHUB_API_KEY }}
|
||||
|
||||
11
BUILDING.md
11
BUILDING.md
@@ -4,9 +4,9 @@
|
||||
|
||||
To build Filament, you must first install the following tools:
|
||||
|
||||
- CMake 3.10 (or more recent)
|
||||
- CMake 3.19 (or more recent)
|
||||
- clang 7.0 (or more recent)
|
||||
- [ninja 1.8](https://github.com/ninja-build/ninja/wiki/Pre-built-Ninja-packages) (or more recent)
|
||||
- [ninja 1.10](https://github.com/ninja-build/ninja/wiki/Pre-built-Ninja-packages) (or more recent)
|
||||
|
||||
To build the Java based components of the project you can optionally install (recommended):
|
||||
|
||||
@@ -17,9 +17,9 @@ section below.
|
||||
|
||||
To build Filament for Android you must also install the following:
|
||||
|
||||
- Android Studio 4.1.0 or more recent
|
||||
- Android Studio 4.2.0 or more recent
|
||||
- Android SDK
|
||||
- Android NDK "side-by-side" 22.0 or higher
|
||||
- Android NDK "side-by-side" 22.1 or higher
|
||||
|
||||
### Environment variables
|
||||
|
||||
@@ -84,6 +84,7 @@ The following CMake options are boolean options specific to Filament:
|
||||
- `FILAMENT_ENABLE_JAVA`: Compile Java projects: requires a JDK and the JAVA_HOME env var
|
||||
- `FILAMENT_ENABLE_LTO`: Enable link-time optimizations if supported by the compiler
|
||||
- `FILAMENT_BUILD_FILAMAT`: Build filamat and JNI buildings
|
||||
- `FILAMENT_SUPPORTS_OPENGL`: Include the OpenGL backend
|
||||
- `FILAMENT_SUPPORTS_METAL`: Include the Metal backend
|
||||
- `FILAMENT_SUPPORTS_VULKAN`: Include the Vulkan backend
|
||||
- `FILAMENT_INSTALL_BACKEND_TEST`: Install the backend test library so it can be consumed on iOS
|
||||
@@ -375,7 +376,7 @@ same version that our continuous builds use.
|
||||
|
||||
```
|
||||
cd <your chosen parent folder for the emscripten SDK>
|
||||
curl -L https://github.com/emscripten-core/emsdk/archive/2.0.12.zip > emsdk.zip
|
||||
curl -L https://github.com/emscripten-core/emsdk/archive/2.0.23.zip > emsdk.zip
|
||||
unzip emsdk.zip ; mv emsdk-* emsdk ; cd emsdk
|
||||
python ./emsdk.py install latest
|
||||
python ./emsdk.py activate latest
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# ==================================================================================================
|
||||
# CMake
|
||||
# ==================================================================================================
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
cmake_minimum_required(VERSION 3.19)
|
||||
|
||||
# ==================================================================================================
|
||||
# Project declaration
|
||||
@@ -25,6 +25,10 @@ option(FILAMENT_SUPPORTS_XCB "Include XCB support in Linux builds" ON)
|
||||
|
||||
option(FILAMENT_SUPPORTS_XLIB "Include XLIB support in Linux builds" ON)
|
||||
|
||||
set(FILAMENT_NDK_VERSION "" CACHE STRING
|
||||
"Android NDK version or version prefix to be used when building for Android."
|
||||
)
|
||||
|
||||
set(FILAMENT_PER_RENDER_PASS_ARENA_SIZE_IN_MB "2" CACHE STRING
|
||||
"Per render pass arena size. Must be roughly 1 MB larger than FILAMENT_PER_FRAME_COMMANDS_SIZE_IN_MB, default 2."
|
||||
)
|
||||
@@ -299,7 +303,7 @@ endif()
|
||||
|
||||
# On Android RELEASE builds, we disable exceptions and RTTI to save some space (about 75 KiB
|
||||
# saved by -fno-exception and 10 KiB saved by -fno-rtti).
|
||||
if (ANDROID OR WEBGL)
|
||||
if (ANDROID OR IOS OR WEBGL)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-exceptions -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-rtti")
|
||||
endif()
|
||||
|
||||
@@ -365,6 +369,12 @@ if (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebIn
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DTNT_DEV")
|
||||
endif()
|
||||
|
||||
# By default, build with support for OpenGL on all platforms.
|
||||
option(FILAMENT_SUPPORTS_OPENGL "Include the OpenGL backend" ON)
|
||||
if (FILAMENT_SUPPORTS_OPENGL)
|
||||
add_definitions(-DFILAMENT_SUPPORTS_OPENGL)
|
||||
endif()
|
||||
|
||||
# By default, build with Vulkan support on desktop platforms, although clients must request to use
|
||||
# it at run time.
|
||||
if (WIN32 OR WEBGL OR IOS)
|
||||
@@ -400,6 +410,13 @@ else()
|
||||
option(FILAMENT_ENABLE_MATDBG "Enable the material debugger" OFF)
|
||||
endif()
|
||||
|
||||
# Only optimize materials in Release mode (so error message lines match the source code)
|
||||
if (CMAKE_BUILD_TYPE MATCHES Release)
|
||||
option(FILAMENT_DISABLE_MATOPT "Disable material optimizations" OFF)
|
||||
else()
|
||||
option(FILAMENT_DISABLE_MATOPT "Disable material optimizations" ON)
|
||||
endif()
|
||||
|
||||
# ==================================================================================================
|
||||
# Material compilation flags
|
||||
# ==================================================================================================
|
||||
@@ -413,9 +430,9 @@ endif()
|
||||
|
||||
set(MATC_API_FLAGS )
|
||||
|
||||
# TODO: Add a flag to build Filament without support for OpenGL.
|
||||
set(MATC_API_FLAGS ${MATC_API_FLAGS} -a opengl)
|
||||
|
||||
if (FILAMENT_SUPPORTS_OPENGL)
|
||||
set(MATC_API_FLAGS ${MATC_API_FLAGS} -a opengl)
|
||||
endif()
|
||||
if (FILAMENT_SUPPORTS_VULKAN)
|
||||
set(MATC_API_FLAGS ${MATC_API_FLAGS} -a vulkan)
|
||||
endif()
|
||||
@@ -423,8 +440,7 @@ if (FILAMENT_SUPPORTS_METAL)
|
||||
set(MATC_API_FLAGS ${MATC_API_FLAGS} -a metal)
|
||||
endif()
|
||||
|
||||
# Only optimize materials in Release mode (so error message lines match the source code)
|
||||
if (NOT CMAKE_BUILD_TYPE MATCHES Release)
|
||||
if (FILAMENT_DISABLE_MATOPT)
|
||||
set(MATC_OPT_FLAGS -g)
|
||||
endif()
|
||||
|
||||
@@ -443,11 +459,15 @@ if (NOT DIST_ARCH)
|
||||
if (CMAKE_OSX_ARCHITECTURES MATCHES ".*;.*")
|
||||
set(DIST_ARCH "universal")
|
||||
else()
|
||||
if (NOT CMAKE_OSX_ARCHITECTURES STREQUAL "")
|
||||
if (NOT "${CMAKE_OSX_ARCHITECTURES}" STREQUAL "")
|
||||
set(DIST_ARCH "${CMAKE_OSX_ARCHITECTURES}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
endif()
|
||||
# On Windows machines, the host processor is set to 'AMD64', which we'll interpret as x86_64.
|
||||
string(TOLOWER "${DIST_ARCH}" DIST_ARCH)
|
||||
string(REPLACE "amd64" "x86_64" DIST_ARCH "${DIST_ARCH}")
|
||||
if (NOT DIST_DIR)
|
||||
set(DIST_DIR "${DIST_ARCH}")
|
||||
endif()
|
||||
@@ -572,23 +592,29 @@ add_subdirectory(${EXTERNAL}/libgtest/tnt)
|
||||
add_subdirectory(${LIBRARIES}/camutils)
|
||||
add_subdirectory(${LIBRARIES}/filabridge)
|
||||
add_subdirectory(${LIBRARIES}/filaflat)
|
||||
add_subdirectory(${LIBRARIES}/filagui)
|
||||
add_subdirectory(${LIBRARIES}/filameshio)
|
||||
add_subdirectory(${LIBRARIES}/geometry)
|
||||
add_subdirectory(${LIBRARIES}/gltfio)
|
||||
add_subdirectory(${LIBRARIES}/ibl)
|
||||
add_subdirectory(${LIBRARIES}/iblprefilter)
|
||||
add_subdirectory(${LIBRARIES}/image)
|
||||
add_subdirectory(${LIBRARIES}/math)
|
||||
add_subdirectory(${LIBRARIES}/mathio)
|
||||
add_subdirectory(${LIBRARIES}/utils)
|
||||
add_subdirectory(${LIBRARIES}/viewer)
|
||||
add_subdirectory(${FILAMENT}/filament)
|
||||
add_subdirectory(${FILAMENT}/shaders)
|
||||
add_subdirectory(${EXTERNAL}/civetweb/tnt)
|
||||
add_subdirectory(${EXTERNAL}/hat-trie/tnt)
|
||||
add_subdirectory(${EXTERNAL}/imgui/tnt)
|
||||
add_subdirectory(${EXTERNAL}/robin-map/tnt)
|
||||
add_subdirectory(${EXTERNAL}/smol-v/tnt)
|
||||
add_subdirectory(${EXTERNAL}/benchmark/tnt)
|
||||
add_subdirectory(${EXTERNAL}/meshoptimizer)
|
||||
add_subdirectory(${EXTERNAL}/cgltf/tnt)
|
||||
add_subdirectory(${EXTERNAL}/draco/tnt)
|
||||
add_subdirectory(${EXTERNAL}/jsmn/tnt)
|
||||
add_subdirectory(${EXTERNAL}/stb/tnt)
|
||||
add_subdirectory(${EXTERNAL}/getopt)
|
||||
|
||||
@@ -602,7 +628,6 @@ if (FILAMENT_BUILD_FILAMAT OR IS_HOST_PLATFORM)
|
||||
|
||||
# the material debugger requires filamat
|
||||
if (FILAMENT_ENABLE_MATDBG OR IS_HOST_PLATFORM)
|
||||
add_subdirectory(${EXTERNAL}/civetweb/tnt)
|
||||
add_subdirectory(${LIBRARIES}/matdbg)
|
||||
endif()
|
||||
endif()
|
||||
@@ -624,11 +649,11 @@ if (WEBGL)
|
||||
endif()
|
||||
|
||||
if (IS_HOST_PLATFORM)
|
||||
add_subdirectory(${LIBRARIES}/bluegl)
|
||||
if (FILAMENT_SUPPORTS_OPENGL)
|
||||
add_subdirectory(${LIBRARIES}/bluegl)
|
||||
endif()
|
||||
add_subdirectory(${LIBRARIES}/filamentapp)
|
||||
add_subdirectory(${LIBRARIES}/filagui)
|
||||
add_subdirectory(${LIBRARIES}/imageio)
|
||||
add_subdirectory(${LIBRARIES}/viewer)
|
||||
|
||||
add_subdirectory(${FILAMENT}/java/filamat)
|
||||
add_subdirectory(${FILAMENT}/java/filament)
|
||||
@@ -638,8 +663,6 @@ if (IS_HOST_PLATFORM)
|
||||
|
||||
add_subdirectory(${EXTERNAL}/astcenc/tnt)
|
||||
add_subdirectory(${EXTERNAL}/etc2comp)
|
||||
add_subdirectory(${EXTERNAL}/imgui/tnt)
|
||||
add_subdirectory(${EXTERNAL}/jsmn/tnt)
|
||||
add_subdirectory(${EXTERNAL}/libassimp/tnt)
|
||||
add_subdirectory(${EXTERNAL}/libpng/tnt)
|
||||
add_subdirectory(${EXTERNAL}/libsdl2/tnt)
|
||||
|
||||
14
README.md
14
README.md
@@ -31,7 +31,7 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.android.filament:filament-android:1.9.12'
|
||||
implementation 'com.google.android.filament:filament-android:1.10.5'
|
||||
}
|
||||
```
|
||||
|
||||
@@ -63,7 +63,7 @@ A much smaller alternative to `filamat-android` that can only generate OpenGL sh
|
||||
iOS projects can use CocoaPods to install the latest release:
|
||||
|
||||
```
|
||||
pod 'Filament', '~> 1.9.12'
|
||||
pod 'Filament', '~> 1.10.5'
|
||||
```
|
||||
|
||||
### Snapshots
|
||||
@@ -131,6 +131,7 @@ Here are a few screenshots of applications that use Filament in production:
|
||||
- Clustered forward renderer
|
||||
- Cook-Torrance microfacet specular BRDF
|
||||
- Lambertian diffuse BRDF
|
||||
- Custom lighting/surface shading
|
||||
- HDR/linear lighting
|
||||
- Metallic workflow
|
||||
- Clear coat
|
||||
@@ -142,6 +143,7 @@ Here are a few screenshots of applications that use Filament in production:
|
||||
- Physically-based camera (shutter speed, sensitivity and aperture)
|
||||
- Physical light units
|
||||
- Point lights, spot lights and directional light
|
||||
- Specular anti-aliasing
|
||||
- Spot and directional light shadows
|
||||
- Cascaded shadows
|
||||
- VSM or PCF shadows
|
||||
@@ -149,13 +151,17 @@ Here are a few screenshots of applications that use Filament in production:
|
||||
- Screen-space ambient occlusion
|
||||
- Screen-space refraction
|
||||
- Global fog
|
||||
- Dynamic resolution
|
||||
|
||||
### Post processing
|
||||
|
||||
- HDR bloom
|
||||
- Depth of field bokeh
|
||||
- Multiple tone mappers: ACES, filmic, etc.
|
||||
- Color grading: white balance, channel mixer, shadows/mid-tones/highlights, ASC CDL,
|
||||
contrast, saturation, etc.
|
||||
- TAA, FXAA, MSAA and specular anti-aliasing
|
||||
- Dynamic resolution
|
||||
- TAA, FXAA, MSAA
|
||||
- Screen-space lens flares
|
||||
|
||||
### glTF 2.0
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ build/common/bump-version.sh $RELEASE
|
||||
Commit changes to main with the title:
|
||||
|
||||
```
|
||||
Bump version to $RELEASE
|
||||
Release Filament $RELEASE
|
||||
```
|
||||
|
||||
Do not push to origin yet.
|
||||
@@ -106,7 +106,9 @@ git push origin release
|
||||
Use the GitHub UI to create a GitHub release corresponding to $RELEASE version.
|
||||
Make sure the target is set to the release branch.
|
||||
|
||||
## 7. Delete the old rc branch.
|
||||
## 7. Delete the old rc branch (optional).
|
||||
|
||||
This step is optional. The old rc branch may be left alive for a few weeks for posterity.
|
||||
|
||||
```
|
||||
git push origin --delete rc/$RELEASE
|
||||
@@ -134,5 +136,5 @@ git push origin main
|
||||
## 10. Push the new rc branch.
|
||||
|
||||
```
|
||||
git push origin rc/$NEXT_RELEASE
|
||||
git push origin -u rc/$NEXT_RELEASE
|
||||
```
|
||||
|
||||
193
RELEASE_NOTES.md
193
RELEASE_NOTES.md
@@ -3,7 +3,198 @@
|
||||
This file contains one line summaries of commits that are worthy of mentioning in release notes.
|
||||
A new header is inserted each time a *tag* is created.
|
||||
|
||||
## Next release (main branch)
|
||||
## v1.10.6 (currently main branch)
|
||||
|
||||
## v1.10.5
|
||||
|
||||
- android: AAR libraries now properly include their ProGuard rules.
|
||||
- engine: User materials can now provide custom lighting/surface shading, please consult
|
||||
the [materials documentation](https://google.github.io/filament/Materials.html) for details.
|
||||
- engine: `Backend::DEFAULT` now selects the most appropriate backend for the platform, rather than
|
||||
always `OPENGL`. On Android the default is `OPENGL`, on Apple platforms the default is `METAL` and
|
||||
on all other platforms that default is `VULKAN`.
|
||||
- engine: Fix a potential memory corruption when using more than 4 render targets.
|
||||
- engine: Fix a possible crash when bloom is enabled.
|
||||
- engine: Fix and refactor support for S3TC + SRGB with OpenGL.
|
||||
- engine: Fix automatic clearing of rendertargets.
|
||||
- engine: Fix imported render target discard and clear flags.
|
||||
- engine: Fix opaque blit with imported render targets.
|
||||
|
||||
## v1.10.4
|
||||
|
||||
- engine: improvements to internal job system.
|
||||
- Vulkan: performance improvements on Mali.
|
||||
- gltfio: improvements to load time for large models.
|
||||
- WebGL: remove bogus stride argument, fix `BindingType` TypeScript definition.
|
||||
|
||||
## v1.10.3
|
||||
|
||||
- android: use `debug.filament.backend` system property to select the desired backend.
|
||||
- engine: fix `LightManager::getFalloff`.
|
||||
- gltfio: fix crash with non-triangles.
|
||||
- macOS: fix main thread checker warnings with OpenGL.
|
||||
- vulkan: fix crash on Windows machines with NVIDIA GPUs.
|
||||
|
||||
## v1.10.2
|
||||
|
||||
- Vulkan: validation and diagnostic improvements
|
||||
- engine: improvements for scenes with many renderables.
|
||||
- gltfio: added support for `KHR_materials_ior`.
|
||||
- java: Add bindings for `IBLPrefilterContext`.
|
||||
- java: add `KTXLoader.getSphericalHarmonics` JNI binding
|
||||
- libimage: fix, respect sRGB option for compressed formats.
|
||||
- sample-gltf-viewer: fix lifetime cycle for RemoteServer.
|
||||
|
||||
## v1.10.1
|
||||
|
||||
- engine: Add `getPlatform` API to Engine.
|
||||
- engine: Add a new cone angles API to `LightManager`.
|
||||
- engine: Attachments of custom RendereTargets are not systematically discarded.
|
||||
- engine: Fix a crash when using custom rendertargets.
|
||||
- engine: New API to duplicate a `MaterialInstance`.
|
||||
- filagui: fix support for custom images in ImGuiHelper.
|
||||
- java: Add bindings for HDRLoader.
|
||||
|
||||
## v1.10.0
|
||||
|
||||
- engine: User materials can now use 9 samplers instead of 8 [⚠️ **Material breakage**].
|
||||
- engine: Remove `populateTangentQuaternions` [⚠️ **API change**].
|
||||
- engine: Deprecate `Stream::Builder::stream(intptr_t)` [⚠️ **API Change**].
|
||||
- engine: Remove deprecated APIs: `Camera::setScaling`, `Engine::destroy(Camera*)`,
|
||||
`Engine::createCamera`, `Renderer::beginFrame(SwapChain*, uint64_t,
|
||||
backend::FrameScheduledCallback, void*)`, and `View::setShadowsEnabled` [⚠️ **API Change**].
|
||||
- engine: Remove `focusDistance` from `View::BloomOptions` [⚠️ **API Change**].
|
||||
- engine: Add a `FILAMENT_SUPPORTS_OPENGL` CMake option to enable/disable OpenGL support.
|
||||
- Vulkan: fixes and improvements for large scenes.
|
||||
- gltfio: fix morphing bugs uncovered by MorphStressTest.
|
||||
- Java: add API for `Texture::Builder::import()`.
|
||||
- WebGL: Fix a potential INVALID_OPERATION.
|
||||
|
||||
## v1.9.25
|
||||
|
||||
- NEW API: Screen-space lens flare effect.
|
||||
- engine: Fix several memory leaks in the GL backend.
|
||||
- Vulkan: General bug fixes and improvements.
|
||||
- Vulkan: Fix some problems seen on Mali devices.
|
||||
- ios: Fix VSM shadows not working.
|
||||
- webgl: Fix black screen seen with some samples.
|
||||
|
||||
## v1.9.24
|
||||
|
||||
- engine: Fix memory leaks in OpenGL driver.
|
||||
- engine: new experimental tone mapper, `EVILS` (name will most likely change).
|
||||
- engine: Improvements to Vulkan backend.
|
||||
- engine: Fix incorrect units documented for `LightManager.getIntensity`.
|
||||
- engine: fix high quality upsampling for SSAO.
|
||||
- engine: implement accurate normal reconstruction for SSAO.
|
||||
- engine: improve LOW and HIGH quality levels for SSAO.
|
||||
- libs: improvements to `libiblprefilter`.
|
||||
- materials: New `quality` property.
|
||||
- samples: Add new gltf-viewer iOS sample.
|
||||
- samples: clear the background in lightbulb sample.
|
||||
|
||||
## v1.9.23
|
||||
|
||||
- Vulkan: various fixes.
|
||||
- android: fix crash seen using VSM with MSAA on Adreno devices.
|
||||
- engine: Add `Engine::getEntityManager()`.
|
||||
- engine: Fix desktop crash seen with some GPU drivers.
|
||||
- engine: improve importance sampling.
|
||||
- gltfio: robustness improvements for Draco meshes.
|
||||
- libs: Add new Transcoder API for C++ clients (part of `libgeometry`).
|
||||
- libs: New `iblprefilter` library to compute IBL pre-integration on the GPU using filament.
|
||||
- materials: Fix documentation for `getNormalizedViewportCoord`.
|
||||
- samples: fix rendertarget sample crash on launch.
|
||||
|
||||
## v1.9.22
|
||||
|
||||
- NEW API: `Renderer::renderStandaloneView()` is a new method that can be used outside of
|
||||
beginFrame/endFrame on Views that have a RenderTarget associated. This can be used as a
|
||||
pseudo-compute API.
|
||||
- Vulkan: bug fixes and improvements.
|
||||
- engine: RenderTarget API can now use MRT.
|
||||
- sample-gltf-viewer: improvements for reading zip files.
|
||||
- sample-gltf-viewer: enable contact-shadows functionality in mobile gltf-viewer.
|
||||
- windows: fix build error in filament_framegraph_test.
|
||||
|
||||
## v1.9.21
|
||||
|
||||
- JavaScript: add missing TextureSampler bindings.
|
||||
- Metal: Fix texture swizzling crash with older Nvidia GPUs.
|
||||
- Vulkan: fix image layout validation error on Android.
|
||||
- android: fix MSAA w/ multisampled_render_to_texture on Mali.
|
||||
- engine: better anisotropic filtering with various drivers.
|
||||
- gltfio: Use BufferObject API, simplify MorphHelper.
|
||||
- gltfio: honor stride in normalizeSkinningWeights.
|
||||
- samples: Add web component demo.
|
||||
|
||||
## v1.9.20
|
||||
|
||||
- Android: Fix VSM.
|
||||
- engine: Introduce BufferObject API.
|
||||
- engine: Add new isTextureSwizzleSupported API on Texture.
|
||||
- engine: Add support to Metal and Vulkan backends for texture swizzling.
|
||||
- engine: Add new DoF settings (native/half res, gather kernel ring counts, CoC radius clamp).
|
||||
- engine: DoF quality and performance improvements.
|
||||
- engine: Fix high-quality upsampling issue with SSAO.
|
||||
- Java: Expose `TransformManager.getParent(int)`.
|
||||
- samples: Add Metal and Vulkan backend support to Suzanne sample.
|
||||
- WebGL: expose fitIntoUnitCube to JS.
|
||||
- WebGL: support for multiple `<canvas>` elements.
|
||||
|
||||
## v1.9.19
|
||||
|
||||
- engine: Fix Metal bug when setGeometryAt is called multiple times.
|
||||
- engine: Improvements to DoF.
|
||||
- engine: Fix RenderTarget NPE when depth is not present.
|
||||
- engine: Improvements to Camera APIs. Move focus distance from DofOptions to Camera.
|
||||
- engine: VSM shadows now support `shadowMultiplier`.
|
||||
- java: Expose severla MaterialInstance APIs (setColorWrite, setDepthWrite, setDepthCulling) that
|
||||
should have been public.
|
||||
- java: fix bug with Texture::setImage buffer size calculation.
|
||||
|
||||
## v1.9.18
|
||||
|
||||
- engine: Fix a DoF bug that caused black dots around the fast tiles.
|
||||
- engine: Minor DoF optimizations.
|
||||
- engine: Fix blanking windows not being drawn into on macOS.
|
||||
- gltfio: Add support for data:// in image URI's.
|
||||
- gltfio: Add internal MorphHelper, enable up to 255 targets.
|
||||
- engine: Fix a hang in JobSystem.
|
||||
- samples: Fix rendertarget sample app.
|
||||
|
||||
## v1.9.17
|
||||
|
||||
- engine: New shift parameter on `Camera` to translate the viewport and emulate a tilt/shift lens.
|
||||
- engine: `Camera::setCustomProjection()` now allows to set a different projection for culling and rendering.
|
||||
- engine: Fixed depth of field rendering with custom projection matrices.
|
||||
- engine: Fix a rare indefinite hang.
|
||||
- gltfio: `SimpleViewer` now exposes more rendering parameters, including `ColorGrading`.
|
||||
- gltfio: Fix tangents when morphing is enabled.
|
||||
- Metal/Vulkan: fix incorrect dominant light shadows rendering.
|
||||
- Fixe some issues with imported rendertargets.
|
||||
|
||||
## v1.9.16
|
||||
|
||||
gltfio: Add ResourceLoader evict API.
|
||||
gltfio: Fix ResourceLoader cache bug.
|
||||
iOS: Disable exceptions to reduce binary size.
|
||||
|
||||
## v1.9.15
|
||||
|
||||
- filamat/matc: fix sporadic crash.
|
||||
|
||||
## v1.9.14
|
||||
|
||||
- Improve bloom/emissive with glTF files.
|
||||
- Publicly expose Exposure API for gltfio.
|
||||
|
||||
## v1.9.13
|
||||
|
||||
- Android: fix "No implementation found" error.
|
||||
- Android: fix compilation error in UbershaderLoader.
|
||||
- engine: computeDataSize now returns correct value for USHORT_565.
|
||||
- Vulkan: various internal improvements.
|
||||
|
||||
## v1.9.12
|
||||
|
||||
|
||||
@@ -64,9 +64,9 @@ buildscript {
|
||||
'minSdk': 19,
|
||||
'targetSdk': 30,
|
||||
'compileSdk': 30,
|
||||
'kotlin': '1.4.30',
|
||||
'kotlin': '1.5.0',
|
||||
'buildTools': '30.0.3',
|
||||
'ndk': '22.0.7026061'
|
||||
'ndk': '22.1.7171670'
|
||||
]
|
||||
|
||||
ext.deps = [
|
||||
@@ -78,7 +78,7 @@ buildscript {
|
||||
]
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.1.2'
|
||||
classpath 'com.android.tools.build:gradle:4.2.0'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}"
|
||||
}
|
||||
|
||||
@@ -116,7 +116,6 @@ buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +137,6 @@ subprojects {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
|
||||
if (!name.startsWith("sample")) {
|
||||
@@ -163,11 +161,13 @@ subprojects {
|
||||
ndk {
|
||||
abiFilters(*rootProject.ext.abis)
|
||||
}
|
||||
}
|
||||
|
||||
consumerProguardFiles '../proguard-rules.pro'
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
version "3.19.0+"
|
||||
path "CMakeLists.txt"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,11 @@ import org.gradle.api.file.FileType
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.logging.LogLevel
|
||||
import org.gradle.api.logging.Logger
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.InputDirectory
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.Optional
|
||||
import org.gradle.api.tasks.OutputDirectory
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.api.tasks.incremental.InputFileDetails
|
||||
@@ -33,24 +36,23 @@ import java.nio.file.Paths
|
||||
|
||||
class TaskWithBinary extends DefaultTask {
|
||||
private final String binaryName
|
||||
private File binaryPath = null
|
||||
private Property<String> binaryPath = null
|
||||
|
||||
TaskWithBinary(String name) {
|
||||
binaryName = name
|
||||
}
|
||||
|
||||
String getBinaryName() {
|
||||
return binaryName
|
||||
}
|
||||
|
||||
File getBinary() {
|
||||
@Input
|
||||
Property<String> getBinary() {
|
||||
if (binaryPath == null) {
|
||||
def tool = ["/bin/${binaryName}.exe", "/bin/${binaryName}"]
|
||||
def fullPath = tool.collect { path ->
|
||||
Paths.get(project.ext.filamentToolsPath.absolutePath, path).toFile()
|
||||
}
|
||||
|
||||
binaryPath = OperatingSystem.current().isWindows() ? fullPath[0] : fullPath[1]
|
||||
binaryPath = project.objects.property(String.class)
|
||||
binaryPath.set(
|
||||
(OperatingSystem.current().isWindows() ? fullPath[0] : fullPath[1]).toString())
|
||||
}
|
||||
return binaryPath
|
||||
}
|
||||
@@ -65,14 +67,6 @@ class LogOutputStream extends ByteArrayOutputStream {
|
||||
this.level = level
|
||||
}
|
||||
|
||||
Logger getLogger() {
|
||||
return logger
|
||||
}
|
||||
|
||||
LogLevel getLevel() {
|
||||
return level
|
||||
}
|
||||
|
||||
@Override
|
||||
void flush() {
|
||||
logger.log(level, toString())
|
||||
@@ -85,10 +79,10 @@ class LogOutputStream extends ByteArrayOutputStream {
|
||||
abstract class MaterialCompiler extends TaskWithBinary {
|
||||
@Incremental
|
||||
@InputDirectory
|
||||
final DirectoryProperty inputDir = project.objects.directoryProperty()
|
||||
abstract DirectoryProperty getInputDir()
|
||||
|
||||
@OutputDirectory
|
||||
final DirectoryProperty outputDir = project.objects.directoryProperty()
|
||||
abstract DirectoryProperty getOutputDir()
|
||||
|
||||
MaterialCompiler() {
|
||||
super("matc")
|
||||
@@ -115,8 +109,8 @@ abstract class MaterialCompiler extends TaskWithBinary {
|
||||
out.write(header)
|
||||
out.flush()
|
||||
|
||||
if (!getBinary().exists()) {
|
||||
throw new GradleException("Could not find ${getBinary()}." +
|
||||
if (!new File(binary.get()).exists()) {
|
||||
throw new GradleException("Could not find ${binary.get()}." +
|
||||
" Ensure Filament has been built/installed before building this app.")
|
||||
}
|
||||
|
||||
@@ -129,7 +123,7 @@ abstract class MaterialCompiler extends TaskWithBinary {
|
||||
project.exec {
|
||||
standardOutput out
|
||||
errorOutput err
|
||||
executable "${getBinary()}"
|
||||
executable "${binary.get()}"
|
||||
args matcArgs
|
||||
}
|
||||
}
|
||||
@@ -143,15 +137,17 @@ abstract class MaterialCompiler extends TaskWithBinary {
|
||||
|
||||
// Custom task to process IBLs using cmgen
|
||||
// This task handles incremental builds
|
||||
class IblGenerator extends TaskWithBinary {
|
||||
String cmgenArgs = null
|
||||
abstract class IblGenerator extends TaskWithBinary {
|
||||
@Input
|
||||
@Optional
|
||||
abstract Property<String> getCmgenArgs()
|
||||
|
||||
@Incremental
|
||||
@InputFile
|
||||
final RegularFileProperty inputFile = project.objects.fileProperty()
|
||||
abstract RegularFileProperty getInputFile()
|
||||
|
||||
@OutputDirectory
|
||||
final DirectoryProperty outputDir = project.objects.directoryProperty()
|
||||
abstract DirectoryProperty getOutputDir()
|
||||
|
||||
IblGenerator() {
|
||||
super("cmgen")
|
||||
@@ -178,23 +174,25 @@ class IblGenerator extends TaskWithBinary {
|
||||
out.write(header)
|
||||
out.flush()
|
||||
|
||||
if (!getBinary().exists()) {
|
||||
throw new GradleException("Could not find ${getBinary()}." +
|
||||
if (!new File(binary.get()).exists()) {
|
||||
throw new GradleException("Could not find ${binary.get()}." +
|
||||
" Ensure Filament has been built/installed before building this app.")
|
||||
}
|
||||
|
||||
def outputPath = outputDir.get().asFile
|
||||
def commandArgs = cmgenArgs.getOrNull()
|
||||
if (commandArgs == null) {
|
||||
commandArgs =
|
||||
'-q -x ' + outputPath + ' --format=rgb32f ' +
|
||||
'--extract-blur=0.08 --extract=' + outputPath.absolutePath
|
||||
}
|
||||
commandArgs = commandArgs + " " + file
|
||||
|
||||
project.exec {
|
||||
standardOutput out
|
||||
if (!cmgenArgs) {
|
||||
cmgenArgs =
|
||||
'-q -x ' + outputPath + ' --format=rgb32f ' +
|
||||
'--extract-blur=0.08 --extract=' + outputPath.absolutePath
|
||||
}
|
||||
cmgenArgs = cmgenArgs + " " + file
|
||||
errorOutput err
|
||||
executable "${getBinary()}"
|
||||
args(cmgenArgs.split())
|
||||
executable "${binary.get()}"
|
||||
args(commandArgs.split())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -207,13 +205,13 @@ class IblGenerator extends TaskWithBinary {
|
||||
|
||||
// Custom task to compile mesh files using filamesh
|
||||
// This task handles incremental builds
|
||||
class MeshCompiler extends TaskWithBinary {
|
||||
abstract class MeshCompiler extends TaskWithBinary {
|
||||
@Incremental
|
||||
@InputFile
|
||||
final RegularFileProperty inputFile = project.objects.fileProperty()
|
||||
abstract RegularFileProperty getInputFile()
|
||||
|
||||
@OutputDirectory
|
||||
final DirectoryProperty outputDir = project.objects.directoryProperty()
|
||||
abstract DirectoryProperty getOutputDir()
|
||||
|
||||
MeshCompiler() {
|
||||
super("filamesh")
|
||||
@@ -240,15 +238,15 @@ class MeshCompiler extends TaskWithBinary {
|
||||
out.write(header)
|
||||
out.flush()
|
||||
|
||||
if (!getBinary().exists()) {
|
||||
throw new GradleException("Could not find ${getBinary()}." +
|
||||
if (!new File(binary.get()).exists()) {
|
||||
throw new GradleException("Could not find ${binary.get()}." +
|
||||
" Ensure Filament has been built/installed before building this app.")
|
||||
}
|
||||
|
||||
project.exec {
|
||||
standardOutput out
|
||||
errorOutput err
|
||||
executable "${getBinary()}"
|
||||
executable "${binary.get()}"
|
||||
args(file, getOutputFile(file))
|
||||
}
|
||||
}
|
||||
@@ -291,8 +289,8 @@ class FilamentToolsPlugin implements Plugin<Project> {
|
||||
enabled =
|
||||
extension.materialInputDir.isPresent() &&
|
||||
extension.materialOutputDir.isPresent()
|
||||
inputDir = extension.materialInputDir.getOrNull()
|
||||
outputDir = extension.materialOutputDir.getOrNull()
|
||||
inputDir.set(extension.materialInputDir.getOrNull())
|
||||
outputDir.set(extension.materialOutputDir.getOrNull())
|
||||
}
|
||||
|
||||
project.preBuild.dependsOn "filamentCompileMaterials"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.6)
|
||||
cmake_minimum_required(VERSION 3.19)
|
||||
project(filamat-android)
|
||||
|
||||
option(FILAMENT_ENABLE_MATDBG "Enables Material debugger" OFF)
|
||||
|
||||
|
||||
@@ -291,6 +291,13 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderFlipUV(
|
||||
builder->flipUV(flipUV);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderCustomSurfaceShading(JNIEnv*,
|
||||
jclass, jlong nativeBuilder, jboolean customSurfaceShading) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
builder->customSurfaceShading(customSurfaceShading);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderMultiBounceAmbientOcclusion(
|
||||
JNIEnv*, jclass, jlong nativeBuilder, jboolean multiBounceAO) {
|
||||
|
||||
@@ -391,6 +391,12 @@ public class MaterialBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder customSurfaceShading(boolean customSurfaceShading) {
|
||||
nMaterialBuilderCustomSurfaceShading(mNativeObject, customSurfaceShading);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder multiBounceAmbientOcclusion(boolean multiBounceAO) {
|
||||
nMaterialBuilderMultiBounceAmbientOcclusion(mNativeObject, multiBounceAO);
|
||||
@@ -556,6 +562,8 @@ public class MaterialBuilder {
|
||||
private static native void nMaterialBuilderClearCoatIorChange(long mNativeObject,
|
||||
boolean clearCoatIorChange);
|
||||
private static native void nMaterialBuilderFlipUV(long nativeBuilder, boolean flipUV);
|
||||
private static native void nMaterialBuilderCustomSurfaceShading(long nativeBuilder,
|
||||
boolean customSurfaceShading);
|
||||
private static native void nMaterialBuilderMultiBounceAmbientOcclusion(long nativeBuilder,
|
||||
boolean multiBounceAO);
|
||||
private static native void nMaterialBuilderSpecularAmbientOcclusion(long nativeBuilder,
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
cmake_minimum_required(VERSION 3.6)
|
||||
cmake_minimum_required(VERSION 3.19)
|
||||
project(filament-android)
|
||||
|
||||
option(FILAMENT_SUPPORTS_VULKAN "Enables Vulkan on Android" OFF)
|
||||
option(FILAMENT_ENABLE_MATDBG "Enables Material debugger" OFF)
|
||||
option(FILAMENT_DISABLE_MATOPT "Disables material optimizations" OFF)
|
||||
|
||||
set(FILAMENT_DIR ${FILAMENT_DIST_DIR})
|
||||
|
||||
@@ -55,6 +57,7 @@ set(VERSION_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/libfilament-jni.map")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -Wl,--version-script=${VERSION_SCRIPT}")
|
||||
|
||||
add_library(filament-jni SHARED
|
||||
src/main/cpp/BufferObject.cpp
|
||||
src/main/cpp/Camera.cpp
|
||||
src/main/cpp/Colors.cpp
|
||||
src/main/cpp/ColorGrading.cpp
|
||||
@@ -95,7 +98,6 @@ target_link_libraries(filament-jni
|
||||
PRIVATE backend
|
||||
PRIVATE filaflat
|
||||
PRIVATE filabridge
|
||||
PRIVATE geometry
|
||||
PRIVATE ibl-lite
|
||||
PRIVATE log
|
||||
PRIVATE GLESv3
|
||||
@@ -103,6 +105,10 @@ target_link_libraries(filament-jni
|
||||
PRIVATE android
|
||||
PRIVATE jnigraphics
|
||||
PRIVATE utils
|
||||
|
||||
# libgeometry is PUBLIC because gltfio uses it.
|
||||
PUBLIC geometry
|
||||
|
||||
$<$<STREQUAL:${FILAMENT_ENABLE_MATDBG},ON>:matdbg>
|
||||
$<$<STREQUAL:${FILAMENT_SUPPORTS_VULKAN},ON>:bluevk>
|
||||
$<$<STREQUAL:${FILAMENT_SUPPORTS_VULKAN},ON>:vkshaders>
|
||||
|
||||
@@ -2,17 +2,24 @@ LIBFILAMENT {
|
||||
global:
|
||||
Java_com_google_android_filament_*;
|
||||
JNI*;
|
||||
*filament*BufferObject*;
|
||||
*filament*Camera*;
|
||||
*filament*Color*;
|
||||
*filament*Exposure*;
|
||||
*filament*Skybox*;
|
||||
*filament*Engine*;
|
||||
*filament*RenderableManager*;
|
||||
*filament*Aabb*;
|
||||
*filament*IndirectLight*;
|
||||
*filament*LightManager*;
|
||||
*filament*Renderer*;
|
||||
*filament*RenderTarget*;
|
||||
*filament*Scene*;
|
||||
*filament*Transform*;
|
||||
*filament*Material*;
|
||||
*filament*IndexBuffer*;
|
||||
*filament*VertexBuffer*;
|
||||
*filament*View*;
|
||||
*filament*Texture*;
|
||||
*filament*geometry*;
|
||||
|
||||
|
||||
99
android/filament-android/src/main/cpp/BufferObject.cpp
Normal file
99
android/filament-android/src/main/cpp/BufferObject.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* 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 <jni.h>
|
||||
|
||||
#include <functional>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <filament/BufferObject.h>
|
||||
|
||||
#include <backend/BufferDescriptor.h>
|
||||
|
||||
#include "common/CallbackUtils.h"
|
||||
#include "common/NioUtils.h"
|
||||
|
||||
using namespace filament;
|
||||
using namespace backend;
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_BufferObject_nCreateBuilder(JNIEnv *env, jclass type) {
|
||||
return (jlong) new BufferObject::Builder();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_BufferObject_nDestroyBuilder(JNIEnv *env, jclass type,
|
||||
jlong nativeBuilder) {
|
||||
BufferObject::Builder* builder = (BufferObject::Builder *) nativeBuilder;
|
||||
delete builder;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_BufferObject_nBuilderSize(JNIEnv *env, jclass type,
|
||||
jlong nativeBuilder, jint byteCount) {
|
||||
BufferObject::Builder* builder = (BufferObject::Builder *) nativeBuilder;
|
||||
builder->size((uint32_t) byteCount);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_BufferObject_nBuilderBindingType(JNIEnv *env, jclass type,
|
||||
jlong nativeBuilder, jint bindingType) {
|
||||
using BindingType = BufferObject::BindingType;
|
||||
BufferObject::Builder* builder = (BufferObject::Builder *) nativeBuilder;
|
||||
BindingType types[] = {BindingType::VERTEX};
|
||||
builder->bindingType(types[bindingType]);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_BufferObject_nBuilderBuild(JNIEnv *env, jclass type,
|
||||
jlong nativeBuilder, jlong nativeEngine) {
|
||||
BufferObject::Builder* builder = (BufferObject::Builder *) nativeBuilder;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
return (jlong) builder->build(*engine);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_BufferObject_nGetByteCount(JNIEnv *env, jclass type,
|
||||
jlong nativeBufferObject) {
|
||||
BufferObject *bufferObject = (BufferObject *) nativeBufferObject;
|
||||
return (jint) bufferObject->getByteCount();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT int JNICALL
|
||||
Java_com_google_android_filament_BufferObject_nSetBuffer(JNIEnv *env, jclass type,
|
||||
jlong nativeBufferObject, jlong nativeEngine, jobject buffer, int remaining,
|
||||
jint destOffsetInBytes, jint count,
|
||||
jobject handler, jobject runnable) {
|
||||
BufferObject *bufferObject = (BufferObject *) nativeBufferObject;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
|
||||
AutoBuffer nioBuffer(env, buffer, count);
|
||||
void* data = nioBuffer.getData();
|
||||
size_t sizeInBytes = nioBuffer.getSize();
|
||||
if (sizeInBytes > (remaining << nioBuffer.getShift())) {
|
||||
// BufferOverflowException
|
||||
return -1;
|
||||
}
|
||||
|
||||
auto* callback = JniBufferCallback::make(engine, env, handler, runnable, std::move(nioBuffer));
|
||||
|
||||
BufferDescriptor desc(data, sizeInBytes, &JniBufferCallback::invoke, callback);
|
||||
|
||||
bufferObject->setBuffer(*engine, std::move(desc), (uint32_t) destOffsetInBytes);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#include <filament/Camera.h>
|
||||
|
||||
#include <utils/Entity.h>
|
||||
|
||||
#include <math/mat4.h>
|
||||
|
||||
using namespace filament;
|
||||
@@ -47,20 +49,31 @@ Java_com_google_android_filament_Camera_nSetLensProjection(JNIEnv*, jclass,
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Camera_nSetCustomProjection(JNIEnv *env, jclass,
|
||||
jlong nativeCamera, jdoubleArray inMatrix_, jdouble near, jdouble far) {
|
||||
jlong nativeCamera, jdoubleArray inProjection_, jdoubleArray inProjectionForCulling_,
|
||||
jdouble near, jdouble far) {
|
||||
Camera *camera = (Camera *) nativeCamera;
|
||||
jdouble *inMatrix = env->GetDoubleArrayElements(inMatrix_, NULL);
|
||||
camera->setCustomProjection(*reinterpret_cast<const filament::math::mat4 *>(inMatrix), near, far);
|
||||
env->ReleaseDoubleArrayElements(inMatrix_, inMatrix, JNI_ABORT);
|
||||
jdouble *inProjection = env->GetDoubleArrayElements(inProjection_, NULL);
|
||||
jdouble *inProjectionForCulling = env->GetDoubleArrayElements(inProjectionForCulling_, NULL);
|
||||
camera->setCustomProjection(
|
||||
*reinterpret_cast<const filament::math::mat4 *>(inProjection),
|
||||
*reinterpret_cast<const filament::math::mat4 *>(inProjectionForCulling),
|
||||
near, far);
|
||||
env->ReleaseDoubleArrayElements(inProjection_, inProjection, JNI_ABORT);
|
||||
env->ReleaseDoubleArrayElements(inProjectionForCulling_, inProjectionForCulling, JNI_ABORT);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Camera_nSetScaling(JNIEnv* env, jclass,
|
||||
jlong nativeCamera, jdoubleArray inScaling_) {
|
||||
jlong nativeCamera, jdouble x, jdouble y) {
|
||||
Camera *camera = (Camera *) nativeCamera;
|
||||
jdouble *inScaling = env->GetDoubleArrayElements(inScaling_, NULL);
|
||||
camera->setScaling(*reinterpret_cast<const filament::math::double4*>(inScaling));
|
||||
env->ReleaseDoubleArrayElements(inScaling_, inScaling, JNI_ABORT);
|
||||
camera->setScaling({(double)x, (double)y});
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Camera_nSetShift(JNIEnv* env, jclass,
|
||||
jlong nativeCamera, jdouble x, jdouble y) {
|
||||
Camera *camera = (Camera *) nativeCamera;
|
||||
camera->setShift({(double)x, (double)y});
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
@@ -205,3 +218,36 @@ Java_com_google_android_filament_Camera_nGetSensitivity(JNIEnv*, jclass,
|
||||
Camera *camera = (Camera *) nativeCamera;
|
||||
return camera->getSensitivity();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Camera_nSetFocusDistance(JNIEnv*, jclass,
|
||||
jlong nativeCamera, jfloat focusDistance) {
|
||||
Camera *camera = (Camera *) nativeCamera;
|
||||
camera->setFocusDistance(focusDistance);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jfloat JNICALL
|
||||
Java_com_google_android_filament_Camera_nGetFocusDistance(JNIEnv*, jclass,
|
||||
jlong nativeCamera) {
|
||||
Camera *camera = (Camera *) nativeCamera;
|
||||
return camera->getFocusDistance();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jdouble JNICALL
|
||||
Java_com_google_android_filament_Camera_nGetFocalLength(JNIEnv*, jclass,
|
||||
jlong nativeCamera) {
|
||||
Camera *camera = (Camera *) nativeCamera;
|
||||
return camera->getFocalLength();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jdouble JNICALL
|
||||
Java_com_google_android_filament_Camera_nComputeEffectiveFocalLength(JNIEnv*, jclass,
|
||||
jdouble focalLength, jdouble focusDistance) {
|
||||
return Camera::computeEffectiveFocalLength(focalLength, focusDistance);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jdouble JNICALL
|
||||
Java_com_google_android_filament_Camera_nComputeEffectiveFov(JNIEnv*, jclass,
|
||||
jdouble fovInDegrees, jdouble focusDistance) {
|
||||
return Camera::computeEffectiveFov(fovInDegrees, focusDistance);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include <filament/Camera.h>
|
||||
#include <filament/Engine.h>
|
||||
|
||||
#include <utils/Entity.h>
|
||||
@@ -120,15 +121,8 @@ Java_com_google_android_filament_Engine_nDestroyRenderer(JNIEnv*, jclass,
|
||||
|
||||
// Camera
|
||||
|
||||
extern "C" [[deprecated]] JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_Engine_nCreateCamera(JNIEnv*, jclass,
|
||||
jlong nativeEngine) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
return (jlong) engine->createCamera();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_Engine_nCreateCameraWithEntity(JNIEnv*, jclass,
|
||||
Java_com_google_android_filament_Engine_nCreateCamera(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jint entity_) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
Entity& entity = *reinterpret_cast<Entity*>(&entity_);
|
||||
@@ -143,12 +137,12 @@ Java_com_google_android_filament_Engine_nGetCameraComponent(JNIEnv*, jclass,
|
||||
return (jlong) engine->getCameraComponent(entity);
|
||||
}
|
||||
|
||||
extern "C" [[deprecated]] JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Engine_nDestroyCamera(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeCamera) {
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Engine_nDestroyCameraComponent(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jint entity_) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
Camera *camera = (Camera *) nativeCamera;
|
||||
engine->destroy(camera);
|
||||
Entity& entity = *reinterpret_cast<Entity*>(&entity_);
|
||||
engine->destroyCameraComponent(entity);
|
||||
}
|
||||
|
||||
// Scene
|
||||
@@ -312,3 +306,9 @@ Java_com_google_android_filament_Engine_nGetJobSystem(JNIEnv*, jclass, jlong nat
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
return (jlong) &engine->getJobSystem();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_Engine_nGetEntityManager(JNIEnv*, jclass, jlong nativeEngine) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
return (jlong) &engine->getEntityManager();
|
||||
}
|
||||
|
||||
@@ -379,3 +379,17 @@ Java_com_google_android_filament_LightManager_nIsShadowCaster(JNIEnv*, jclass,
|
||||
LightManager *lm = (LightManager *) nativeLightManager;
|
||||
return (jboolean)lm->isShadowCaster((LightManager::Instance) i);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jfloat JNICALL
|
||||
Java_com_google_android_filament_LightManager_nGetOuterConeAngle(JNIEnv*, jclass,
|
||||
jlong nativeLightManager, jint i) {
|
||||
LightManager *lm = (LightManager *) nativeLightManager;
|
||||
return (jfloat)lm->getSpotLightOuterCone((LightManager::Instance) i);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jfloat JNICALL
|
||||
Java_com_google_android_filament_LightManager_nGetInnerConeAngle(JNIEnv*, jclass,
|
||||
jlong nativeLightManager, jint i) {
|
||||
LightManager *lm = (LightManager *) nativeLightManager;
|
||||
return (jfloat)lm->getSpotLightInnerCone((LightManager::Instance) i);
|
||||
}
|
||||
|
||||
@@ -364,3 +364,19 @@ Java_com_google_android_filament_MaterialInstance_nGetMaterial(JNIEnv* env, jcla
|
||||
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
|
||||
return (jlong) instance->getMaterial();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nDuplicate(JNIEnv* env, jclass clazz,
|
||||
jlong otherNativeMaterialInstance, jstring name) {
|
||||
MaterialInstance* other = (MaterialInstance*) otherNativeMaterialInstance;
|
||||
const char *cstr = nullptr;
|
||||
if (name != nullptr) {
|
||||
cstr = env->GetStringUTFChars(name, nullptr);
|
||||
}
|
||||
MaterialInstance* mi = MaterialInstance::duplicate(other, cstr);
|
||||
if (name != nullptr) {
|
||||
env->ReleaseStringUTFChars(name, cstr);
|
||||
}
|
||||
return (jlong)mi;
|
||||
}
|
||||
|
||||
@@ -50,6 +50,14 @@ Java_com_google_android_filament_Renderer_nRender(JNIEnv *, jclass, jlong native
|
||||
renderer->render(view);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Renderer_nRenderStandaloneView(JNIEnv *, jclass, jlong nativeRenderer,
|
||||
jlong nativeView) {
|
||||
Renderer *renderer = (Renderer *) nativeRenderer;
|
||||
View *view = (View *) nativeView;
|
||||
renderer->renderStandaloneView(view);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Renderer_nCopyFrame(JNIEnv *, jclass, jlong nativeRenderer,
|
||||
jlong nativeDstSwapChain,
|
||||
|
||||
@@ -102,7 +102,10 @@ extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Stream_nBuilderStream(JNIEnv*, jclass,
|
||||
jlong nativeStreamBuilder, jlong externalTextureId) {
|
||||
StreamBuilder* builder = (StreamBuilder*) nativeStreamBuilder;
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
builder->builder()->stream(externalTextureId);
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
|
||||
@@ -34,12 +34,13 @@
|
||||
using namespace filament;
|
||||
using namespace backend;
|
||||
|
||||
static size_t getTextureDataSize(const Texture *texture, size_t level,
|
||||
Texture::Format format, Texture::Type type, size_t stride, size_t alignment) {
|
||||
static size_t getTextureDataSize(const Texture *texture,
|
||||
size_t level, Texture::Format format, Texture::Type type,
|
||||
size_t stride, size_t height, size_t alignment) {
|
||||
// Zero stride implies tight row-to-row packing.
|
||||
stride = stride == 0 ? texture->getWidth(level) : std::max(size_t(1), stride >> level);
|
||||
return Texture::computeTextureDataSize(format, type,
|
||||
stride, texture->getHeight(level), alignment);
|
||||
stride = stride == 0 ? texture->getWidth(level) : std::max(size_t(1), stride >> level);
|
||||
height = height == 0 ? texture->getHeight(level) : std::max(size_t(1), height >> level);
|
||||
return Texture::computeTextureDataSize(format, type, stride, height, alignment);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
@@ -50,6 +51,13 @@ Java_com_google_android_filament_Texture_nIsTextureFormatSupported(JNIEnv*, jcla
|
||||
(Texture::InternalFormat) internalFormat);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Texture_nIsTextureSwizzleSupported(JNIEnv*, jclass,
|
||||
jlong nativeEngine) {
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
return (jboolean) Texture::isTextureSwizzleSupported(*engine);
|
||||
}
|
||||
|
||||
// Texture::Builder...
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
@@ -121,6 +129,13 @@ Java_com_google_android_filament_Texture_nBuilderSwizzle(JNIEnv *, jclass ,
|
||||
(Texture::Swizzle)r, (Texture::Swizzle)g, (Texture::Swizzle)b, (Texture::Swizzle)a);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Texture_nBuilderImportTexture(JNIEnv*, jclass, jlong nativeBuilder, jlong id) {
|
||||
Texture::Builder *builder = (Texture::Builder *) nativeBuilder;
|
||||
builder->import((intptr_t)id);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_Texture_nBuilderBuild(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jlong nativeEngine) {
|
||||
@@ -175,14 +190,14 @@ extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Texture_nSetImage(JNIEnv* env, jclass, jlong nativeTexture,
|
||||
jlong nativeEngine, jint level, jint xoffset, jint yoffset, jint width, jint height,
|
||||
jobject storage, jint remaining,
|
||||
jint left, jint bottom, jint type, jint alignment,
|
||||
jint left, jint top, jint type, jint alignment,
|
||||
jint stride, jint format,
|
||||
jobject handler, jobject runnable) {
|
||||
Texture* texture = (Texture*) nativeTexture;
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
|
||||
size_t sizeInBytes = getTextureDataSize(texture, (size_t) level, (Texture::Format) format,
|
||||
(Texture::Type) type, (size_t) stride, (size_t) alignment);
|
||||
(Texture::Type) type, (size_t) stride, (size_t) height, (size_t) alignment);
|
||||
|
||||
AutoBuffer nioBuffer(env, storage, 0);
|
||||
if (sizeInBytes > (size_t(remaining) << nioBuffer.getShift())) {
|
||||
@@ -194,7 +209,7 @@ Java_com_google_android_filament_Texture_nSetImage(JNIEnv* env, jclass, jlong na
|
||||
auto *callback = JniBufferCallback::make(engine, env, handler, runnable, std::move(nioBuffer));
|
||||
|
||||
Texture::PixelBufferDescriptor desc(buffer, sizeInBytes, (backend::PixelDataFormat) format,
|
||||
(backend::PixelDataType) type, (uint8_t) alignment, (uint32_t) left, (uint32_t) bottom,
|
||||
(backend::PixelDataType) type, (uint8_t) alignment, (uint32_t) left, (uint32_t) top,
|
||||
(uint32_t) stride, &JniBufferCallback::invoke, callback);
|
||||
|
||||
texture->setImage(*engine, (size_t) level, (uint32_t) xoffset, (uint32_t) yoffset,
|
||||
@@ -239,14 +254,14 @@ Java_com_google_android_filament_Texture_nSetImage3D(JNIEnv* env, jclass, jlong
|
||||
jint xoffset, jint yoffset, jint zoffset,
|
||||
jint width, jint height, jint depth,
|
||||
jobject storage, jint remaining,
|
||||
jint left, jint bottom, jint type, jint alignment,
|
||||
jint left, jint top, jint type, jint alignment,
|
||||
jint stride, jint format,
|
||||
jobject handler, jobject runnable) {
|
||||
Texture* texture = (Texture*) nativeTexture;
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
|
||||
size_t sizeInBytes = getTextureDataSize(texture, (size_t) level, (Texture::Format) format,
|
||||
(Texture::Type) type, (size_t) stride, (size_t) alignment);
|
||||
(Texture::Type) type, (size_t) stride, (size_t) height, (size_t) alignment) * depth;
|
||||
|
||||
AutoBuffer nioBuffer(env, storage, 0);
|
||||
if (sizeInBytes > (size_t(remaining) << nioBuffer.getShift())) {
|
||||
@@ -258,7 +273,7 @@ Java_com_google_android_filament_Texture_nSetImage3D(JNIEnv* env, jclass, jlong
|
||||
auto *callback = JniBufferCallback::make(engine, env, handler, runnable, std::move(nioBuffer));
|
||||
|
||||
Texture::PixelBufferDescriptor desc(buffer, sizeInBytes, (backend::PixelDataFormat) format,
|
||||
(backend::PixelDataType) type, (uint8_t) alignment, (uint32_t) left, (uint32_t) bottom,
|
||||
(backend::PixelDataType) type, (uint8_t) alignment, (uint32_t) left, (uint32_t) top,
|
||||
(uint32_t) stride, &JniBufferCallback::invoke, callback);
|
||||
|
||||
texture->setImage(*engine, (size_t) level,
|
||||
@@ -306,7 +321,7 @@ Java_com_google_android_filament_Texture_nSetImage3DCompressed(JNIEnv *env, jcla
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Texture_nSetImageCubemap(JNIEnv *env, jclass,
|
||||
jlong nativeTexture, jlong nativeEngine, jint level, jobject storage, jint remaining,
|
||||
jint left, jint bottom, jint type, jint alignment, jint stride, jint format,
|
||||
jint left, jint top, jint type, jint alignment, jint stride, jint format,
|
||||
jintArray faceOffsetsInBytes_,
|
||||
jobject handler, jobject runnable) {
|
||||
Texture *texture = (Texture *) nativeTexture;
|
||||
@@ -318,7 +333,7 @@ Java_com_google_android_filament_Texture_nSetImageCubemap(JNIEnv *env, jclass,
|
||||
env->ReleaseIntArrayElements(faceOffsetsInBytes_, faceOffsetsInBytes, JNI_ABORT);
|
||||
|
||||
size_t sizeInBytes = 6 * getTextureDataSize(texture, (size_t) level, (Texture::Format) format,
|
||||
(Texture::Type) type, (size_t) stride, (size_t) alignment);
|
||||
(Texture::Type) type, (size_t) stride, 0, (size_t) alignment);
|
||||
|
||||
AutoBuffer nioBuffer(env, storage, 0);
|
||||
if (sizeInBytes > (size_t(remaining) << nioBuffer.getShift())) {
|
||||
@@ -330,7 +345,7 @@ Java_com_google_android_filament_Texture_nSetImageCubemap(JNIEnv *env, jclass,
|
||||
auto *callback = JniBufferCallback::make(engine, env, handler, runnable, std::move(nioBuffer));
|
||||
|
||||
Texture::PixelBufferDescriptor desc(buffer, sizeInBytes, (backend::PixelDataFormat) format,
|
||||
(backend::PixelDataType) type, (uint8_t) alignment, (uint32_t) left, (uint32_t) bottom,
|
||||
(backend::PixelDataType) type, (uint8_t) alignment, (uint32_t) left, (uint32_t) top,
|
||||
(uint32_t) stride, &JniBufferCallback::invoke, callback);
|
||||
|
||||
texture->setImage(*engine, (size_t) level, std::move(desc), faceOffsets);
|
||||
@@ -341,7 +356,7 @@ Java_com_google_android_filament_Texture_nSetImageCubemap(JNIEnv *env, jclass,
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Texture_nSetImageCubemapCompressed(JNIEnv *env, jclass,
|
||||
jlong nativeTexture, jlong nativeEngine, jint level, jobject storage, jint remaining,
|
||||
jint left, jint bottom, jint type, jint alignment,
|
||||
jint left, jint top, jint type, jint alignment,
|
||||
jint compressedSizeInBytes, jint compressedFormat, jintArray faceOffsetsInBytes_,
|
||||
jobject handler, jobject runnable) {
|
||||
|
||||
|
||||
@@ -86,6 +86,13 @@ Java_com_google_android_filament_TransformManager_nSetParent(JNIEnv*, jclass,
|
||||
(TransformManager::Instance) newParent);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_TransformManager_nGetParent(JNIEnv*, jclass,
|
||||
jlong nativeTransformManager, jint i) {
|
||||
TransformManager* tm = (TransformManager*) nativeTransformManager;
|
||||
return tm->getParent((TransformManager::Instance) i).getId();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_TransformManager_nSetTransform(JNIEnv* env,
|
||||
jclass, jlong nativeTransformManager, jint i,
|
||||
|
||||
@@ -50,6 +50,13 @@ Java_com_google_android_filament_VertexBuffer_nBuilderVertexCount(JNIEnv *env, j
|
||||
builder->vertexCount((uint32_t) vertexCount);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_VertexBuffer_nBuilderEnableBufferObjects(JNIEnv *env, jclass type,
|
||||
jlong nativeBuilder, jboolean enabled) {
|
||||
VertexBuffer::Builder* builder = (VertexBuffer::Builder *) nativeBuilder;
|
||||
builder->enableBufferObjects(enabled);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_VertexBuffer_nBuilderBufferCount(JNIEnv *env, jclass type,
|
||||
jlong nativeBuilder, jint bufferCount) {
|
||||
@@ -115,42 +122,11 @@ Java_com_google_android_filament_VertexBuffer_nSetBufferAt(JNIEnv *env, jclass t
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" [[deprecated]] JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_VertexBuffer_nPopulateTangentQuaternions(JNIEnv *env,
|
||||
jclass type, jint quatType, jint quatCount, jobject outBuffer, jint outRemaining,
|
||||
jint outStride, jobject normals, jint normalsRemaining, jint normalsStride,
|
||||
jobject tangents, jint tangentsRemaining, jint tangentsStride) {
|
||||
|
||||
AutoBuffer outNioBuffer(env, outBuffer, outRemaining, true);
|
||||
void* outData = outNioBuffer.getData();
|
||||
|
||||
AutoBuffer normalsNioBuffer(env, normals, normalsRemaining);
|
||||
auto normalsData = (const float3*) normalsNioBuffer.getData();
|
||||
|
||||
if (tangents) {
|
||||
AutoBuffer tangentsNioBuffer(env, tangents, tangentsRemaining);
|
||||
auto tangentsData = (const float4*) tangentsNioBuffer.getData();
|
||||
VertexBuffer::populateTangentQuaternions({
|
||||
.quatType = (VertexBuffer::QuatType) quatType,
|
||||
.quatCount = (size_t) quatCount,
|
||||
.outBuffer = outData,
|
||||
.outStride = (size_t) outStride,
|
||||
.normals = normalsData,
|
||||
.normalsStride = (size_t) normalsStride,
|
||||
.tangents = tangentsData,
|
||||
.tangentsStride = (size_t) tangentsStride
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
VertexBuffer::populateTangentQuaternions({
|
||||
.quatType = (VertexBuffer::QuatType) quatType,
|
||||
.quatCount = (size_t) quatCount,
|
||||
.outBuffer = outData,
|
||||
.outStride = (size_t) outStride,
|
||||
.normals = normalsData,
|
||||
.normalsStride = (size_t) normalsStride,
|
||||
.tangents = nullptr,
|
||||
.tangentsStride = 0
|
||||
});
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_VertexBuffer_nSetBufferObjectAt(JNIEnv *env, jclass type,
|
||||
jlong nativeVertexBuffer, jlong nativeEngine, jint bufferIndex, jlong nativeBufferObject) {
|
||||
VertexBuffer *vertexBuffer = (VertexBuffer *) nativeVertexBuffer;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
BufferObject *bufferObject = (BufferObject *) nativeBufferObject;
|
||||
vertexBuffer->setBufferObjectAt(*engine, (uint8_t) bufferIndex, bufferObject);
|
||||
}
|
||||
|
||||
@@ -253,7 +253,10 @@ extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetBloomOptions(JNIEnv*, jclass,
|
||||
jlong nativeView, jlong nativeTexture,
|
||||
jfloat dirtStrength, jfloat strength, jint resolution, jfloat anamorphism, jint levels,
|
||||
jint blendMode, jboolean threshold, jboolean enabled, jfloat highlight) {
|
||||
jint blendMode, jboolean threshold, jboolean enabled, jfloat highlight,
|
||||
jboolean lensFlare, jboolean starburst, jfloat chromaticAberration, jint ghostCount,
|
||||
jfloat ghostSpacing, jfloat ghostThreshold, jfloat haloThickness, jfloat haloRadius,
|
||||
jfloat haloThreshold) {
|
||||
View* view = (View*) nativeView;
|
||||
Texture* dirt = (Texture*) nativeTexture;
|
||||
View::BloomOptions options = {
|
||||
@@ -266,7 +269,16 @@ Java_com_google_android_filament_View_nSetBloomOptions(JNIEnv*, jclass,
|
||||
.blendMode = (View::BloomOptions::BlendMode)blendMode,
|
||||
.threshold = (bool)threshold,
|
||||
.enabled = (bool)enabled,
|
||||
.highlight = highlight
|
||||
.highlight = highlight,
|
||||
.lensFlare = (bool)lensFlare,
|
||||
.starburst = (bool)starburst,
|
||||
.chromaticAberration = chromaticAberration,
|
||||
.ghostCount = (uint8_t)ghostCount,
|
||||
.ghostSpacing = ghostSpacing,
|
||||
.ghostThreshold = ghostThreshold,
|
||||
.haloThickness = haloThickness,
|
||||
.haloRadius = haloRadius,
|
||||
.haloThreshold = haloThreshold
|
||||
};
|
||||
view->setBloomOptions(options);
|
||||
}
|
||||
@@ -300,10 +312,24 @@ Java_com_google_android_filament_View_nSetBlendMode(JNIEnv *, jclass , jlong nat
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetDepthOfFieldOptions(JNIEnv *, jclass ,
|
||||
jlong nativeView, jfloat focusDistance, jfloat cocScale, jfloat maxApertureDiameter, jboolean enabled) {
|
||||
jlong nativeView, jfloat focusDistance, jfloat cocScale, jfloat maxApertureDiameter, jboolean enabled, jint filter,
|
||||
jboolean nativeResolution, jint foregroundRingCount, jint backgroundRingCount, jint fastGatherRingCount,
|
||||
jint maxForegroundCOC, jint maxBackgroundCOC) {
|
||||
View* view = (View*) nativeView;
|
||||
view->setDepthOfFieldOptions({.focusDistance = focusDistance, .cocScale = cocScale,
|
||||
.maxApertureDiameter = maxApertureDiameter, .enabled = (bool)enabled});
|
||||
View::DepthOfFieldOptions::Filter eFilter{};
|
||||
if (filter == 1) {
|
||||
// View::DepthOfFieldOptions::Filter::MEDIAN value is actually 2
|
||||
eFilter = View::DepthOfFieldOptions::Filter::MEDIAN;
|
||||
}
|
||||
view->setDepthOfFieldOptions({.cocScale = cocScale,
|
||||
.maxApertureDiameter = maxApertureDiameter, .enabled = (bool)enabled, .filter = eFilter,
|
||||
.nativeResolution = (bool)nativeResolution,
|
||||
.foregroundRingCount = (uint8_t)foregroundRingCount,
|
||||
.backgroundRingCount = (uint8_t)backgroundRingCount,
|
||||
.fastGatherRingCount = (uint8_t)fastGatherRingCount,
|
||||
.maxForegroundCOC = (uint8_t)maxForegroundCOC,
|
||||
.maxBackgroundCOC = (uint8_t)maxBackgroundCOC,
|
||||
});
|
||||
}
|
||||
|
||||
extern "C"
|
||||
|
||||
@@ -1,67 +1,67 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
|
||||
#include <jawt.h>
|
||||
#include <win32/jawt_md.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include <utils/unwindows.h>
|
||||
|
||||
#include "JAWTUtils.h"
|
||||
#include <filament/Engine.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
void* getNativeWindow(JNIEnv* env, jclass, jobject surface) {
|
||||
JAWT_DrawingSurface* ds = nullptr;
|
||||
JAWT_DrawingSurfaceInfo* dsi = nullptr;
|
||||
|
||||
if (!acquireDrawingSurface(env, surface, &ds, &dsi)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JAWT_Win32DrawingSurfaceInfo* dsi_win32 = (JAWT_Win32DrawingSurfaceInfo*) dsi->platformInfo;
|
||||
HWND hWnd = dsi_win32->hwnd;
|
||||
|
||||
releaseDrawingSurface(ds, dsi);
|
||||
|
||||
return (void*) hWnd;
|
||||
}
|
||||
|
||||
|
||||
jlong createNativeSurface(jint width, jint height) {
|
||||
// We need to adjust the window size so the "client area" matches width and height requested.
|
||||
// Otherwise, the window itself will be of dimension width-height but the "client area" and the
|
||||
// resulting surface will be smaller than requested.
|
||||
RECT dimension = {0, 0, width, height};
|
||||
AdjustWindowRect(&dimension, WS_OVERLAPPEDWINDOW, FALSE);
|
||||
width = dimension.right - dimension.left;
|
||||
height = dimension.bottom - dimension.top;
|
||||
|
||||
HWND window = CreateWindowA("STATIC", "dummy", 0, 0, 0, width, height, NULL, NULL, NULL, NULL);
|
||||
SetWindowLong(window, GWL_STYLE, 0); //remove all window styles
|
||||
|
||||
return (jlong) window;
|
||||
}
|
||||
|
||||
void destroyNativeSurface(jlong surface) {
|
||||
HWND window = (HWND) surface;
|
||||
DestroyWindow(window);
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
|
||||
#include <jawt.h>
|
||||
#include <win32/jawt_md.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include <utils/unwindows.h>
|
||||
|
||||
#include "JAWTUtils.h"
|
||||
#include <filament/Engine.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
void* getNativeWindow(JNIEnv* env, jclass, jobject surface) {
|
||||
JAWT_DrawingSurface* ds = nullptr;
|
||||
JAWT_DrawingSurfaceInfo* dsi = nullptr;
|
||||
|
||||
if (!acquireDrawingSurface(env, surface, &ds, &dsi)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JAWT_Win32DrawingSurfaceInfo* dsi_win32 = (JAWT_Win32DrawingSurfaceInfo*) dsi->platformInfo;
|
||||
HWND hWnd = dsi_win32->hwnd;
|
||||
|
||||
releaseDrawingSurface(ds, dsi);
|
||||
|
||||
return (void*) hWnd;
|
||||
}
|
||||
|
||||
|
||||
jlong createNativeSurface(jint width, jint height) {
|
||||
// We need to adjust the window size so the "client area" matches width and height requested.
|
||||
// Otherwise, the window itself will be of dimension width-height but the "client area" and the
|
||||
// resulting surface will be smaller than requested.
|
||||
RECT dimension = {0, 0, width, height};
|
||||
AdjustWindowRect(&dimension, WS_OVERLAPPEDWINDOW, FALSE);
|
||||
width = dimension.right - dimension.left;
|
||||
height = dimension.bottom - dimension.top;
|
||||
|
||||
HWND window = CreateWindowA("STATIC", "dummy", 0, 0, 0, width, height, NULL, NULL, NULL, NULL);
|
||||
SetWindowLong(window, GWL_STYLE, 0); //remove all window styles
|
||||
|
||||
return (jlong) window;
|
||||
}
|
||||
|
||||
void destroyNativeSurface(jlong surface) {
|
||||
HWND window = (HWND) surface;
|
||||
DestroyWindow(window);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.nio.Buffer;
|
||||
import java.nio.BufferOverflowException;
|
||||
|
||||
/**
|
||||
* A generic GPU buffer containing data.
|
||||
*
|
||||
* Usage of this BufferObject is optional. For simple use cases it is not necessary. It is useful
|
||||
* only when you need to share data between multiple VertexBuffer instances. It also allows you to
|
||||
* efficiently swap-out the buffers in VertexBuffer.
|
||||
*
|
||||
* NOTE: For now this is only used for vertex data, but in the future we may use it for other things
|
||||
* (e.g. compute).
|
||||
*
|
||||
* @see VertexBuffer
|
||||
*/
|
||||
public class BufferObject {
|
||||
private long mNativeObject;
|
||||
|
||||
private BufferObject(long nativeBufferObject) {
|
||||
mNativeObject = nativeBufferObject;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
|
||||
// Keep to finalize native resources
|
||||
private final BuilderFinalizer mFinalizer;
|
||||
private final long mNativeBuilder;
|
||||
|
||||
public enum BindingType {
|
||||
VERTEX,
|
||||
}
|
||||
|
||||
public Builder() {
|
||||
mNativeBuilder = nCreateBuilder();
|
||||
mFinalizer = new BuilderFinalizer(mNativeBuilder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Size of the buffer in bytes.
|
||||
*
|
||||
* @param byteCount Maximum number of bytes the BufferObject can hold.
|
||||
* @return A reference to this Builder for chaining calls.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder size(@IntRange(from = 1) int byteCount) {
|
||||
nBuilderSize(mNativeBuilder, byteCount);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The binding type for this buffer object. (defaults to VERTEX)
|
||||
*
|
||||
* @param bindingType Distinguishes between SSBO, VBO, etc. For now this must be VERTEX.
|
||||
* @return A reference to this Builder for chaining calls.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder bindingType(@NonNull BindingType bindingType) {
|
||||
nBuilderBindingType(mNativeBuilder, bindingType.ordinal());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns the <code>BufferObject</code> object. After creation, the buffer
|
||||
* is uninitialized. Use {@link #setBuffer} to initialize the <code>BufferObject</code>.
|
||||
*
|
||||
* @param engine reference to the {@link Engine} to associate this <code>BufferObject</code>
|
||||
* with
|
||||
*
|
||||
* @return the newly created <code>BufferObject</code> object
|
||||
*
|
||||
* @exception IllegalStateException if the BufferObject could not be created
|
||||
*
|
||||
* @see #setBuffer
|
||||
*/
|
||||
@NonNull
|
||||
public BufferObject build(@NonNull Engine engine) {
|
||||
long nativeBufferObject = nBuilderBuild(mNativeBuilder, engine.getNativeObject());
|
||||
if (nativeBufferObject == 0)
|
||||
throw new IllegalStateException("Couldn't create BufferObject");
|
||||
return new BufferObject(nativeBufferObject);
|
||||
}
|
||||
|
||||
private static class BuilderFinalizer {
|
||||
private final long mNativeObject;
|
||||
|
||||
BuilderFinalizer(long nativeObject) {
|
||||
mNativeObject = nativeObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finalize() {
|
||||
try {
|
||||
super.finalize();
|
||||
} catch (Throwable t) { // Ignore
|
||||
} finally {
|
||||
nDestroyBuilder(mNativeObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of this <code>BufferObject</code> in elements.
|
||||
*
|
||||
* @return the number of bytes the <code>BufferObject</code> holds
|
||||
*/
|
||||
@IntRange(from = 0)
|
||||
public int getByteCount() {
|
||||
return nGetByteCount(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously copy-initializes this <code>BufferObject</code> from the data provided.
|
||||
*
|
||||
* @param engine reference to the {@link Engine} to associate this
|
||||
* <code>BufferObject</code> with
|
||||
* @param buffer a CPU-side {@link Buffer} with the data used to initialize the
|
||||
* <code>BufferObject</code>.
|
||||
*/
|
||||
public void setBuffer(@NonNull Engine engine, @NonNull Buffer buffer) {
|
||||
setBuffer(engine, buffer, 0, 0, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously copy-initializes a region of this <code>BufferObject</code> from the data
|
||||
* provided.
|
||||
*
|
||||
* @param engine reference to the {@link Engine} to associate this
|
||||
* <code>BufferObject</code> with
|
||||
* @param buffer a CPU-side {@link Buffer} with the data used to initialize the
|
||||
* <code>BufferObject</code>.
|
||||
* @param destOffsetInBytes offset in <i>bytes</i> into the <code>BufferObject</code>
|
||||
* @param count number of bytes to consume, defaults to
|
||||
* <code>buffer.remaining()</code>
|
||||
*/
|
||||
public void setBuffer(@NonNull Engine engine, @NonNull Buffer buffer,
|
||||
@IntRange(from = 0) int destOffsetInBytes, @IntRange(from = 0) int count) {
|
||||
setBuffer(engine, buffer, destOffsetInBytes, count, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously copy-initializes a region of this <code>BufferObject</code> from the data
|
||||
* provided.
|
||||
*
|
||||
* @param engine reference to the {@link Engine} to associate this
|
||||
* <code>BufferObject</code> with
|
||||
* @param buffer a CPU-side {@link Buffer} with the data used to initialize the
|
||||
* <code>BufferObject</code>.
|
||||
* @param destOffsetInBytes offset in <i>bytes</i> into the <code>BufferObject</code>
|
||||
* @param count number of bytes to consume, defaults to
|
||||
* <code>buffer.remaining()</code>
|
||||
* @param handler an {@link java.util.concurrent.Executor Executor}. On Android this
|
||||
* can also be a {@link android.os.Handler Handler}.
|
||||
* @param callback a callback executed by <code>handler</code> when <code>buffer</code>
|
||||
* is no longer needed.
|
||||
*/
|
||||
public void setBuffer(@NonNull Engine engine, @NonNull Buffer buffer,
|
||||
@IntRange(from = 0) int destOffsetInBytes, @IntRange(from = 0) int count,
|
||||
@Nullable Object handler, @Nullable Runnable callback) {
|
||||
int result = nSetBuffer(getNativeObject(), engine.getNativeObject(), buffer, buffer.remaining(),
|
||||
destOffsetInBytes, count == 0 ? buffer.remaining() : count, handler, callback);
|
||||
if (result < 0) {
|
||||
throw new BufferOverflowException();
|
||||
}
|
||||
}
|
||||
|
||||
public long getNativeObject() {
|
||||
if (mNativeObject == 0) {
|
||||
throw new IllegalStateException("Calling method on destroyed BufferObject");
|
||||
}
|
||||
return mNativeObject;
|
||||
}
|
||||
|
||||
void clearNativeObject() {
|
||||
mNativeObject = 0;
|
||||
}
|
||||
|
||||
private static native long nCreateBuilder();
|
||||
private static native void nDestroyBuilder(long nativeBuilder);
|
||||
private static native void nBuilderSize(long nativeBuilder, int byteCount);
|
||||
private static native void nBuilderBindingType(long nativeBuilder, int bindingType);
|
||||
private static native long nBuilderBuild(long nativeBuilder, long nativeEngine);
|
||||
|
||||
private static native int nGetByteCount(long nativeBufferObject);
|
||||
private static native int nSetBuffer(long nativeBufferObject, long nativeEngine,
|
||||
Buffer buffer, int remaining,
|
||||
int destOffsetInBytes, int count, Object handler, Runnable callback);
|
||||
}
|
||||
@@ -27,21 +27,17 @@ import androidx.annotation.Size;
|
||||
*
|
||||
* <h1><u>Creation and destruction</u></h1>
|
||||
*
|
||||
* Unlike most Filament objects, Camera doesn't require a builder and can be constructed directly
|
||||
* using {@link Engine#createCamera}. At the very least, a projection must be defined
|
||||
* using {@link #setProjection}. In most case, the camera position also needs to be set.
|
||||
* <p>
|
||||
* A Camera object is destroyed using {@link Engine#destroyCamera}.
|
||||
* In Filament, Camera is a component that must be associated with an entity. To do so,
|
||||
* use {@link Engine#createCamera(int)}. A Camera component is destroyed using
|
||||
* {@link Engine#destroyCameraComponent(int Entity)} ()}.
|
||||
*
|
||||
* <pre>
|
||||
* Engine engine = Engine.create();
|
||||
*
|
||||
* Camera myCamera = engine.createCamera();
|
||||
* Camera myCamera = engine.createCamera(myCameraEntity);
|
||||
* myCamera.setProjection(45, 16.0/9.0, 0.1, 1.0);
|
||||
* myCamera.lookAt(0, 1.60, 1,
|
||||
* 0, 0, 0,
|
||||
* 0, 1, 0);
|
||||
* engine.destroyCamera(myCamera);
|
||||
* engine.destroyCameraComponent(myCameraEntity);
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
@@ -125,6 +121,9 @@ import androidx.annotation.Size;
|
||||
public class Camera {
|
||||
private long mNativeObject;
|
||||
|
||||
@Entity
|
||||
private final int mEntity;
|
||||
|
||||
/**
|
||||
* Denotes the projection type used by this camera.
|
||||
* @see #setProjection
|
||||
@@ -147,8 +146,9 @@ public class Camera {
|
||||
HORIZONTAL
|
||||
}
|
||||
|
||||
Camera(long nativeCamera) {
|
||||
Camera(long nativeCamera, @Entity int entity) {
|
||||
mNativeObject = nativeCamera;
|
||||
mEntity = entity;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -252,9 +252,9 @@ public class Camera {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the projection matrix.
|
||||
* Sets a custom projection matrix.
|
||||
*
|
||||
* @param inMatrix custom projection matrix.
|
||||
* @param inProjection custom projection matrix for rendering and culling
|
||||
*
|
||||
* @param near distance in world units from the camera to the near plane.
|
||||
* The near plane's position in view space is z = -<code>near</code>.
|
||||
@@ -270,10 +270,71 @@ public class Camera {
|
||||
* <code>far</code> != <code>near</code>
|
||||
* for {@link Projection#ORTHO}.
|
||||
*/
|
||||
public void setCustomProjection(@NonNull @Size(min = 16) double[] inMatrix,
|
||||
public void setCustomProjection(@NonNull @Size(min = 16) double[] inProjection,
|
||||
double near, double far) {
|
||||
Asserts.assertMat4dIn(inMatrix);
|
||||
nSetCustomProjection(getNativeObject(), inMatrix, near, far);
|
||||
Asserts.assertMat4dIn(inProjection);
|
||||
nSetCustomProjection(getNativeObject(), inProjection, inProjection, near, far);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a custom projection matrix.
|
||||
*
|
||||
* @param inProjection custom projection matrix for rendering.
|
||||
*
|
||||
* @param inProjectionForCulling custom projection matrix for culling.
|
||||
*
|
||||
* @param near distance in world units from the camera to the near plane.
|
||||
* The near plane's position in view space is z = -<code>near</code>.
|
||||
* Precondition:
|
||||
* <code>near</code> > 0 for {@link Projection#PERSPECTIVE} or
|
||||
* <code>near</code> != <code>far</code> for {@link Projection#ORTHO}.
|
||||
*
|
||||
* @param far distance in world units from the camera to the far plane.
|
||||
* The far plane's position in view space is z = -<code>far</code>.
|
||||
* Precondition:
|
||||
* <code>far</code> > <code>near</code>
|
||||
* for {@link Projection#PERSPECTIVE} or
|
||||
* <code>far</code> != <code>near</code>
|
||||
* for {@link Projection#ORTHO}.
|
||||
*/
|
||||
public void setCustomProjection(
|
||||
@NonNull @Size(min = 16) double[] inProjection,
|
||||
@NonNull @Size(min = 16) double[] inProjectionForCulling,
|
||||
double near, double far) {
|
||||
Asserts.assertMat4dIn(inProjection);
|
||||
Asserts.assertMat4dIn(inProjectionForCulling);
|
||||
nSetCustomProjection(getNativeObject(), inProjection, inProjectionForCulling, near, far);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an additional matrix that scales the projection matrix.
|
||||
*
|
||||
* <p>This is useful to adjust the aspect ratio of the camera independent from its projection.
|
||||
* First, pass an aspect of 1.0 to setProjection. Then set the scaling with the desired aspect
|
||||
* ratio:<br>
|
||||
*
|
||||
* <code>
|
||||
* double aspect = width / height;
|
||||
*
|
||||
* // with Fov.HORIZONTAL passed to setProjection:
|
||||
* camera.setScaling(1.0, aspect);
|
||||
*
|
||||
* // with Fov.VERTICAL passed to setProjection:
|
||||
* camera.setScaling(1.0 / aspect, 1.0);
|
||||
* </code>
|
||||
*
|
||||
* By default, this is an identity matrix.
|
||||
* </p>
|
||||
*
|
||||
* @param xscaling horizontal scaling to be applied after the projection matrix.
|
||||
* @param yscaling vertical scaling to be applied after the projection matrix.
|
||||
*
|
||||
* @see Camera#setProjection
|
||||
* @see Camera#setLensProjection
|
||||
* @see Camera#setCustomProjection
|
||||
*/
|
||||
public void setScaling(double xscaling, double yscaling) {
|
||||
nSetScaling(getNativeObject(), xscaling, yscaling);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -303,10 +364,33 @@ public class Camera {
|
||||
* @see Camera#setProjection
|
||||
* @see Camera#setLensProjection
|
||||
* @see Camera#setCustomProjection
|
||||
*
|
||||
* @deprecated use {@link #setScaling(double, double)}
|
||||
*
|
||||
*/
|
||||
@Deprecated
|
||||
public void setScaling(@NonNull @Size(min = 4) double[] inScaling) {
|
||||
Asserts.assertDouble4In(inScaling);
|
||||
nSetScaling(getNativeObject(), inScaling);
|
||||
setScaling(inScaling[0], inScaling[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an additional matrix that shifts (translates) the projection matrix.
|
||||
* <p>
|
||||
* The shift parameters are specified in NDC coordinates, that is, if the translation must
|
||||
* be specified in pixels, the xshift and yshift parameters be scaled by 1.0 / viewport.width
|
||||
* and 1.0 / viewport.height respectively.
|
||||
* </p>
|
||||
*
|
||||
* @param xshift horizontal shift in NDC coordinates applied after the projection
|
||||
* @param yshift vertical shift in NDC coordinates applied after the projection
|
||||
*
|
||||
* @see Camera#setProjection
|
||||
* @see Camera#setLensProjection
|
||||
* @see Camera#setCustomProjection
|
||||
*/
|
||||
public void setShift(double xshift, double yshift) {
|
||||
nSetShift(getNativeObject(), xshift, yshift);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -348,6 +432,7 @@ public class Camera {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the distance to the near plane
|
||||
* @return Distance to the near plane
|
||||
*/
|
||||
public float getNear() {
|
||||
@@ -355,6 +440,7 @@ public class Camera {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the distance to the far plane
|
||||
* @return Distance to the far plane
|
||||
*/
|
||||
public float getCullingFar() {
|
||||
@@ -551,6 +637,7 @@ public class Camera {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the aperture in f-stops
|
||||
* @return Aperture in f-stops
|
||||
*/
|
||||
public float getAperture() {
|
||||
@@ -558,6 +645,7 @@ public class Camera {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the shutter speed in seconds
|
||||
* @return Shutter speed in seconds
|
||||
*/
|
||||
public float getShutterSpeed() {
|
||||
@@ -565,12 +653,69 @@ public class Camera {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the focal length in meters
|
||||
* @return focal length in meters [m]
|
||||
*/
|
||||
public double getFocalLength() {
|
||||
return nGetFocalLength(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the camera focus distance in world units
|
||||
* @param distance Distance from the camera to the focus plane in world units. Must be
|
||||
* positive and larger than the camera's near clipping plane.
|
||||
*/
|
||||
public void setFocusDistance(float distance) {
|
||||
nSetFocusDistance(getNativeObject(), distance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the distance from the camera to the focus plane in world units
|
||||
* @return Distance from the camera to the focus plane in world units
|
||||
*/
|
||||
public float getFocusDistance() {
|
||||
return nGetFocusDistance(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the sensitivity in ISO
|
||||
* @return Sensitivity in ISO
|
||||
*/
|
||||
public float getSensitivity() {
|
||||
return nGetSensitivity(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the entity representing this Camera
|
||||
* @return the entity this Camera component is attached to
|
||||
*/
|
||||
@Entity
|
||||
public int getEntity() {
|
||||
return mEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to compute the effective focal length taking into account the focus distance
|
||||
*
|
||||
* @param focalLength focal length in any unit (e.g. [m] or [mm])
|
||||
* @param focusDistance focus distance in same unit as focalLength
|
||||
* @return the effective focal length in same unit as focalLength
|
||||
*/
|
||||
static double computeEffectiveFocalLength(double focalLength, double focusDistance) {
|
||||
return nComputeEffectiveFocalLength(focalLength, focusDistance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to compute the effective field-of-view taking into account the focus distance
|
||||
*
|
||||
* @param fovInDegrees full field of view in degrees
|
||||
* @param focusDistance focus distance in meters [m]
|
||||
* @return effective full field of view in degrees
|
||||
*/
|
||||
static double computeEffectiveFov(double fovInDegrees, double focusDistance) {
|
||||
return nComputeEffectiveFov(fovInDegrees, focusDistance);
|
||||
}
|
||||
|
||||
public long getNativeObject() {
|
||||
if (mNativeObject == 0) {
|
||||
throw new IllegalStateException("Calling method on destroyed Camera");
|
||||
@@ -585,8 +730,9 @@ public class Camera {
|
||||
private static native void nSetProjection(long nativeCamera, int projection, double left, double right, double bottom, double top, double near, double far);
|
||||
private static native void nSetProjectionFov(long nativeCamera, double fovInDegrees, double aspect, double near, double far, int fov);
|
||||
private static native void nSetLensProjection(long nativeCamera, double focalLength, double aspect, double near, double far);
|
||||
private static native void nSetCustomProjection(long nativeCamera, double[] inMatrix, double near, double far);
|
||||
private static native void nSetScaling(long nativeCamera, double[] inScaling);
|
||||
private static native void nSetCustomProjection(long nativeCamera, double[] inProjection, double[] inProjectionForCulling, double near, double far);
|
||||
private static native void nSetScaling(long nativeCamera, double x, double y);
|
||||
private static native void nSetShift(long nativeCamera, double x, double y);
|
||||
private static native void nSetModelMatrix(long nativeCamera, float[] in);
|
||||
private static native void nLookAt(long nativeCamera, double eyeX, double eyeY, double eyeZ, double centerX, double centerY, double centerZ, double upX, double upY, double upZ);
|
||||
private static native float nGetNear(long nativeCamera);
|
||||
@@ -604,4 +750,9 @@ public class Camera {
|
||||
private static native float nGetAperture(long nativeCamera);
|
||||
private static native float nGetShutterSpeed(long nativeCamera);
|
||||
private static native float nGetSensitivity(long nativeCamera);
|
||||
private static native void nSetFocusDistance(long nativeCamera, float distance);
|
||||
private static native float nGetFocusDistance(long nativeCamera);
|
||||
private static native double nGetFocalLength(long nativeCamera);
|
||||
private static native double nComputeEffectiveFocalLength(double focalLength, double focusDistance);
|
||||
private static native double nComputeEffectiveFov(double fovInDegrees, double focusDistance);
|
||||
}
|
||||
|
||||
@@ -109,15 +109,16 @@ public class ColorGrading {
|
||||
ACES,
|
||||
/** Filmic tone mapping, modelled after ACES but applied in sRGB space. */
|
||||
FILMIC,
|
||||
/** Filmic tone mapping, with more contrast and saturation. */
|
||||
UCHIMURA,
|
||||
/** Exposure value invariant luminance scaling tone mapping, offers the best behaviors in high intensity areas. */
|
||||
EVILS,
|
||||
/** Reinhard luma-based tone mapping. */
|
||||
REINHARD,
|
||||
/** Tone mapping used to validate/debug scene exposure. */
|
||||
DISPLAY_RANGE,
|
||||
}
|
||||
|
||||
ColorGrading(long colorGrading) {
|
||||
// NOTE: This constructor is public only so that filament-utils can use it.
|
||||
public ColorGrading(long colorGrading) {
|
||||
mNativeObject = colorGrading;
|
||||
}
|
||||
|
||||
|
||||
@@ -110,6 +110,7 @@ public class Engine {
|
||||
@NonNull private final TransformManager mTransformManager;
|
||||
@NonNull private final LightManager mLightManager;
|
||||
@NonNull private final RenderableManager mRenderableManager;
|
||||
@NonNull private final EntityManager mEntityManager;
|
||||
|
||||
/**
|
||||
* Denotes a backend
|
||||
@@ -142,6 +143,7 @@ public class Engine {
|
||||
mTransformManager = new TransformManager(nGetTransformManager(nativeEngine));
|
||||
mLightManager = new LightManager(nGetLightManager(nativeEngine));
|
||||
mRenderableManager = new RenderableManager(nGetRenderableManager(nativeEngine));
|
||||
mEntityManager = new EntityManager(nGetEntityManager(nativeEngine));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -397,19 +399,6 @@ public class Engine {
|
||||
|
||||
// Camera
|
||||
|
||||
/**
|
||||
* Creates a new <code>entity</code> and adds a {@link Camera} component to it.
|
||||
*
|
||||
* @return A newly created {@link Camera}
|
||||
* @exception IllegalStateException can be thrown if the {@link Camera} couldn't be created
|
||||
*/
|
||||
@NonNull
|
||||
public Camera createCamera() {
|
||||
long nativeCamera = nCreateCamera(getNativeObject());
|
||||
if (nativeCamera == 0) throw new IllegalStateException("Couldn't create Camera");
|
||||
return new Camera(nativeCamera);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and adds a {@link Camera} component to a given <code>entity</code>.
|
||||
*
|
||||
@@ -419,9 +408,9 @@ public class Engine {
|
||||
*/
|
||||
@NonNull
|
||||
public Camera createCamera(@Entity int entity) {
|
||||
long nativeCamera = nCreateCameraWithEntity(getNativeObject(), entity);
|
||||
long nativeCamera = nCreateCamera(getNativeObject(), entity);
|
||||
if (nativeCamera == 0) throw new IllegalStateException("Couldn't create Camera");
|
||||
return new Camera(nativeCamera);
|
||||
return new Camera(nativeCamera, entity);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -435,16 +424,16 @@ public class Engine {
|
||||
public Camera getCameraComponent(@Entity int entity) {
|
||||
long nativeCamera = nGetCameraComponent(getNativeObject(), entity);
|
||||
if (nativeCamera == 0) return null;
|
||||
return new Camera(nativeCamera);
|
||||
return new Camera(nativeCamera, entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys a {@link Camera} component and frees all its associated resources.
|
||||
* @param camera the {@link Camera} to destroy
|
||||
* Destroys the {@link Camera} component associated with the given entity.
|
||||
*
|
||||
* @param entity an entity
|
||||
*/
|
||||
public void destroyCamera(@NonNull Camera camera) {
|
||||
nDestroyCamera(getNativeObject(), camera.getNativeObject());
|
||||
camera.clearNativeObject();
|
||||
public void destroyCameraComponent(@Entity int entity) {
|
||||
nDestroyCameraComponent(getNativeObject(), entity);
|
||||
}
|
||||
|
||||
// Scene
|
||||
@@ -632,6 +621,14 @@ public class Engine {
|
||||
return mRenderableManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link EntityManager} used by this {@link Engine}
|
||||
*/
|
||||
@NonNull
|
||||
public EntityManager getEntityManager() {
|
||||
return mEntityManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Kicks the hardware thread (e.g.: the OpenGL, Vulkan or Metal thread) and blocks until
|
||||
* all commands to this point are executed. Note that this doesn't guarantee that the
|
||||
@@ -683,10 +680,9 @@ public class Engine {
|
||||
private static native boolean nDestroyView(long nativeEngine, long nativeView);
|
||||
private static native long nCreateRenderer(long nativeEngine);
|
||||
private static native boolean nDestroyRenderer(long nativeEngine, long nativeRenderer);
|
||||
private static native long nCreateCamera(long nativeEngine);
|
||||
private static native long nCreateCameraWithEntity(long nativeEngine, int entity);
|
||||
private static native long nCreateCamera(long nativeEngine, int entity);
|
||||
private static native long nGetCameraComponent(long nativeEngine, int entity);
|
||||
private static native void nDestroyCamera(long nativeEngine, long nativeCamera);
|
||||
private static native void nDestroyCameraComponent(long nativeEngine, int entity);
|
||||
private static native long nCreateScene(long nativeEngine);
|
||||
private static native boolean nDestroyScene(long nativeEngine, long nativeScene);
|
||||
private static native long nCreateFence(long nativeEngine);
|
||||
@@ -707,4 +703,5 @@ public class Engine {
|
||||
private static native long nGetLightManager(long nativeEngine);
|
||||
private static native long nGetRenderableManager(long nativeEngine);
|
||||
private static native long nGetJobSystem(long nativeEngine);
|
||||
private static native long nGetEntityManager(long nativeEngine);
|
||||
}
|
||||
|
||||
@@ -31,6 +31,10 @@ public class EntityManager {
|
||||
private EntityManager() {
|
||||
}
|
||||
|
||||
EntityManager(long nativeEntityManager) {
|
||||
mNativeObject = nativeEntityManager;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static EntityManager get() {
|
||||
return Holder.INSTANCE;
|
||||
|
||||
@@ -21,8 +21,6 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.Size;
|
||||
|
||||
import com.google.android.filament.proguard.UsedByReflection;
|
||||
|
||||
/**
|
||||
* <code>IndirectLight</code> is used to simulate environment lighting, a form of global illumination.
|
||||
*
|
||||
@@ -86,11 +84,7 @@ import com.google.android.filament.proguard.UsedByReflection;
|
||||
public class IndirectLight {
|
||||
long mNativeObject;
|
||||
|
||||
public IndirectLight(Engine engine, long indirectLight) {
|
||||
mNativeObject = indirectLight;
|
||||
}
|
||||
|
||||
IndirectLight(long indirectLight) {
|
||||
public IndirectLight(long indirectLight) {
|
||||
mNativeObject = indirectLight;
|
||||
}
|
||||
|
||||
@@ -288,7 +282,7 @@ public class IndirectLight {
|
||||
* range can be adjusted with this method.</p>
|
||||
*
|
||||
* @param envIntensity Scale factor applied to the environment and irradiance such that
|
||||
* the result is in cd/m^2 (lux) units (default = 30000)
|
||||
* the result is in <i>lux</i>, or <i>lumen/m^2</i> (default = 30000)
|
||||
*
|
||||
* @return This Builder, for chaining calls.
|
||||
*/
|
||||
@@ -354,14 +348,14 @@ public class IndirectLight {
|
||||
* range can be adjusted with this method.</p>
|
||||
*
|
||||
* @param intensity Scale factor applied to the environment and irradiance such that
|
||||
* the result is in cd/m^2 units (default = 30000)
|
||||
* the result is in <i>lux</i>, or <i>lumen/m^2</i> (default = 30000)
|
||||
*/
|
||||
public void setIntensity(float intensity) {
|
||||
nSetIntensity(getNativeObject(), intensity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the environment's intensity in cd/m<sup>2</sup>.
|
||||
* Returns the environment's intensity in <i>lux</i>, or <i>lumen/m^2</i>.
|
||||
*/
|
||||
public float getIntensity() {
|
||||
return nGetIntensity(getNativeObject());
|
||||
@@ -430,6 +424,7 @@ public class IndirectLight {
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
@Deprecated
|
||||
@NonNull @Size(min = 3)
|
||||
public float[] getDirectionEstimate(@Nullable @Size(min = 3) float[] direction) {
|
||||
direction = Asserts.assertFloat3(direction);
|
||||
@@ -472,6 +467,7 @@ public class IndirectLight {
|
||||
|
||||
|
||||
/** @deprecated */
|
||||
@Deprecated
|
||||
@NonNull @Size(min = 4)
|
||||
public float[] getColorEstimate(@Nullable @Size(min = 4) float[] colorIntensity, float x, float y, float z) {
|
||||
colorIntensity = Asserts.assertFloat4(colorIntensity);
|
||||
|
||||
@@ -1065,6 +1065,14 @@ public class LightManager {
|
||||
return nIsShadowCaster(mNativeObject, i);
|
||||
}
|
||||
|
||||
public float getOuterConeAngle(@EntityInstance int i) {
|
||||
return nGetOuterConeAngle(mNativeObject, i);
|
||||
}
|
||||
|
||||
public float getInnerConeAngle(@EntityInstance int i) {
|
||||
return nGetInnerConeAngle(mNativeObject, i);
|
||||
}
|
||||
|
||||
public long getNativeObject() {
|
||||
return mNativeObject;
|
||||
}
|
||||
@@ -1118,4 +1126,6 @@ public class LightManager {
|
||||
private static native float nGetSunHaloFalloff(long nativeLightManager, int i);
|
||||
private static native void nSetShadowCaster(long nativeLightManager, int i, boolean shadowCaster);
|
||||
private static native boolean nIsShadowCaster(long nativeLightManager, int i);
|
||||
private static native float nGetOuterConeAngle(long nativeLightManager, int i);
|
||||
private static native float nGetInnerConeAngle(long nativeLightManager, int i);
|
||||
}
|
||||
|
||||
@@ -760,7 +760,7 @@ public class Material {
|
||||
* @param name name of the parameter array as defined by this Material
|
||||
* @param type the number of components for each individual parameter
|
||||
* @param v array of values to set to the named parameter array
|
||||
* @param offset the number of elements to skip
|
||||
* @param offset the number of elements in <code>v</code> to skip
|
||||
* @param count the number of elements in the parameter array to set
|
||||
*
|
||||
* <p>For example, to set a parameter array of 4 bool4s:
|
||||
@@ -768,11 +768,6 @@ public class Material {
|
||||
* boolean[] a = new boolean[4 * 4];
|
||||
* material.setDefaultParameter("param", MaterialInstance.BooleanElement.BOOL4, a, 0, 4);
|
||||
* }</pre>
|
||||
* To only set the last 3 elements, specify an offset of 1 and a count of 3:
|
||||
* <pre>{@code
|
||||
* boolean[] a = new boolean[4 * 3];
|
||||
* material.setDefaultParameter("param", MaterialInstance.BooleanElement.BOOL4, a, 1, 3);
|
||||
* }</pre>
|
||||
* </p>
|
||||
*
|
||||
* @see Material#getDefaultInstance()
|
||||
@@ -789,7 +784,7 @@ public class Material {
|
||||
* @param name name of the parameter array as defined by this Material
|
||||
* @param type the number of components for each individual parameter
|
||||
* @param v array of values to set to the named parameter array
|
||||
* @param offset the number of elements to skip
|
||||
* @param offset the number of elements in <code>v</code> to skip
|
||||
* @param count the number of elements in the parameter array to set
|
||||
*
|
||||
* <p>For example, to set a parameter array of 4 int4s:
|
||||
@@ -797,11 +792,6 @@ public class Material {
|
||||
* int[] a = new int[4 * 4];
|
||||
* material.setDefaultParameter("param", MaterialInstance.IntElement.INT4, a, 0, 4);
|
||||
* }</pre>
|
||||
* To only set the last 3 elements, specify an offset of 1 and a count of 3:
|
||||
* <pre>{@code
|
||||
* int[] a = new int[4 * 3];
|
||||
* material.setDefaultParameter("param", MaterialInstance.IntElement.INT4, a, 1, 3);
|
||||
* }</pre>
|
||||
* </p>
|
||||
*
|
||||
* @see Material#getDefaultInstance()
|
||||
@@ -818,7 +808,7 @@ public class Material {
|
||||
* @param name name of the parameter array as defined by this Material
|
||||
* @param type the number of components for each individual parameter
|
||||
* @param v array of values to set to the named parameter array
|
||||
* @param offset the number of elements to skip
|
||||
* @param offset the number of elements in <code>v</code> to skip
|
||||
* @param count the number of elements in the parameter array to set
|
||||
*
|
||||
* <p>For example, to set a parameter array of 4 float4s:
|
||||
@@ -826,11 +816,6 @@ public class Material {
|
||||
* float[] a = new float[4 * 4];
|
||||
* material.setDefaultParameter("param", MaterialInstance.FloatElement.FLOAT4, a, 0, 4);
|
||||
* }</pre>
|
||||
* To only set the last 3 elements, specify an offset of 1 and a count of 3:
|
||||
* <pre>{@code
|
||||
* float[] a = new float[4 * 3];
|
||||
* material.setDefaultParameter("param", MaterialInstance.FloatElement.FLOAT4, a, 1, 3);
|
||||
* }</pre>
|
||||
* </p>
|
||||
*
|
||||
* @see Material#getDefaultInstance()
|
||||
|
||||
@@ -64,6 +64,22 @@ public class MaterialInstance {
|
||||
mNativeMaterial = nGetMaterial(mNativeObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link #MaterialInstance} using another {@link #MaterialInstance} as a template for initialization.
|
||||
* The new {@link #MaterialInstance} is an instance of the same {@link Material} of the template instance and
|
||||
* must be destroyed just like any other {@link #MaterialInstance}.
|
||||
*
|
||||
* @param other A {@link #MaterialInstance} to use as a template for initializing a new instance
|
||||
* @param name A name for the new {@link #MaterialInstance} or nullptr to use the template's name
|
||||
* @return A new {@link #MaterialInstance}
|
||||
*/
|
||||
@NonNull
|
||||
public static MaterialInstance duplicate(@NonNull MaterialInstance other, String name) {
|
||||
long nativeInstance = nDuplicate(other.mNativeObject, name);
|
||||
if (nativeInstance == 0) throw new IllegalStateException("Couldn't duplicate MaterialInstance");
|
||||
return new MaterialInstance(other.mMaterial, nativeInstance);
|
||||
}
|
||||
|
||||
/** @return the {@link Material} associated with this instance */
|
||||
@NonNull
|
||||
public Material getMaterial() {
|
||||
@@ -238,7 +254,7 @@ public class MaterialInstance {
|
||||
* @param name name of the parameter array as defined by this Material
|
||||
* @param type the number of components for each individual parameter
|
||||
* @param v array of values to set to the named parameter array
|
||||
* @param offset the number of elements to skip
|
||||
* @param offset the number of elements in <code>v</code> to skip
|
||||
* @param count the number of elements in the parameter array to set
|
||||
*
|
||||
* <p>For example, to set a parameter array of 4 bool4s:
|
||||
@@ -246,11 +262,6 @@ public class MaterialInstance {
|
||||
* boolean[] a = new boolean[4 * 4];
|
||||
* instance.setParameter("param", MaterialInstance.BooleanElement.BOOL4, a, 0, 4);
|
||||
* }</pre>
|
||||
* To only set the last 3 elements, specify an offset of 1 and a count of 3:
|
||||
* <pre>{@code
|
||||
* boolean[] a = new boolean[4 * 3];
|
||||
* instance.setParameter("param", MaterialInstance.BooleanElement.BOOL4, a, 1, 3);
|
||||
* }</pre>
|
||||
* </p>
|
||||
*/
|
||||
public void setParameter(@NonNull String name,
|
||||
@@ -265,7 +276,7 @@ public class MaterialInstance {
|
||||
* @param name name of the parameter array as defined by this Material
|
||||
* @param type the number of components for each individual parameter
|
||||
* @param v array of values to set to the named parameter array
|
||||
* @param offset the number of elements to skip
|
||||
* @param offset the number of elements in <code>v</code> to skip
|
||||
* @param count the number of elements in the parameter array to set
|
||||
*
|
||||
* <p>For example, to set a parameter array of 4 int4s:
|
||||
@@ -273,11 +284,6 @@ public class MaterialInstance {
|
||||
* int[] a = new int[4 * 4];
|
||||
* instance.setParameter("param", MaterialInstance.IntElement.INT4, a, 0, 4);
|
||||
* }</pre>
|
||||
* To only set the last 3 elements, specify an offset of 1 and a count of 3:
|
||||
* <pre>{@code
|
||||
* int[] a = new int[4 * 3];
|
||||
* instance.setParameter("param", MaterialInstance.IntElement.INT4, a, 1, 3);
|
||||
* }</pre>
|
||||
* </p>
|
||||
*/
|
||||
public void setParameter(@NonNull String name,
|
||||
@@ -292,7 +298,7 @@ public class MaterialInstance {
|
||||
* @param name name of the parameter array as defined by this Material
|
||||
* @param type the number of components for each individual parameter
|
||||
* @param v array of values to set to the named parameter array
|
||||
* @param offset the number of elements to skip
|
||||
* @param offset the number of elements in <code>v</code> to skip
|
||||
* @param count the number of elements in the parameter array to set
|
||||
*
|
||||
* <p>For example, to set a parameter array of 4 float4s:
|
||||
@@ -300,11 +306,6 @@ public class MaterialInstance {
|
||||
* float[] a = new float[4 * 4];
|
||||
* material.setDefaultParameter("param", MaterialInstance.FloatElement.FLOAT4, a, 0, 4);
|
||||
* }</pre>
|
||||
* To only set the last 3 elements, specify an offset of 1 and a count of 3:
|
||||
* <pre>{@code
|
||||
* float[] a = new float[4 * 3];
|
||||
* material.setDefaultParameter("param", MaterialInstance.FloatElement.FLOAT4, a, 1, 3);
|
||||
* }</pre>
|
||||
* </p>
|
||||
*/
|
||||
public void setParameter(@NonNull String name,
|
||||
@@ -452,7 +453,7 @@ public class MaterialInstance {
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/rasterization:colorWrite">
|
||||
* Rasterization: colorWrite</a>
|
||||
*/
|
||||
void setColorWrite(boolean enable) {
|
||||
public void setColorWrite(boolean enable) {
|
||||
nSetColorWrite(getNativeObject(), enable);
|
||||
}
|
||||
|
||||
@@ -463,7 +464,7 @@ public class MaterialInstance {
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/rasterization:depthWrite">
|
||||
* Rasterization: depthWrite</a>
|
||||
*/
|
||||
void setDepthWrite(boolean enable) {
|
||||
public void setDepthWrite(boolean enable) {
|
||||
nSetDepthWrite(getNativeObject(), enable);
|
||||
}
|
||||
|
||||
@@ -474,7 +475,7 @@ public class MaterialInstance {
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/rasterization:depthCulling">
|
||||
* Rasterization: depthCulling</a>
|
||||
*/
|
||||
void setDepthCulling(boolean enable) {
|
||||
public void setDepthCulling(boolean enable) {
|
||||
nSetDepthCulling(getNativeObject(), enable);
|
||||
}
|
||||
|
||||
@@ -554,4 +555,6 @@ public class MaterialInstance {
|
||||
|
||||
private static native String nGetName(long nativeMaterialInstance);
|
||||
private static native long nGetMaterial(long nativeMaterialInstance);
|
||||
|
||||
private static native long nDuplicate(long otherNativeMaterialInstance, String name);
|
||||
}
|
||||
|
||||
@@ -32,12 +32,12 @@ import androidx.annotation.Nullable;
|
||||
*/
|
||||
public class RenderTarget {
|
||||
private long mNativeObject;
|
||||
private final Texture[] mTextures = new Texture[2];
|
||||
private static final int ATTACHMENT_COUNT = 5;
|
||||
private final Texture[] mTextures = new Texture[ATTACHMENT_COUNT];
|
||||
|
||||
private RenderTarget(long nativeRenderTarget, Builder builder) {
|
||||
mNativeObject = nativeRenderTarget;
|
||||
mTextures[0] = builder.mTextures[0];
|
||||
mTextures[1] = builder.mTextures[1];
|
||||
System.arraycopy(builder.mTextures, 0, mTextures, 0, ATTACHMENT_COUNT);
|
||||
}
|
||||
|
||||
public long getNativeObject() {
|
||||
@@ -52,7 +52,14 @@ public class RenderTarget {
|
||||
*/
|
||||
public enum AttachmentPoint {
|
||||
COLOR,
|
||||
DEPTH,
|
||||
COLOR1,
|
||||
COLOR2,
|
||||
COLOR3,
|
||||
COLOR4,
|
||||
COLOR5,
|
||||
COLOR6,
|
||||
COLOR7,
|
||||
DEPTH
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,7 +69,7 @@ public class RenderTarget {
|
||||
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
|
||||
private final BuilderFinalizer mFinalizer;
|
||||
private final long mNativeBuilder;
|
||||
private final Texture[] mTextures = new Texture[2];
|
||||
private final Texture[] mTextures = new Texture[ATTACHMENT_COUNT];
|
||||
|
||||
public Builder() {
|
||||
mNativeBuilder = nCreateBuilder();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -315,7 +315,7 @@ public class Renderer {
|
||||
* <li>Color pass</li>
|
||||
* <li>Post-processing pass</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>
|
||||
* A typical render loop looks like this:
|
||||
*
|
||||
* <pre>
|
||||
@@ -331,31 +331,58 @@ public class Renderer {
|
||||
* </pre>
|
||||
*
|
||||
* <ul>
|
||||
*<li><code>render()</code> must be called <b>after</b> {@link #beginFrame} and <b>before</b>
|
||||
*{@link #endFrame}.</li>
|
||||
* <li><code>render()</code> must be called <b>after</b> {@link #beginFrame} and <b>before</b>
|
||||
* {@link #endFrame}.</li>
|
||||
*
|
||||
*<li><code>render()</code> must be called from the {@link Engine}'s main thread
|
||||
*(or external synchronization must be provided). In particular, calls to <code>render()</code>
|
||||
*on different <code>Renderer</code> instances <b>must</b> be synchronized.</li>
|
||||
* <li><code>render()</code> must be called from the {@link Engine}'s main thread
|
||||
* (or external synchronization must be provided). In particular, calls to <code>render()</code>
|
||||
* on different <code>Renderer</code> instances <b>must</b> be synchronized.</li>
|
||||
*
|
||||
*<li><code>render()</code> performs potentially heavy computations and cannot be multi-threaded.
|
||||
*However, internally, it is highly multi-threaded to both improve performance and mitigate
|
||||
*the call's latency.</li>
|
||||
* <li><code>render()</code> performs potentially heavy computations and cannot be multi-threaded.
|
||||
* However, internally, it is highly multi-threaded to both improve performance and mitigate
|
||||
* the call's latency.</li>
|
||||
*
|
||||
*<li><code>render()</code> is typically called once per frame (but not necessarily).</li>
|
||||
* <li><code>render()</code> is typically called once per frame (but not necessarily).</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param view the {@link View} to render
|
||||
*
|
||||
* @see #beginFrame
|
||||
* @see #endFrame
|
||||
* @see View
|
||||
*
|
||||
*/
|
||||
public void render(@NonNull View view) {
|
||||
nRender(getNativeObject(), view.getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a standalone {@link View} into its associated <code>RenderTarget</code>.
|
||||
*
|
||||
* <p>
|
||||
* This call is mostly equivalent to calling {@link #render(View)} inside a
|
||||
* {@link #beginFrame} / {@link #endFrame} block, but incurs less overhead. It can be used
|
||||
* as a poor man's compute API.
|
||||
* </p>
|
||||
*
|
||||
* <ul>
|
||||
* <li><code>renderStandaloneView()</code> must be called <b>outside</b> of
|
||||
* {@link #beginFrame} / {@link #endFrame}.</li>
|
||||
*
|
||||
* <li><code>renderStandaloneView()</code> must be called from the {@link Engine}'s main thread
|
||||
* (or external synchronization must be provided). In particular, calls to
|
||||
* <code>renderStandaloneView()</code> on different <code>Renderer</code> instances <b>must</b>
|
||||
* be synchronized.</li>
|
||||
*
|
||||
* <li><code>renderStandaloneView()</code> performs potentially heavy computations and cannot be
|
||||
* multi-threaded. However, internally, it is highly multi-threaded to both improve performance
|
||||
* and mitigate the call's latency.</li>
|
||||
*
|
||||
* @param view the {@link View} to render. This View must have an associated {@link RenderTarget}
|
||||
* @see View
|
||||
*/
|
||||
public void renderStandaloneView(@NonNull View view) {
|
||||
nRenderStandaloneView(getNativeObject(), view.getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the currently rendered {@link View} to the indicated {@link SwapChain}, using the
|
||||
* indicated source and destination rectangle.
|
||||
@@ -635,6 +662,7 @@ public class Renderer {
|
||||
private static native boolean nBeginFrame(long nativeRenderer, long nativeSwapChain, long frameTimeNanos);
|
||||
private static native void nEndFrame(long nativeRenderer);
|
||||
private static native void nRender(long nativeRenderer, long nativeView);
|
||||
private static native void nRenderStandaloneView(long nativeRenderer, long nativeView);
|
||||
private static native void nCopyFrame(long nativeRenderer, long nativeDstSwapChain,
|
||||
int dstLeft, int dstBottom, int dstWidth, int dstHeight,
|
||||
int srcLeft, int srcBottom, int srcWidth, int srcHeight,
|
||||
|
||||
@@ -128,6 +128,7 @@ public class Scene {
|
||||
/**
|
||||
* @deprecated See {@link #removeEntity(int)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void remove(@Entity int entity) {
|
||||
removeEntity(entity);
|
||||
}
|
||||
|
||||
@@ -23,8 +23,6 @@ import androidx.annotation.Size;
|
||||
|
||||
import static com.google.android.filament.Colors.LinearColor;
|
||||
|
||||
import com.google.android.filament.proguard.UsedByReflection;
|
||||
|
||||
/**
|
||||
* Skybox
|
||||
* <p>When added to a {@link Scene}, the <code>Skybox</code> fills all untouched pixels.</p>
|
||||
@@ -53,11 +51,7 @@ import com.google.android.filament.proguard.UsedByReflection;
|
||||
public class Skybox {
|
||||
private long mNativeObject;
|
||||
|
||||
public Skybox(Engine engine, long nativeSkybox) {
|
||||
mNativeObject = nativeSkybox;
|
||||
}
|
||||
|
||||
Skybox(long nativeSkybox) {
|
||||
public Skybox(long nativeSkybox) {
|
||||
mNativeObject = nativeSkybox;
|
||||
}
|
||||
|
||||
@@ -115,13 +109,14 @@ public class Skybox {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the <code>Skybox</code> intensity when no {@link IndirectLight} is set
|
||||
* Sets the <code>Skybox</code> intensity when no {@link IndirectLight} is set on the
|
||||
* {@link Scene}.
|
||||
*
|
||||
* <p>This call is ignored when an {@link IndirectLight} is set, otherwise it is used in
|
||||
* its place.</p>
|
||||
* <p>This call is ignored when an {@link IndirectLight} is set on the {@link Scene}, and
|
||||
* the intensity of the {@link IndirectLight} is used instead.</p>
|
||||
*
|
||||
* @param envIntensity Scale factor applied to the skybox texel values such that
|
||||
* the result is in cd/m<sup>2</sup> (lux) units (default = 30000)
|
||||
* the result is in <i>lux</i>, or <i>lumen/m^2</i> (default = 30000)
|
||||
*
|
||||
* @return This Builder, for chaining calls.
|
||||
*
|
||||
@@ -237,7 +232,7 @@ public class Skybox {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>Skybox</code>'s intensity in cd/m<sup>2</sup>.
|
||||
* Returns the <code>Skybox</code>'s intensity in <i>lux</i>, or <i>lumen/m^2</i>.
|
||||
*/
|
||||
public float getIntensity() { return nGetIntensity(getNativeObject()); }
|
||||
|
||||
|
||||
@@ -26,6 +26,67 @@ import java.nio.ReadOnlyBufferException;
|
||||
/**
|
||||
* <code>Stream</code> is used to attach a native video stream to a filament {@link Texture}.
|
||||
*
|
||||
* Stream supports three different configurations:
|
||||
*
|
||||
* <dl>
|
||||
* <dt>TEXTURE_ID</dt> <dd>takes an OpenGL texture ID and incurs a copy</dd>
|
||||
* <dt>ACQUIRED</dt> <dd>connects to an Android AHardwareBuffer</dd>
|
||||
* <dt>NATIVE</dt> <dd>connects to an Android SurfaceTexture</dd>
|
||||
* </dl>
|
||||
*
|
||||
* <p>
|
||||
* Before explaining these different configurations, let's review the high-level structure of an
|
||||
* AR or video application that uses Filament.
|
||||
* </p>
|
||||
*
|
||||
* <pre>
|
||||
* while (true) {
|
||||
*
|
||||
* // Misc application work occurs here, such as:
|
||||
* // - Writing the image data for a video frame into a Stream
|
||||
* // - Moving the Filament Camera
|
||||
*
|
||||
* if (renderer.beginFrame(swapChain)) {
|
||||
* renderer.render(view);
|
||||
* renderer.endFrame();
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* Let's say that the video image data at the time of a particular invocation of beginFrame
|
||||
* becomes visible to users at time A. The 3D scene state (including the camera) at the time of
|
||||
* that same invocation becomes apparent to users at time B.
|
||||
* </p>
|
||||
*
|
||||
* <ul>
|
||||
* <li>If time A matches time B, we say that the stream is <em>synchronized</em>.</li>
|
||||
* <li>Filament invokes low-level graphics commands on the <em>driver thread</em>.</li>
|
||||
* <li>The thread that calls beginFrame is called the <em>main thread</em>.</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>
|
||||
* The <b>TEXTURE_ID</b> configuration achieves synchronization automatically. In this mode,
|
||||
* Filament performs a copy on the main thread during beginFrame by blitting the external image into
|
||||
* an internal round-robin queue of images. This copy has a run-time cost.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* For <b>ACQUIRED</b> streams, there is no need to perform the copy because Filament explictly
|
||||
* acquires the stream, then releases it later via a callback function. This configuration is
|
||||
* especially useful when the Vulkan backend is enabled.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* For <b>NATIVE</b> streams, Filament does not make any synchronization guarantee. However they are
|
||||
* simple to use and do not incur a copy. These are often appropriate in video applications.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Please see <code>sample-stream-test</code> and <code>sample-hello-camera</code> for usage
|
||||
* examples.
|
||||
* </p>
|
||||
*
|
||||
* @see Texture#setExternalStream
|
||||
* @see Engine#destroyStream
|
||||
*/
|
||||
@@ -105,7 +166,9 @@ public class Stream {
|
||||
* <code>GL_TEXTURE_EXTERNAL_OES.</code>
|
||||
* @return This Builder, for chaining calls.
|
||||
* @see Texture#setExternalStream
|
||||
* @deprecated this method existed only for ARCore which doesn't need this anymore, use {@link Texture.Builder#importTexture(long)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@NonNull
|
||||
public Builder stream(long externalTextureId) {
|
||||
nBuilderStream(mNativeBuilder, externalTextureId);
|
||||
@@ -179,8 +242,17 @@ public class Stream {
|
||||
/**
|
||||
* Updates an <pre>ACQUIRED</pre> stream with an image that is guaranteed to be used in the next frame.
|
||||
*
|
||||
* This method should be called on the same thread that calls {#link Renderer#beginFrame}, which is
|
||||
* also where the callback is invoked.
|
||||
* This method tells Filament to immediately "acquire" the image and trigger a callback
|
||||
* when it is done with it. This should be called by the user outside of beginFrame / endFrame,
|
||||
* and should be called only once per frame. If the user pushes images to the same stream
|
||||
* multiple times in a single frame, only the final image is honored, but all callbacks are
|
||||
* invoked.
|
||||
*
|
||||
* This method should be called on the same thread that calls {@link Renderer#beginFrame}, which is
|
||||
* also where the callback is invoked. This method can only be used for streams that were
|
||||
* constructed without calling the {@link Builder.stream} method.
|
||||
*
|
||||
* See {@link Stream} for more information about NATIVE, TEXTURE_ID, and ACQUIRED configurations.
|
||||
*
|
||||
* @param hwbuffer {@link android.hardware.HardwareBuffer HardwareBuffer} (requires API level 26)
|
||||
* @param handler {@link java.util.concurrent.Executor Executor} or {@link android.os.Handler Handler}.
|
||||
|
||||
@@ -73,11 +73,7 @@ import static com.google.android.filament.Texture.Type.COMPRESSED;
|
||||
public class Texture {
|
||||
private long mNativeObject;
|
||||
|
||||
Texture(long nativeTexture) {
|
||||
mNativeObject = nativeTexture;
|
||||
}
|
||||
|
||||
public Texture(Engine engine, long nativeTexture) {
|
||||
public Texture(long nativeTexture) {
|
||||
mNativeObject = nativeTexture;
|
||||
}
|
||||
|
||||
@@ -509,12 +505,15 @@ public class Texture {
|
||||
case RGBA_INTEGER:
|
||||
n = 4;
|
||||
break;
|
||||
|
||||
default: throw new IllegalStateException("unsupported format enum");
|
||||
}
|
||||
|
||||
int bpp = n;
|
||||
switch (type) {
|
||||
case UBYTE:
|
||||
case BYTE:
|
||||
case COMPRESSED:
|
||||
// nothing to do
|
||||
break;
|
||||
case USHORT:
|
||||
@@ -531,6 +530,9 @@ public class Texture {
|
||||
// Special case, format must be RGB and uses 4 bytes
|
||||
bpp = 4;
|
||||
break;
|
||||
case USHORT_565:
|
||||
bpp = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
int bpr = bpp * stride;
|
||||
@@ -562,6 +564,17 @@ public class Texture {
|
||||
return nIsTextureFormatSupported(engine.getNativeObject(), format.ordinal());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether texture swizzling is supported in this {@link Engine}.
|
||||
* This depends on the selected backend.
|
||||
*
|
||||
* @param engine {@link Engine}
|
||||
* @return <code>true</code> if texture swizzling.
|
||||
*/
|
||||
public static boolean isTextureSwizzleSupported(@NonNull Engine engine) {
|
||||
return nIsTextureSwizzleSupported(engine.getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Use <code>Builder</code> to construct a <code>Texture</code> object instance.
|
||||
*/
|
||||
@@ -678,6 +691,26 @@ public class Texture {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a native texture to import as a Filament texture.
|
||||
* <p>
|
||||
* The texture id is backend-specific:
|
||||
* <ul>
|
||||
* <li> OpenGL: GLuint texture ID </li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @param id a backend specific texture identifier
|
||||
*
|
||||
* @return This Builder, for chaining calls.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder importTexture(long id) {
|
||||
nBuilderImportTexture(mNativeBuilder, id);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>Texture</code> instance.
|
||||
* @param engine The {@link Engine} to associate this <code>Texture</code> with.
|
||||
@@ -882,7 +915,7 @@ public class Texture {
|
||||
* @param level Level to set the image for. Must be less than {@link #getLevels()}.
|
||||
* @param xoffset x-offset in texel of the region to modify
|
||||
* @param yoffset y-offset in texel of the region to modify
|
||||
* @param yoffset z-offset in texel of the region to modify
|
||||
* @param zoffset z-offset in texel of the region to modify
|
||||
* @param width width in texel of the region to modify
|
||||
* @param height height in texel of the region to modify
|
||||
* @param depth depth in texel or index of the region to modify
|
||||
@@ -1137,6 +1170,7 @@ public class Texture {
|
||||
}
|
||||
|
||||
private static native boolean nIsTextureFormatSupported(long nativeEngine, int internalFormat);
|
||||
private static native boolean nIsTextureSwizzleSupported(long nativeEngine);
|
||||
|
||||
private static native long nCreateBuilder();
|
||||
private static native void nDestroyBuilder(long nativeBuilder);
|
||||
@@ -1149,6 +1183,7 @@ public class Texture {
|
||||
private static native void nBuilderFormat(long nativeBuilder, int format);
|
||||
private static native void nBuilderUsage(long nativeBuilder, int flags);
|
||||
private static native void nBuilderSwizzle(long nativeBuilder, int r, int g, int b, int a);
|
||||
private static native void nBuilderImportTexture(long nativeBuilder, long id);
|
||||
private static native long nBuilderBuild(long nativeBuilder, long nativeEngine);
|
||||
|
||||
private static native int nGetWidth(long nativeTexture, int level);
|
||||
@@ -1160,35 +1195,35 @@ public class Texture {
|
||||
|
||||
private static native int nSetImage(long nativeTexture, long nativeEngine,
|
||||
int level, int xoffset, int yoffset, int width, int height,
|
||||
Buffer storage, int remaining, int left, int bottom, int type, int alignment,
|
||||
Buffer storage, int remaining, int left, int top, int type, int alignment,
|
||||
int stride, int format,
|
||||
Object handler, Runnable callback);
|
||||
|
||||
private static native int nSetImageCompressed(long nativeTexture, long nativeEngine,
|
||||
int level, int xoffset, int yoffset, int width, int height,
|
||||
Buffer storage, int remaining, int left, int bottom, int type, int alignment,
|
||||
Buffer storage, int remaining, int left, int top, int type, int alignment,
|
||||
int compressedSizeInBytes, int compressedFormat,
|
||||
Object handler, Runnable callback);
|
||||
|
||||
private static native int nSetImage3D(long nativeTexture, long nativeEngine,
|
||||
int level, int xoffset, int yoffset, int zoffset, int width, int height, int depth,
|
||||
Buffer storage, int remaining, int left, int bottom, int type, int alignment,
|
||||
Buffer storage, int remaining, int left, int top, int type, int alignment,
|
||||
int stride, int format,
|
||||
Object handler, Runnable callback);
|
||||
|
||||
private static native int nSetImage3DCompressed(long nativeTexture, long nativeEngine,
|
||||
int level, int xoffset, int yoffset, int zoffset, int width, int height, int depth,
|
||||
Buffer storage, int remaining, int left, int bottom, int type, int alignment,
|
||||
Buffer storage, int remaining, int left, int top, int type, int alignment,
|
||||
int compressedSizeInBytes, int compressedFormat,
|
||||
Object handler, Runnable callback);
|
||||
|
||||
private static native int nSetImageCubemap(long nativeTexture, long nativeEngine,
|
||||
int level, Buffer storage, int remaining, int left, int bottom, int type,
|
||||
int level, Buffer storage, int remaining, int left, int top, int type,
|
||||
int alignment, int stride, int format,
|
||||
int[] faceOffsetsInBytes, Object handler, Runnable callback);
|
||||
|
||||
private static native int nSetImageCubemapCompressed(long nativeTexture, long nativeEngine,
|
||||
int level, Buffer storage, int remaining, int left, int bottom, int type,
|
||||
int level, Buffer storage, int remaining, int left, int top, int type,
|
||||
int alignment, int compressedSizeInBytes, int compressedFormat,
|
||||
int[] faceOffsetsInBytes, Object handler, Runnable callback);
|
||||
|
||||
|
||||
@@ -140,6 +140,19 @@ import androidx.annotation.Size;
|
||||
nSetParent(mNativeObject, i, newParent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the actual parent entity of an {@link EntityInstance} originally defined
|
||||
* by {@link #setParent(int, int)}.
|
||||
*
|
||||
* @param i the {@link EntityInstance} of the transform component to get the parent from.
|
||||
* @return the parent {@link Entity}.
|
||||
* @see #getInstance
|
||||
*/
|
||||
@Entity
|
||||
public int getParent(@EntityInstance int i) {
|
||||
return nGetParent(mNativeObject, i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a local transform of a transform component.
|
||||
* <p>This operation can be slow if the hierarchy of transform is too deep, and this
|
||||
@@ -241,6 +254,7 @@ import androidx.annotation.Size;
|
||||
private static native int nCreateArray(long mNativeObject, int entity, int parent, float[] localTransform);
|
||||
private static native void nDestroy(long nativeTransformManager, int entity);
|
||||
private static native void nSetParent(long nativeTransformManager, int i, int newParent);
|
||||
private static native int nGetParent(long nativeTransformManager, int i);
|
||||
private static native void nSetTransform(long nativeTransformManager, int i, float[] localTransform);
|
||||
private static native void nGetTransform(long nativeTransformManager, int i, float[] outLocalTransform);
|
||||
private static native void nGetWorldTransform(long nativeTransformManager, int i, float[] outWorldTransform);
|
||||
|
||||
@@ -104,48 +104,6 @@ public class VertexBuffer {
|
||||
HALF3,
|
||||
HALF4,
|
||||
}
|
||||
/**
|
||||
* Specifies the quaternion type for the {@link #populateTangentQuaternions} utility.
|
||||
*/
|
||||
public enum QuatType {
|
||||
/** 2 bytes per component as half-floats (8 bytes per quat) */
|
||||
HALF4,
|
||||
|
||||
/** 2 bytes per component as normalized integers (8 bytes per quat) */
|
||||
SHORT4,
|
||||
|
||||
/** 4 bytes per component as floats (16 bytes per quat) */
|
||||
FLOAT4,
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the parameters for the {@link #populateTangentQuaternions} utility.
|
||||
*/
|
||||
public static class QuatTangentContext {
|
||||
/** desired quaternion type (required) */
|
||||
public QuatType quatType;
|
||||
|
||||
/** number of quaternions (required) */
|
||||
public int quatCount;
|
||||
|
||||
/** pre-allocated output buffer (required) */
|
||||
public Buffer outBuffer;
|
||||
|
||||
/** desired stride in bytes (optional) */
|
||||
public int outStride;
|
||||
|
||||
/** source normals (required) */
|
||||
public Buffer normals;
|
||||
|
||||
/** normals stride in bytes (optional) */
|
||||
public int normalsStride;
|
||||
|
||||
/** source tangents (optional) */
|
||||
public Buffer tangents;
|
||||
|
||||
/** tangents stride in bytes (optional) */
|
||||
public int tangentsStride;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) // Keep to finalize native resources
|
||||
@@ -170,6 +128,21 @@ public class VertexBuffer {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows buffers to be swapped out and shared using BufferObject.
|
||||
*
|
||||
* If buffer objects mode is enabled, clients must call setBufferObjectAt rather than
|
||||
* setBufferAt. This allows sharing of data between VertexBuffer objects, but it may
|
||||
* slightly increase the memory footprint of Filament's internal bookkeeping.
|
||||
*
|
||||
* @param enabled If true, enables buffer object mode. False by default.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder enableBufferObjects(boolean enabled) {
|
||||
nBuilderEnableBufferObjects(mNativeBuilder, enabled);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines how many buffers will be created in this vertex buffer set. These buffers are
|
||||
* later referenced by index from 0 to <code>bufferCount</code> - 1.
|
||||
@@ -397,36 +370,21 @@ public class VertexBuffer {
|
||||
throw new BufferOverflowException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience function that consumes normal vectors (and, optionally, tangent vectors) and
|
||||
* produces quaternions that can be passed into a TANGENTS buffer.
|
||||
* Swaps in the given buffer object.
|
||||
*
|
||||
* <p>
|
||||
* The given output buffer must be preallocated with at least quatCount * outStride bytes.
|
||||
* <p>
|
||||
* To use this, you must first call enableBufferObjects() on the Builder.
|
||||
*
|
||||
* <p>
|
||||
* Normals are required but tangents are optional, in which case this function tries to generate
|
||||
* reasonable tangents. The given normals should be unit length.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* If supplied, the tangent vectors should be unit length and should be orthogonal to the
|
||||
* normals. The w component of the tangent is a sign (-1 or +1) indicating handedness of the
|
||||
* basis.
|
||||
* </p>
|
||||
*
|
||||
* @deprecated Instead please use SurfaceOrientation since it has additional capabilities and a
|
||||
* builder-style API.
|
||||
*
|
||||
* @param context an initialized QuatTangentContext object
|
||||
* @param engine Reference to the filament::Engine to associate this VertexBuffer with.
|
||||
* @param bufferIndex Index of the buffer to initialize. Must be between 0
|
||||
* and Builder::bufferCount() - 1.
|
||||
* @param bufferObject The handle to the GPU data that will be used in this buffer slot.
|
||||
*/
|
||||
public static void populateTangentQuaternions(@NonNull QuatTangentContext context) {
|
||||
nPopulateTangentQuaternions(context.quatType.ordinal(), context.quatCount,
|
||||
context.outBuffer, context.outBuffer.remaining(), context.outStride,
|
||||
context.normals, context.normals.remaining(), context.normalsStride,
|
||||
context.tangents, context.tangents != null ? context.tangents.remaining() : 0,
|
||||
context.tangentsStride);
|
||||
public void setBufferObjectAt(@NonNull Engine engine, int bufferIndex,
|
||||
@NonNull BufferObject bufferObject) {
|
||||
nSetBufferObjectAt(getNativeObject(), engine.getNativeObject(), bufferIndex,
|
||||
bufferObject.getNativeObject());
|
||||
}
|
||||
|
||||
public long getNativeObject() {
|
||||
@@ -443,6 +401,7 @@ public class VertexBuffer {
|
||||
private static native long nCreateBuilder();
|
||||
private static native void nDestroyBuilder(long nativeBuilder);
|
||||
private static native void nBuilderVertexCount(long nativeBuilder, int vertexCount);
|
||||
private static native void nBuilderEnableBufferObjects(long nativeBuilder, boolean enabled);
|
||||
private static native void nBuilderBufferCount(long nativeBuilder, int bufferCount);
|
||||
private static native void nBuilderAttribute(long nativeBuilder, int attribute,
|
||||
int bufferIndex, int attributeType, int byteOffset, int byteStride);
|
||||
@@ -455,7 +414,6 @@ public class VertexBuffer {
|
||||
int bufferIndex, Buffer buffer, int remaining, int destOffsetInBytes, int count,
|
||||
Object handler, Runnable callback);
|
||||
|
||||
private static native void nPopulateTangentQuaternions(int quatType, int quatCount,
|
||||
Buffer outBuffer, int outRemaining, int outStride, Buffer normals, int normalsRemaining,
|
||||
int normalsStride, Buffer tangents, int tangentsRemaining, int tangentsStride);
|
||||
private static native void nSetBufferObjectAt(long nativeVertexBuffer, long nativeEngine,
|
||||
int bufferIndex, long nativeBufferObject);
|
||||
}
|
||||
|
||||
@@ -266,7 +266,7 @@ public class View {
|
||||
|
||||
/**
|
||||
* Options for Temporal Anti-aliasing (TAA)
|
||||
* @see View#setTemporalAntiAliasingOptions()
|
||||
* @see View#setTemporalAntiAliasingOptions
|
||||
*/
|
||||
public static class TemporalAntiAliasingOptions {
|
||||
/** reconstruction filter width typically between 0 (sharper, aliased) and 1 (smoother) */
|
||||
@@ -284,11 +284,11 @@ public class View {
|
||||
*
|
||||
* enabled: Enable or disable the bloom post-processing effect. Disabled by default.
|
||||
* levels: Number of successive blurs to achieve the blur effect, the minimum is 3 and the
|
||||
* maximum is 12. This value together with resolution influences the spread of the
|
||||
* maximum is 11. This value together with resolution influences the spread of the
|
||||
* blur effect. This value can be silently reduced to accommodate the original
|
||||
* image size.
|
||||
* resolution: Resolution of bloom's minor axis. The minimum value is 2^levels and the
|
||||
* the maximum is lower of the original resolution and 4096. This parameter is
|
||||
* resolution: Resolution of bloom's vertical axis. The minimum value is 2^levels and the
|
||||
* the maximum is lower of the original resolution and 2048. This parameter is
|
||||
* silently clamped to the minimum and maximum.
|
||||
* It is highly recommended that this value be smaller than the target resolution
|
||||
* after dynamic resolution is applied (horizontally and vertically).
|
||||
@@ -329,7 +329,7 @@ public class View {
|
||||
public float strength = 0.10f;
|
||||
|
||||
/**
|
||||
* Resolution of minor axis (2^levels to 4096)
|
||||
* Resolution of minor axis (2^levels to 2048)
|
||||
*/
|
||||
public int resolution = 360;
|
||||
|
||||
@@ -339,7 +339,7 @@ public class View {
|
||||
public float anamorphism = 1.0f;
|
||||
|
||||
/**
|
||||
* Number of blur levels (3 to 12)
|
||||
* Number of blur levels (3 to 11)
|
||||
*/
|
||||
public int levels = 6;
|
||||
|
||||
@@ -363,6 +363,52 @@ public class View {
|
||||
* minimum value is 10.0.
|
||||
*/
|
||||
public float highlight = 1000.0f;
|
||||
|
||||
|
||||
/**
|
||||
* enable screen-space lens flare
|
||||
*/
|
||||
public boolean lensFlare = false;
|
||||
|
||||
/**
|
||||
* enable starburst effect on lens flare
|
||||
*/
|
||||
public boolean starburst = true;
|
||||
|
||||
/**
|
||||
* amount of chromatic aberration
|
||||
*/
|
||||
public float chromaticAberration = 0.005f;
|
||||
|
||||
/**
|
||||
* number of flare "ghosts"
|
||||
*/
|
||||
public int ghostCount = 4;
|
||||
|
||||
/**
|
||||
* spacing of the ghost in screen units [0, 1[
|
||||
*/
|
||||
public float ghostSpacing = 0.6f;
|
||||
|
||||
/**
|
||||
* hdr threshold for the ghosts
|
||||
*/
|
||||
public float ghostThreshold = 10.0f;
|
||||
|
||||
/**
|
||||
* thickness of halo in vertical screen units, 0 to disable
|
||||
*/
|
||||
public float haloThickness = 0.1f;
|
||||
|
||||
/**
|
||||
* radius of halo in vertical screen units [0, 0.5]
|
||||
*/
|
||||
public float haloRadius = 0.4f;
|
||||
|
||||
/**
|
||||
* hdr threshold for the halo
|
||||
*/
|
||||
public float haloThreshold = 10.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -431,8 +477,10 @@ public class View {
|
||||
*/
|
||||
public static class DepthOfFieldOptions {
|
||||
|
||||
/** focus distance in world units */
|
||||
public float focusDistance = 10.0f;
|
||||
public enum Filter {
|
||||
NONE,
|
||||
MEDIAN
|
||||
}
|
||||
|
||||
/**
|
||||
* circle of confusion scale factor (amount of blur)
|
||||
@@ -451,6 +499,59 @@ public class View {
|
||||
|
||||
/** enable or disable Depth of field effect */
|
||||
public boolean enabled = false;
|
||||
|
||||
/** filter to use for filling gaps in the kernel */
|
||||
@NonNull
|
||||
public Filter filter = Filter.MEDIAN;
|
||||
|
||||
/** perform DoF processing at native resolution */
|
||||
public boolean nativeResolution = false;
|
||||
|
||||
/**
|
||||
* <p>Number of of rings used by the foreground kernel. The number of rings affects quality
|
||||
* and performance. The actual number of sample per pixel is defined
|
||||
* as (ringCount * 2 - 1)^2. Here are a few commonly used values:</p>
|
||||
* 3 rings : 25 ( 5x 5 grid)
|
||||
* 4 rings : 49 ( 7x 7 grid)
|
||||
* 5 rings : 81 ( 9x 9 grid)
|
||||
* 17 rings : 1089 (33x33 grid)
|
||||
*
|
||||
* <p>With a maximum circle-of-confusion of 32, it is never necessary to use more than 17 rings.</p>
|
||||
*
|
||||
* <p>Usually all three settings below are set to the same value, however, it is often
|
||||
* acceptable to use a lower ring count for the "fast tiles", which improves performance.
|
||||
* Fast tiles are regions of the screen where every pixels have a similar
|
||||
* circle-of-confusion radius.</p>
|
||||
*
|
||||
* <p>A value of 0 means default, which is 5 on desktop and 3 on mobile.</p>
|
||||
*/
|
||||
public int foregroundRingCount = 0;
|
||||
|
||||
/**
|
||||
* Number of of rings used by the background kernel. The number of rings affects quality
|
||||
* and performance.
|
||||
* @see #foregroundRingCount
|
||||
*/
|
||||
public int backgroundRingCount = 0;
|
||||
|
||||
/**
|
||||
* Number of of rings used by the fast gather kernel. The number of rings affects quality
|
||||
* and performance.
|
||||
* @see #foregroundRingCount
|
||||
*/
|
||||
public int fastGatherRingCount = 0;
|
||||
|
||||
/**
|
||||
* maximum circle-of-confusion in pixels for the foreground, must be in [0, 32] range.
|
||||
* A value of 0 means default, which is 32 on desktop and 24 on mobile.
|
||||
*/
|
||||
public int maxForegroundCOC = 0;
|
||||
|
||||
/**
|
||||
* maximum circle-of-confusion in pixels for the background, must be in [0, 32] range.
|
||||
* A value of 0 means default, which is 32 on desktop and 24 on mobile.
|
||||
*/
|
||||
public int maxBackgroundCOC = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -830,16 +931,6 @@ public class View {
|
||||
nSetShadowingEnabled(getNativeObject(), enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables shadow mapping. Enabled by default.
|
||||
*
|
||||
* @deprecated Use {@link #setShadowingEnabled}
|
||||
*/
|
||||
@Deprecated
|
||||
public void setShadowsEnabled(boolean enabled) {
|
||||
setShadowingEnabled(enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether shadowing is enabled
|
||||
*/
|
||||
@@ -1294,7 +1385,10 @@ public class View {
|
||||
nSetBloomOptions(getNativeObject(), options.dirt != null ? options.dirt.getNativeObject() : 0,
|
||||
options.dirtStrength, options.strength, options.resolution,
|
||||
options.anamorphism, options.levels, options.blendingMode.ordinal(),
|
||||
options.threshold, options.enabled, options.highlight);
|
||||
options.threshold, options.enabled, options.highlight,
|
||||
options.lensFlare, options.starburst, options.chromaticAberration,
|
||||
options.ghostCount, options.ghostSpacing, options.ghostThreshold,
|
||||
options.haloThickness, options.haloRadius, options.haloThreshold);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1379,7 +1473,10 @@ public class View {
|
||||
*/
|
||||
public void setDepthOfFieldOptions(@NonNull DepthOfFieldOptions options) {
|
||||
mDepthOfFieldOptions = options;
|
||||
nSetDepthOfFieldOptions(getNativeObject(), options.focusDistance, options.cocScale, options.maxApertureDiameter, options.enabled);
|
||||
nSetDepthOfFieldOptions(getNativeObject(), options.cocScale,
|
||||
options.maxApertureDiameter, options.enabled, options.filter.ordinal(),
|
||||
options.nativeResolution, options.foregroundRingCount, options.backgroundRingCount,
|
||||
options.fastGatherRingCount, options.maxForegroundCOC, options.maxBackgroundCOC);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1435,10 +1532,12 @@ public class View {
|
||||
private static native int nGetAmbientOcclusion(long nativeView);
|
||||
private static native void nSetAmbientOcclusionOptions(long nativeView, float radius, float bias, float power, float resolution, float intensity, int quality, int lowPassFilter, int upsampling, boolean enabled, float minHorizonAngleRad);
|
||||
private static native void nSetSSCTOptions(long nativeView, float ssctLightConeRad, float ssctStartTraceDistance, float ssctContactDistanceMax, float ssctIntensity, float v, float v1, float v2, float ssctDepthBias, float ssctDepthSlopeBias, int ssctSampleCount, int ssctRayCount, boolean ssctEnabled);
|
||||
private static native void nSetBloomOptions(long nativeView, long dirtNativeObject, float dirtStrength, float strength, int resolution, float anamorphism, int levels, int blendMode, boolean threshold, boolean enabled, float highlight);
|
||||
private static native void nSetBloomOptions(long nativeView, long dirtNativeObject, float dirtStrength, float strength, int resolution, float anamorphism, int levels, int blendMode, boolean threshold, boolean enabled, float highlight,
|
||||
boolean lensFlare, boolean starburst, float chromaticAberration, int ghostCount, float ghostSpacing, float ghostThreshold, float haloThickness, float haloRadius, float haloThreshold);
|
||||
private static native void nSetFogOptions(long nativeView, float distance, float maximumOpacity, float height, float heightFalloff, float v, float v1, float v2, float density, float inScatteringStart, float inScatteringSize, boolean fogColorFromIbl, boolean enabled);
|
||||
private static native void nSetBlendMode(long nativeView, int blendMode);
|
||||
private static native void nSetDepthOfFieldOptions(long nativeView, float focusDistance, float cocScale, float maxApertureDiameter, boolean enabled);
|
||||
private static native void nSetDepthOfFieldOptions(long nativeView, float cocScale, float maxApertureDiameter, boolean enabled, int filter,
|
||||
boolean nativeResolution, int foregroundRingCount, int backgroundRingCount, int fastGatherRingCount, int maxForegroundCOC, int maxBackgroundCOC);
|
||||
private static native void nSetVignetteOptions(long nativeView, float midPoint, float roundness, float feather, float r, float g, float b, float a, boolean enabled);
|
||||
private static native void nSetTemporalAntiAliasingOptions(long nativeView, float feedback, float filterWidth, boolean enabled);
|
||||
private static native boolean nIsShadowingEnabled(long nativeView);
|
||||
|
||||
@@ -23,8 +23,6 @@ import androidx.annotation.NonNull;
|
||||
import com.google.android.filament.Engine;
|
||||
import com.google.android.filament.Texture;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public final class TextureHelper {
|
||||
// Keep in sync with Texture.cpp
|
||||
private static final int BITMAP_CONFIG_ALPHA_8 = 0;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
cmake_minimum_required(VERSION 3.6)
|
||||
cmake_minimum_required(VERSION 3.19)
|
||||
project(filament-utils-android)
|
||||
|
||||
set(FILAMENT_DIR ${FILAMENT_DIST_DIR})
|
||||
set(IMAGEIO_DIR ../../libs/imageio)
|
||||
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../gltfio-android ${CMAKE_CURRENT_BINARY_DIR}/gltfio-android)
|
||||
|
||||
@@ -12,27 +14,54 @@ add_library(image STATIC IMPORTED)
|
||||
set_target_properties(image PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libimage.a)
|
||||
|
||||
include_directories(${FILAMENT_DIR}/include
|
||||
..
|
||||
../../libs/utils/include)
|
||||
add_library(viewer STATIC IMPORTED)
|
||||
set_target_properties(viewer PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libviewer.a)
|
||||
|
||||
add_library(civetweb STATIC IMPORTED)
|
||||
set_target_properties(civetweb PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libcivetweb.a)
|
||||
|
||||
add_library(iblprefilter STATIC IMPORTED)
|
||||
set_target_properties(iblprefilter PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libfilament-iblprefilter.a)
|
||||
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/libfilament-utils-jni.map")
|
||||
|
||||
add_library(filament-utils-jni SHARED
|
||||
src/main/cpp/AutomationEngine.cpp
|
||||
src/main/cpp/Bookmark.cpp
|
||||
src/main/cpp/HDRLoader.cpp
|
||||
src/main/cpp/IBLPrefilterContext.cpp
|
||||
src/main/cpp/Utils.cpp
|
||||
src/main/cpp/Manipulator.cpp
|
||||
src/main/cpp/RemoteServer.cpp
|
||||
|
||||
${IMAGEIO_DIR}/include/imageio/ImageDecoder.h
|
||||
${IMAGEIO_DIR}/include/imageio/HDRDecoder.h
|
||||
${IMAGEIO_DIR}/src/HDRDecoder.cpp
|
||||
|
||||
../common/CallbackUtils.cpp
|
||||
../common/NioUtils.cpp
|
||||
)
|
||||
|
||||
target_compile_definitions(filament-utils-jni PUBLIC IMAGEIO_LITE=1)
|
||||
|
||||
target_include_directories(filament-utils-jni PRIVATE
|
||||
${FILAMENT_DIR}/include
|
||||
..
|
||||
${IMAGEIO_DIR}/include
|
||||
../../libs/utils/include)
|
||||
|
||||
set_target_properties(filament-utils-jni PROPERTIES LINK_DEPENDS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libfilament-utils-jni.symbols)
|
||||
|
||||
# The ordering in the following list is important because CMake does not have dependency information.
|
||||
target_link_libraries(filament-utils-jni
|
||||
gltfio-jni
|
||||
civetweb
|
||||
camutils
|
||||
iblprefilter
|
||||
image
|
||||
viewer
|
||||
)
|
||||
|
||||
@@ -45,7 +45,7 @@ dependencies {
|
||||
implementation deps.androidx.annotations
|
||||
implementation project(':filament-android')
|
||||
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.3'
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.8'
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.3'
|
||||
|
||||
fullImplementation module("com.google.android.filament:gltfio-android:${VERSION_NAME}")
|
||||
|
||||
179
android/filament-utils-android/src/main/cpp/AutomationEngine.cpp
Normal file
179
android/filament-utils-android/src/main/cpp/AutomationEngine.cpp
Normal file
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* 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 <jni.h>
|
||||
|
||||
#include <viewer/AutomationEngine.h>
|
||||
|
||||
using namespace filament;
|
||||
using namespace filament::viewer;
|
||||
using namespace utils;
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_utils_AutomationEngine_nCreateAutomationEngine(JNIEnv* env, jclass,
|
||||
jstring spec_) {
|
||||
const char* spec = env->GetStringUTFChars(spec_, 0);
|
||||
jlong result = (jlong) AutomationEngine::createFromJSON(spec, strlen(spec));
|
||||
env->ReleaseStringUTFChars(spec_, spec);
|
||||
return result;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_utils_AutomationEngine_nCreateDefaultAutomationEngine(JNIEnv* env,
|
||||
jclass klass) {
|
||||
return (jlong) AutomationEngine::createDefault();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_utils_AutomationEngine_nSetOptions(JNIEnv* env, jclass klass,
|
||||
jlong nativeAutomation, jfloat sleepDuration, jint minFrameCount, jboolean verbose) {
|
||||
AutomationEngine* automation = (AutomationEngine*) nativeAutomation;
|
||||
AutomationEngine::Options options = {
|
||||
.sleepDuration = sleepDuration,
|
||||
.minFrameCount = minFrameCount,
|
||||
.verbose = (bool) verbose,
|
||||
|
||||
// Since they write to the filesystem, we do not currently support exporting screenshots
|
||||
// and JSON files on Android.
|
||||
.exportScreenshots = false,
|
||||
.exportSettings = false,
|
||||
};
|
||||
automation->setOptions(options);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_utils_AutomationEngine_nStartRunning(JNIEnv* env, jclass klass,
|
||||
jlong nativeAutomation) {
|
||||
AutomationEngine* automation = (AutomationEngine*) nativeAutomation;
|
||||
automation->startRunning();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_utils_AutomationEngine_nStartBatchMode(JNIEnv* env, jclass klass,
|
||||
jlong nativeAutomation) {
|
||||
AutomationEngine* automation = (AutomationEngine*) nativeAutomation;
|
||||
automation->startBatchMode();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_utils_AutomationEngine_nTick(JNIEnv* env, jclass klass,
|
||||
jlong nativeAutomation, jlong view, jlongArray materials, jlong renderer, jfloat deltaTime) {
|
||||
using MaterialPointer = MaterialInstance*;
|
||||
jsize materialCount = 0;
|
||||
jlong* longMaterials = nullptr;
|
||||
MaterialPointer* ptrMaterials = nullptr;
|
||||
if (materials) {
|
||||
materialCount = env->GetArrayLength(materials);
|
||||
ptrMaterials = new MaterialPointer[materialCount];
|
||||
longMaterials = env->GetLongArrayElements(materials, nullptr);
|
||||
for (jsize i = 0; i < materialCount; i++) {
|
||||
ptrMaterials[i] = (MaterialPointer) longMaterials[i];
|
||||
}
|
||||
}
|
||||
AutomationEngine* automation = (AutomationEngine*) nativeAutomation;
|
||||
automation->tick((View*) view, ptrMaterials, materialCount, (Renderer*) renderer, deltaTime);
|
||||
if (longMaterials) {
|
||||
env->ReleaseLongArrayElements(materials, longMaterials, 0);
|
||||
delete[] ptrMaterials;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_utils_AutomationEngine_nApplySettings(JNIEnv* env, jclass klass,
|
||||
jlong nativeAutomation, jstring json, jlong view, jlongArray materials, jlong nativeIbl,
|
||||
jint lightEntity, jlong nativeLm, jlong scene, jlong renderer) {
|
||||
using MaterialPointer = MaterialInstance*;
|
||||
jsize materialCount = 0;
|
||||
jlong* longMaterials = nullptr;
|
||||
MaterialPointer* ptrMaterials = nullptr;
|
||||
if (materials) {
|
||||
materialCount = env->GetArrayLength(materials);
|
||||
ptrMaterials = new MaterialPointer[materialCount];
|
||||
longMaterials = env->GetLongArrayElements(materials, nullptr);
|
||||
for (jsize i = 0; i < materialCount; i++) {
|
||||
ptrMaterials[i] = (MaterialPointer) longMaterials[i];
|
||||
}
|
||||
}
|
||||
AutomationEngine* automation = (AutomationEngine*) nativeAutomation;
|
||||
const char* nativeJson = env->GetStringUTFChars(json, 0);
|
||||
size_t jsonLength = env->GetStringUTFLength(json);
|
||||
automation->applySettings(nativeJson, jsonLength, (View*) view, ptrMaterials, materialCount,
|
||||
(IndirectLight*) nativeIbl, (Entity&) lightEntity, (LightManager*) nativeLm,
|
||||
(Scene*) scene, (Renderer*) renderer);
|
||||
env->ReleaseStringUTFChars(json, nativeJson);
|
||||
if (longMaterials) {
|
||||
env->ReleaseLongArrayElements(materials, longMaterials, 0);
|
||||
delete[] ptrMaterials;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_utils_AutomationEngine_nGetViewerOptions(JNIEnv* env, jclass,
|
||||
jlong nativeObject, jobject result) {
|
||||
AutomationEngine* automation = (AutomationEngine*) nativeObject;
|
||||
auto options = automation->getViewerOptions();
|
||||
|
||||
const jclass klass = env->GetObjectClass(result);
|
||||
|
||||
const jfieldID cameraAperture = env->GetFieldID(klass, "cameraAperture", "F");
|
||||
const jfieldID cameraSpeed = env->GetFieldID(klass, "cameraSpeed", "F");
|
||||
const jfieldID cameraISO = env->GetFieldID(klass, "cameraISO", "F");
|
||||
const jfieldID groundShadowStrength = env->GetFieldID(klass, "groundShadowStrength", "F");
|
||||
const jfieldID groundPlaneEnabled = env->GetFieldID(klass, "groundPlaneEnabled", "Z");
|
||||
const jfieldID skyboxEnabled = env->GetFieldID(klass, "skyboxEnabled", "Z");
|
||||
const jfieldID cameraFocalLength = env->GetFieldID(klass, "cameraFocalLength", "F");
|
||||
const jfieldID cameraFocusDistance = env->GetFieldID(klass, "cameraFocusDistance", "F");
|
||||
|
||||
env->SetFloatField(result, cameraAperture, options.cameraAperture);
|
||||
env->SetFloatField(result, cameraSpeed, options.cameraSpeed);
|
||||
env->SetFloatField(result, cameraISO, options.cameraISO);
|
||||
env->SetFloatField(result, groundShadowStrength, options.groundShadowStrength);
|
||||
env->SetBooleanField(result, groundPlaneEnabled, options.groundPlaneEnabled);
|
||||
env->SetBooleanField(result, skyboxEnabled, options.skyboxEnabled);
|
||||
env->SetFloatField(result, cameraFocalLength, options.cameraFocalLength);
|
||||
env->SetFloatField(result, cameraFocusDistance, options.cameraFocusDistance);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_utils_AutomationEngine_nGetColorGrading(JNIEnv*, jclass,
|
||||
jlong nativeObject, jlong nativeEngine) {
|
||||
AutomationEngine* automation = (AutomationEngine*) nativeObject;
|
||||
return (jlong) automation->getColorGrading((Engine*) nativeEngine);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_utils_AutomationEngine_nSignalBatchMode(JNIEnv*, jclass, jlong native) {
|
||||
AutomationEngine* automation = (AutomationEngine*) native;
|
||||
automation->signalBatchMode();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_utils_AutomationEngine_nStopRunning(JNIEnv*, jclass, jlong native) {
|
||||
AutomationEngine* automation = (AutomationEngine*) native;
|
||||
automation->stopRunning();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_utils_AutomationEngine_nShouldClose(JNIEnv*, jclass, jlong native) {
|
||||
AutomationEngine* automation = (AutomationEngine*) native;
|
||||
return automation->shouldClose();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_utils_AutomationEngine_nDestroy(JNIEnv*, jclass, jlong native) {
|
||||
AutomationEngine* automation = (AutomationEngine*) native;
|
||||
delete automation;
|
||||
}
|
||||
91
android/filament-utils-android/src/main/cpp/HDRLoader.cpp
Normal file
91
android/filament-utils-android/src/main/cpp/HDRLoader.cpp
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* 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 <jni.h>
|
||||
|
||||
#include <filament/Engine.h>
|
||||
#include <filament/Texture.h>
|
||||
|
||||
#include <imageio/HDRDecoder.h>
|
||||
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "common/NioUtils.h"
|
||||
|
||||
using namespace filament;
|
||||
using namespace image;
|
||||
using namespace utils;
|
||||
|
||||
using PixelBufferDescriptor = Texture::PixelBufferDescriptor;
|
||||
|
||||
jlong nCreateHDRTexture(JNIEnv* env, jclass,
|
||||
jlong nativeEngine, jobject javaBuffer, jint remaining, jint internalFormat) {
|
||||
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
AutoBuffer buffer(env, javaBuffer, remaining);
|
||||
Texture::InternalFormat textureFormat = (Texture::InternalFormat) internalFormat;
|
||||
|
||||
auto dataPtr = (char const*) buffer.getData();
|
||||
const size_t byteCount = buffer.getSize();
|
||||
|
||||
// This creates a copy but it's the easest way to create a memory stream.
|
||||
std::string ins(dataPtr, byteCount);
|
||||
std::istringstream in(ins);
|
||||
|
||||
LinearImage* image = new LinearImage(ImageDecoder::decode(in, "memory.hdr"));
|
||||
|
||||
// This can happen if a decoding error occurs.
|
||||
if (image->getChannels() != 3) {
|
||||
delete image;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Texture* texture = Texture::Builder()
|
||||
.width(image->getWidth())
|
||||
.height(image->getHeight())
|
||||
.levels(0xff)
|
||||
.sampler(Texture::Sampler::SAMPLER_2D)
|
||||
.format(textureFormat)
|
||||
.build(*engine);
|
||||
|
||||
if (texture == nullptr) {
|
||||
slog.e << "Unable to create Filament Texture from HDR image." << io::endl;
|
||||
delete image;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PixelBufferDescriptor::Callback freeCallback = [](void* buf, size_t, void* userdata) {
|
||||
delete (LinearImage*) userdata;
|
||||
};
|
||||
|
||||
PixelBufferDescriptor pbd(
|
||||
(void const* ) image->getPixelRef(),
|
||||
image->getWidth() * image->getHeight() * 3 * sizeof(float),
|
||||
PixelBufferDescriptor::PixelDataFormat::RGB,
|
||||
PixelBufferDescriptor::PixelDataType::FLOAT,
|
||||
freeCallback,
|
||||
image);
|
||||
|
||||
// Note that the setImage call could fail (e.g. due to an invalid combination of internal format
|
||||
// and PixelDataFormat) but there is no way of detecting such a failure.
|
||||
texture->setImage(*engine, 0, std::move(pbd));
|
||||
|
||||
texture->generateMipmaps(*engine);
|
||||
|
||||
return (jlong) texture;
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* 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 <jni.h>
|
||||
|
||||
#include <filament-iblprefilter/IBLPrefilterContext.h>
|
||||
|
||||
#include <filament/Engine.h>
|
||||
#include <filament/Texture.h>
|
||||
|
||||
using namespace filament;
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_utils_IBLPrefilterContext_nCreate(JNIEnv* env, jclass,
|
||||
jlong nativeEngine) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
return (jlong) new IBLPrefilterContext(*engine);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_utils_IBLPrefilterContext_nDestroy(JNIEnv*, jclass, jlong native) {
|
||||
IBLPrefilterContext* context = (IBLPrefilterContext*) native;
|
||||
delete context;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT long JNICALL
|
||||
Java_com_google_android_filament_utils_IBLPrefilterContext_nCreateEquirectHelper(JNIEnv* env, jclass, jlong nativeContext) {
|
||||
IBLPrefilterContext* context = (IBLPrefilterContext*) nativeContext;
|
||||
return (long) new IBLPrefilterContext::EquirectangularToCubemap(*context);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT long JNICALL
|
||||
Java_com_google_android_filament_utils_IBLPrefilterContext_nEquirectHelperRun(JNIEnv* env, jclass, jlong nativeHelper, long nativeEquirect) {
|
||||
auto helper = (IBLPrefilterContext::EquirectangularToCubemap*) nativeHelper;
|
||||
auto texture = (filament::Texture*) nativeEquirect;
|
||||
auto result = (*helper)(texture);
|
||||
return (long) result;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_utils_IBLPrefilterContext_nDestroyEquirectHelper(JNIEnv* env, jclass, jlong nativeObject) {
|
||||
delete (IBLPrefilterContext::EquirectangularToCubemap*) nativeObject;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT long JNICALL
|
||||
Java_com_google_android_filament_utils_IBLPrefilterContext_nCreateSpecularFilter(JNIEnv* env, jclass, jlong nativeContext) {
|
||||
IBLPrefilterContext* context = (IBLPrefilterContext*) nativeContext;
|
||||
return (long) new IBLPrefilterContext::SpecularFilter(*context);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT long JNICALL
|
||||
Java_com_google_android_filament_utils_IBLPrefilterContext_nSpecularFilterRun(JNIEnv* env, jclass, jlong nativeHelper, long nativeSkybox) {
|
||||
auto helper = (IBLPrefilterContext::SpecularFilter*) nativeHelper;
|
||||
auto texture = (filament::Texture*) nativeSkybox;
|
||||
auto result = (*helper)(texture);
|
||||
return (long) result;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_utils_IBLPrefilterContext_nDestroySpecularFilter(JNIEnv* env, jclass, jlong nativeObject) {
|
||||
delete (IBLPrefilterContext::SpecularFilter*) nativeObject;
|
||||
}
|
||||
77
android/filament-utils-android/src/main/cpp/RemoteServer.cpp
Normal file
77
android/filament-utils-android/src/main/cpp/RemoteServer.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* 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 <jni.h>
|
||||
|
||||
#include <viewer/RemoteServer.h>
|
||||
|
||||
using namespace filament::viewer;
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_utils_RemoteServer_nCreate(JNIEnv* env, jclass, jint port) {
|
||||
RemoteServer* server = new RemoteServer(port);
|
||||
if (!server->isValid()) {
|
||||
delete server;
|
||||
return 0;
|
||||
}
|
||||
return (jlong) server;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_utils_RemoteServer_nDestroy(JNIEnv*, jclass, jlong native) {
|
||||
RemoteServer* server = (RemoteServer*) native;
|
||||
delete server;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jstring JNICALL
|
||||
Java_com_google_android_filament_utils_RemoteServer_nPeekIncomingLabel(JNIEnv* env, jclass, jlong native) {
|
||||
RemoteServer* server = (RemoteServer*) native;
|
||||
char const* label = server->peekIncomingLabel();
|
||||
return label ? env->NewStringUTF(label) : nullptr;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jstring JNICALL
|
||||
Java_com_google_android_filament_utils_RemoteServer_nPeekReceivedLabel(JNIEnv* env, jclass, jlong native) {
|
||||
RemoteServer* server = (RemoteServer*) native;
|
||||
ReceivedMessage const* msg = server->peekReceivedMessage();
|
||||
return msg ? env->NewStringUTF(msg->label) : nullptr;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_utils_RemoteServer_nPeekReceivedBufferLength(JNIEnv* env, jclass, jlong native) {
|
||||
RemoteServer* server = (RemoteServer*) native;
|
||||
ReceivedMessage const* msg = server->peekReceivedMessage();
|
||||
return msg ? msg->bufferByteCount : 0;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_utils_RemoteServer_nAcquireReceivedMessage(JNIEnv* env, jclass, jlong native, jobject buffer, jint length) {
|
||||
RemoteServer* server = (RemoteServer*) native;
|
||||
ReceivedMessage const* msg = server->acquireReceivedMessage();
|
||||
if (msg == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
void* address = env->GetDirectBufferAddress(buffer);
|
||||
if (address == nullptr) {
|
||||
// This should never happen because the Java layer does allocateDirect.
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(address, msg->buffer, length);
|
||||
server->releaseReceivedMessage(msg);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,10 @@ using namespace filament;
|
||||
using namespace filament::math;
|
||||
using namespace image;
|
||||
|
||||
static jlong nCreateTexture(JNIEnv* env, jclass,
|
||||
jlong nCreateHDRTexture(JNIEnv* env, jclass,
|
||||
jlong nativeEngine, jobject javaBuffer, jint remaining, jint internalFormat);
|
||||
|
||||
static jlong nCreateKTXTexture(JNIEnv* env, jclass,
|
||||
jlong nativeEngine, jobject javaBuffer, jint remaining, jboolean srgb) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
AutoBuffer buffer(env, javaBuffer, remaining);
|
||||
@@ -73,6 +76,19 @@ static jlong nCreateSkybox(JNIEnv* env, jclass,
|
||||
return (jlong) Skybox::Builder().environment(cubemap).showSun(true).build(*engine);
|
||||
}
|
||||
|
||||
static jboolean nGetSphericalHarmonics(JNIEnv* env, jclass, jobject javaBuffer, jint remaining,
|
||||
jfloatArray outSphericalHarmonics_) {
|
||||
AutoBuffer buffer(env, javaBuffer, remaining);
|
||||
KtxBundle bundle((const uint8_t*) buffer.getData(), buffer.getSize());
|
||||
|
||||
jfloat* outSphericalHarmonics = env->GetFloatArrayElements(outSphericalHarmonics_, nullptr);
|
||||
const auto success = bundle.getSphericalHarmonics(
|
||||
reinterpret_cast<filament::math::float3*>(outSphericalHarmonics)
|
||||
);
|
||||
env->ReleaseFloatArrayElements(outSphericalHarmonics_, outSphericalHarmonics, JNI_ABORT);
|
||||
|
||||
return success ? JNI_TRUE : JNI_FALSE;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) {
|
||||
JNIEnv* env;
|
||||
@@ -80,15 +96,27 @@ JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
jclass c = env->FindClass("com/google/android/filament/utils/KtxLoader");
|
||||
if (c == nullptr) return JNI_ERR;
|
||||
int rc;
|
||||
|
||||
static const JNINativeMethod methods[] = {
|
||||
{"nCreateTexture", "(JLjava/nio/Buffer;IZ)J", reinterpret_cast<void*>(nCreateTexture)},
|
||||
{"nCreateIndirectLight", "(JLjava/nio/Buffer;IZ)J", reinterpret_cast<void*>(nCreateIndirectLight)},
|
||||
{"nCreateSkybox", "(JLjava/nio/Buffer;IZ)J", reinterpret_cast<void*>(nCreateSkybox)},
|
||||
// KTXLoader
|
||||
jclass ktxloaderClass = env->FindClass("com/google/android/filament/utils/KTXLoader");
|
||||
if (ktxloaderClass == nullptr) return JNI_ERR;
|
||||
static const JNINativeMethod ktxMethods[] = {
|
||||
{(char*)"nCreateKTXTexture", (char*)"(JLjava/nio/Buffer;IZ)J", reinterpret_cast<void*>(nCreateKTXTexture)},
|
||||
{(char*)"nCreateIndirectLight", (char*)"(JLjava/nio/Buffer;IZ)J", reinterpret_cast<void*>(nCreateIndirectLight)},
|
||||
{(char*)"nCreateSkybox", (char*)"(JLjava/nio/Buffer;IZ)J", reinterpret_cast<void*>(nCreateSkybox)},
|
||||
{(char*)"nGetSphericalHarmonics", (char*)"(Ljava/nio/Buffer;I[F)Z", reinterpret_cast<void*>(nGetSphericalHarmonics)},
|
||||
};
|
||||
int rc = env->RegisterNatives(c, methods, sizeof(methods) / sizeof(JNINativeMethod));
|
||||
rc = env->RegisterNatives(ktxloaderClass, ktxMethods, sizeof(ktxMethods) / sizeof(JNINativeMethod));
|
||||
if (rc != JNI_OK) return rc;
|
||||
|
||||
// HDRLoader
|
||||
jclass hdrloaderClass = env->FindClass("com/google/android/filament/utils/HDRLoader");
|
||||
if (hdrloaderClass == nullptr) return JNI_ERR;
|
||||
static const JNINativeMethod hdrMethods[] = {
|
||||
{(char*)"nCreateHDRTexture", (char*)"(JLjava/nio/Buffer;II)J", reinterpret_cast<void*>(nCreateHDRTexture)},
|
||||
};
|
||||
rc = env->RegisterNatives(hdrloaderClass, hdrMethods, sizeof(hdrMethods) / sizeof(JNINativeMethod));
|
||||
if (rc != JNI_OK) return rc;
|
||||
|
||||
return JNI_VERSION_1_6;
|
||||
|
||||
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.google.android.filament.utils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.filament.ColorGrading;
|
||||
import com.google.android.filament.Engine;
|
||||
import com.google.android.filament.Entity;
|
||||
import com.google.android.filament.IndirectLight;
|
||||
import com.google.android.filament.LightManager;
|
||||
import com.google.android.filament.Scene;
|
||||
import com.google.android.filament.View;
|
||||
import com.google.android.filament.MaterialInstance;
|
||||
import com.google.android.filament.Renderer;
|
||||
|
||||
/**
|
||||
* The AutomationEngine makes it easy to push a bag of settings values to Filament.
|
||||
* It can also be used to iterate through settings permutations for testing purposes.
|
||||
*
|
||||
* When creating an automation engine for testing purposes, clients give it a JSON string that
|
||||
* tells it how to generate permutations of settings. Automation is always in one of two states:
|
||||
* running or idle. The running state can be entered immediately (startRunning) or by requesting
|
||||
* batch mode (startBatchMode).
|
||||
*
|
||||
* When executing a test, clients should call tick() after each frame is rendered, which provides an
|
||||
* opportunity to push settings to Filament, increment the current test index (if enough time has
|
||||
* elapsed), and request an asychronous screenshot.
|
||||
*
|
||||
* The time to sleep between tests is configurable and can be set to zero. Automation also waits a
|
||||
* specified minimum number of frames between tests.
|
||||
*
|
||||
* Batch mode is meant for non-interactive applications. In batch mode, automation defers applying
|
||||
* the first test case until the client unblocks it via signalBatchMode(). This is useful when
|
||||
* waiting for a large model file to become fully loaded. Batch mode also offers a query
|
||||
* (shouldClose) that is triggered after the last test has been invoked.
|
||||
*/
|
||||
public class AutomationEngine {
|
||||
private long mNativeObject;
|
||||
private ColorGrading mColorGrading;
|
||||
|
||||
/**
|
||||
* Allows users to toggle screenshots, change the sleep duration between tests, etc.
|
||||
*/
|
||||
public static class Options {
|
||||
/**
|
||||
* Minimum time that automation waits between applying a settings object and advancing
|
||||
* to the next test case. Specified in seconds.
|
||||
*/
|
||||
public float sleepDuration = 0.2f;
|
||||
|
||||
/**
|
||||
* Similar to sleepDuration, but expressed as a frame count. Both the minimum sleep time
|
||||
* and the minimum frame count must be elapsed before automation advances to the next test.
|
||||
*/
|
||||
public int minFrameCount = 2;
|
||||
|
||||
/**
|
||||
* If true, test progress is dumped to the utils Log (info priority).
|
||||
*/
|
||||
public boolean verbose = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows remote control for the viewer.
|
||||
*/
|
||||
public static class ViewerOptions {
|
||||
public float cameraAperture = 16.0f;
|
||||
public float cameraSpeed = 125.0f;
|
||||
public float cameraISO = 100.0f;
|
||||
public float groundShadowStrength = 0.75f;
|
||||
public boolean groundPlaneEnabled = false;
|
||||
public boolean skyboxEnabled = true;
|
||||
public float cameraFocalLength = 28.0f;
|
||||
public float cameraFocusDistance = 0.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an automation engine from a JSON specification.
|
||||
*
|
||||
* An example of a JSON spec can be found by searching the repo for DEFAULT_AUTOMATION.
|
||||
* This is documented using a JSON schema (look for viewer/schemas/automation.json).
|
||||
*
|
||||
* @param jsonSpec Valid JSON string that conforms to the automation schema.
|
||||
*/
|
||||
public AutomationEngine(@NonNull String jsonSpec) {
|
||||
mNativeObject = nCreateAutomationEngine(jsonSpec);
|
||||
if (mNativeObject == 0) throw new IllegalStateException("Couldn't create AutomationEngine");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an automation engine for the sole purpose of pushing settings, or for executing
|
||||
* the default test sequence.
|
||||
*
|
||||
* To see how the default test sequence is generated, search for DEFAULT_AUTOMATION.
|
||||
*/
|
||||
public AutomationEngine() {
|
||||
mNativeObject = nCreateDefaultAutomationEngine();
|
||||
if (mNativeObject == 0) throw new IllegalStateException("Couldn't create AutomationEngine");
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the automation engine for users who wish to set up a custom sleep time
|
||||
* between tests, etc.
|
||||
*/
|
||||
public void setOptions(@NonNull Options options) {
|
||||
nSetOptions(mNativeObject, options.sleepDuration, options.minFrameCount, options.verbose);
|
||||
}
|
||||
|
||||
/**
|
||||
* Activates the automation test. During the subsequent call to tick(), the first test is
|
||||
* applied and automation enters the running state.
|
||||
*/
|
||||
public void startRunning() { nStartRunning(mNativeObject); }
|
||||
|
||||
/**
|
||||
* Activates the automation test, but enters a paused state until the user calls
|
||||
* signalBatchMode().
|
||||
*/
|
||||
public void startBatchMode() { nStartBatchMode(mNativeObject); }
|
||||
|
||||
/**
|
||||
* Notifies the automation engine that time has passed and a new frame has been rendered.
|
||||
*
|
||||
* This is when settings get applied, screenshots are (optionally) exported, and the internal
|
||||
* test counter is potentially incremented.
|
||||
*
|
||||
* @param view The Filament View that automation pushes changes to.
|
||||
* @param materials Optional set of of materials that can receive parameter tweaks.
|
||||
* @param renderer The Filament Renderer that can be used to take screenshots.
|
||||
* @param deltaTime The amount of time that has passed since the previous tick in seconds.
|
||||
*/
|
||||
public void tick(@NonNull View view, @Nullable MaterialInstance[] materials,
|
||||
@NonNull Renderer renderer, float deltaTime) {
|
||||
long[] nativeMaterialInstances = null;
|
||||
if (materials != null) {
|
||||
nativeMaterialInstances = new long[materials.length];
|
||||
for (int i = 0; i < nativeMaterialInstances.length; i++) {
|
||||
nativeMaterialInstances[i] = materials[i].getNativeObject();
|
||||
}
|
||||
}
|
||||
long nativeView = view.getNativeObject();
|
||||
long nativeRenderer = renderer.getNativeObject();
|
||||
nTick(mNativeObject, nativeView, nativeMaterialInstances, nativeRenderer, deltaTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mutates a set of client-owned Filament objects according to a JSON string.
|
||||
*
|
||||
* This method is an alternative to tick(). It allows clients to use the automation engine as a
|
||||
* remote control, as opposed to iterating through a predetermined test sequence.
|
||||
*
|
||||
* This updates the stashed Settings object, then pushes those settings to the given
|
||||
* Filament objects. Clients can optionally call getColorGrading() after calling this method.
|
||||
*/
|
||||
public void applySettings(@NonNull String settingsJson, @NonNull View view,
|
||||
@Nullable MaterialInstance[] materials, @Nullable IndirectLight ibl, @Entity int light,
|
||||
@NonNull LightManager lm, @NonNull Scene scene, @NonNull Renderer renderer) {
|
||||
long[] nativeMaterialInstances = null;
|
||||
if (materials != null) {
|
||||
nativeMaterialInstances = new long[materials.length];
|
||||
for (int i = 0; i < nativeMaterialInstances.length; i++) {
|
||||
nativeMaterialInstances[i] = materials[i].getNativeObject();
|
||||
}
|
||||
}
|
||||
long nativeView = view.getNativeObject();
|
||||
long nativeIbl = ibl == null ? 0 : ibl.getNativeObject();
|
||||
long nativeLm = lm.getNativeObject();
|
||||
long nativeScene = scene.getNativeObject();
|
||||
long nativeRenderer = renderer.getNativeObject();
|
||||
nApplySettings(mNativeObject, settingsJson, nativeView, nativeMaterialInstances,
|
||||
nativeIbl, light, nativeLm, nativeScene, nativeRenderer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current viewer options.
|
||||
*
|
||||
* NOTE: Focal length here might be different from the user-specified value, due to DoF options.
|
||||
*/
|
||||
@NonNull
|
||||
public ViewerOptions getViewerOptions() {
|
||||
ViewerOptions result = new ViewerOptions();
|
||||
nGetViewerOptions(mNativeObject, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a color grading object that corresponds to the latest settings.
|
||||
*
|
||||
* This method either returns a cached instance, or it destroys the cached instance and creates
|
||||
* a new one.
|
||||
*/
|
||||
@NonNull
|
||||
public ColorGrading getColorGrading(@NonNull Engine engine) {
|
||||
// The native layer automatically destroys the old color grading instance,
|
||||
// so there is no need to call Engine#destroyColorGrading here.
|
||||
long nativeCg = nGetColorGrading(mNativeObject, engine.getNativeObject());
|
||||
if (mColorGrading == null || mColorGrading.getNativeObject() != nativeCg) {
|
||||
mColorGrading = nativeCg == 0 ? null : new ColorGrading(nativeCg);
|
||||
}
|
||||
return mColorGrading;
|
||||
}
|
||||
|
||||
/**
|
||||
* Signals that batch mode can begin. Call this after all meshes and textures finish loading.
|
||||
*/
|
||||
public void signalBatchMode() { nSignalBatchMode(mNativeObject); }
|
||||
|
||||
/**
|
||||
* Cancels an in-progress automation session.
|
||||
*/
|
||||
public void stopRunning() { nStopRunning(mNativeObject); }
|
||||
|
||||
/**
|
||||
* Returns true if automation is in batch mode and all tests have finished.
|
||||
*/
|
||||
public boolean shouldClose() { return nShouldClose(mNativeObject); }
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
nDestroy(mNativeObject);
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
private static native long nCreateAutomationEngine(String jsonSpec);
|
||||
private static native long nCreateDefaultAutomationEngine();
|
||||
private static native void nSetOptions(long nativeObject, float sleepDuration,
|
||||
int minFrameCount, boolean verbose);
|
||||
private static native void nStartRunning(long nativeObject);
|
||||
private static native void nStartBatchMode(long nativeObject);
|
||||
private static native void nTick(long nativeObject, long view, long[] materials, long renderer,
|
||||
float deltaTime);
|
||||
private static native void nApplySettings(long nativeObject, String jsonSettings, long view,
|
||||
long[] materials, long ibl, int light, long lightManager, long scene, long renderer);
|
||||
private static native void nGetViewerOptions(long nativeObject, Object result);
|
||||
private static native long nGetColorGrading(long nativeObject, long nativeEngine);
|
||||
private static native void nSignalBatchMode(long nativeObject);
|
||||
private static native void nStopRunning(long nativeObject);
|
||||
private static native boolean nShouldClose(long nativeObject);
|
||||
private static native void nDestroy(long nativeObject);
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.google.android.filament.utils
|
||||
|
||||
import com.google.android.filament.Engine
|
||||
import com.google.android.filament.Texture
|
||||
|
||||
import java.nio.Buffer
|
||||
|
||||
/**
|
||||
* Utility for decoding an HDR file and producing a Filament texture.
|
||||
*/
|
||||
object HDRLoader {
|
||||
class Options {
|
||||
var desiredFormat = Texture.InternalFormat.RGB16F
|
||||
}
|
||||
|
||||
/**
|
||||
* Consumes the content of an HDR file and produces a [Texture] object.
|
||||
*
|
||||
* @param engine Gets passed to the builder.
|
||||
* @param buffer The content of the HDR File.
|
||||
* @param options Loader options.
|
||||
* @return The resulting Filament texture, or null on failure.
|
||||
*/
|
||||
fun createTexture(engine: Engine, buffer: Buffer, options: Options = Options()): Texture? {
|
||||
val nativeEngine = engine.nativeObject
|
||||
val nativeTexture = nCreateHDRTexture(nativeEngine, buffer, buffer.remaining(), options.desiredFormat.ordinal)
|
||||
if (nativeTexture == 0L) {
|
||||
return null;
|
||||
}
|
||||
return Texture(nativeTexture)
|
||||
}
|
||||
|
||||
private external fun nCreateHDRTexture(nativeEngine: Long, buffer: Buffer, remaining: Int, format: Int): Long
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.google.android.filament.utils;
|
||||
|
||||
import com.google.android.filament.Engine;
|
||||
import com.google.android.filament.Texture;
|
||||
|
||||
/**
|
||||
* IBLPrefilterContext creates and initializes GPU state common to all environment map filters
|
||||
* supported. Typically, only one instance per filament Engine of this object needs to exist.
|
||||
*
|
||||
* Java usage example:
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* context = new IBLPrefilterContext(engine);
|
||||
* equirectangularToCubemap = new IBLPrefilterContext.EquirectangularToCubemap(context);
|
||||
*
|
||||
* Texture equirect = HDRLoader.createTexture("foo.hdr");
|
||||
* Texture skyboxTexture = equirectangularToCubemap.run(equirect);
|
||||
* engine.destroy(equirect);
|
||||
*
|
||||
* specularFilter = new IBLPrefilterContext.SpecularFilter(context);
|
||||
* Texture reflections = specularFilter.run(skyboxTexture);
|
||||
*
|
||||
* IndirectLight ibl = IndirectLight.Builder()
|
||||
* .reflections(reflections)
|
||||
* .intensity(30000.0f)
|
||||
* .build(engine);
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
public class IBLPrefilterContext {
|
||||
private final long mNativeObject;
|
||||
|
||||
public IBLPrefilterContext(Engine engine) {
|
||||
mNativeObject = nCreate(engine.getNativeObject());
|
||||
if (mNativeObject == 0) throw new IllegalStateException("Couldn't create IBLPrefilterContext");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
nDestroy(mNativeObject);
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
public static class EquirectangularToCubemap {
|
||||
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) // Keep to finalize native resources
|
||||
private final HelperFinalizer mFinalizer;
|
||||
private final long mNativeHelper;
|
||||
|
||||
public EquirectangularToCubemap(IBLPrefilterContext context) {
|
||||
mNativeHelper = nCreateEquirectHelper(context.mNativeObject);
|
||||
mFinalizer = new HelperFinalizer(mNativeHelper);
|
||||
}
|
||||
|
||||
public Texture run(Texture equirect) {
|
||||
long nativeTexture = nEquirectHelperRun(mNativeHelper, equirect.getNativeObject());
|
||||
return new Texture(nativeTexture);
|
||||
}
|
||||
|
||||
private static class HelperFinalizer {
|
||||
private final long mNativeObject;
|
||||
|
||||
HelperFinalizer(long nativeObject) { mNativeObject = nativeObject; }
|
||||
|
||||
@Override
|
||||
public void finalize() {
|
||||
try {
|
||||
super.finalize();
|
||||
} catch (Throwable t) { // Ignore
|
||||
} finally {
|
||||
nDestroyEquirectHelper(mNativeObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class SpecularFilter {
|
||||
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) // Keep to finalize native resources
|
||||
private final HelperFinalizer mFinalizer;
|
||||
private final long mNativeHelper;
|
||||
|
||||
public SpecularFilter(IBLPrefilterContext context) {
|
||||
mNativeHelper = nCreateSpecularFilter(context.mNativeObject);
|
||||
mFinalizer = new HelperFinalizer(mNativeHelper);
|
||||
}
|
||||
|
||||
public Texture run(Texture skybox) {
|
||||
long nativeTexture = nSpecularFilterRun(mNativeHelper, skybox.getNativeObject());
|
||||
return new Texture(nativeTexture);
|
||||
}
|
||||
|
||||
private static class HelperFinalizer {
|
||||
private final long mNativeObject;
|
||||
|
||||
HelperFinalizer(long nativeObject) { mNativeObject = nativeObject; }
|
||||
|
||||
@Override
|
||||
public void finalize() {
|
||||
try {
|
||||
super.finalize();
|
||||
} catch (Throwable t) { // Ignore
|
||||
} finally {
|
||||
nDestroySpecularFilter(mNativeObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static native long nCreate(long nativeEngine);
|
||||
private static native void nDestroy(long nativeObject);
|
||||
|
||||
private static native long nCreateEquirectHelper(long nativeContext);
|
||||
private static native long nEquirectHelperRun(long nativeHelper, long nativeEquirect);
|
||||
private static native void nDestroyEquirectHelper(long nativeObject);
|
||||
|
||||
private static native long nCreateSpecularFilter(long nativeContext);
|
||||
private static native long nSpecularFilterRun(long nativeHelper, long nativeSkybox);
|
||||
private static native void nDestroySpecularFilter(long nativeObject);
|
||||
}
|
||||
@@ -29,7 +29,7 @@ import java.nio.Buffer
|
||||
* KTX is a simple container format that makes it easy to bundle miplevels and cubemap faces
|
||||
* into a single file.
|
||||
*/
|
||||
object KtxLoader {
|
||||
object KTXLoader {
|
||||
class Options {
|
||||
var srgb = false
|
||||
}
|
||||
@@ -44,8 +44,8 @@ object KtxLoader {
|
||||
*/
|
||||
fun createTexture(engine: Engine, buffer: Buffer, options: Options = Options()): Texture {
|
||||
val nativeEngine = engine.nativeObject
|
||||
val nativeTexture = nCreateTexture(nativeEngine, buffer, buffer.remaining(), options.srgb)
|
||||
return Texture(engine, nativeTexture)
|
||||
val nativeTexture = nCreateKTXTexture(nativeEngine, buffer, buffer.remaining(), options.srgb)
|
||||
return Texture(nativeTexture)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,7 +59,7 @@ object KtxLoader {
|
||||
fun createIndirectLight(engine: Engine, buffer: Buffer, options: Options = Options()): IndirectLight {
|
||||
val nativeEngine = engine.nativeObject
|
||||
val nativeIndirectLight = nCreateIndirectLight(nativeEngine, buffer, buffer.remaining(), options.srgb)
|
||||
return IndirectLight(engine, nativeIndirectLight)
|
||||
return IndirectLight(nativeIndirectLight)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,10 +73,23 @@ object KtxLoader {
|
||||
fun createSkybox(engine: Engine, buffer: Buffer, options: Options = Options()): Skybox {
|
||||
val nativeEngine = engine.nativeObject
|
||||
val nativeSkybox = nCreateSkybox(nativeEngine, buffer, buffer.remaining(), options.srgb)
|
||||
return Skybox(engine, nativeSkybox)
|
||||
return Skybox(nativeSkybox)
|
||||
}
|
||||
|
||||
private external fun nCreateTexture(nativeEngine: Long, buffer: Buffer, remaining: Int, srgb: Boolean): Long
|
||||
/**
|
||||
* Retrieves spherical harmonics from the content of a KTX file.
|
||||
*
|
||||
* @param buffer The content of the KTX File.
|
||||
* @return The resulting array of 9 * 3 floats, or null on failure.
|
||||
*/
|
||||
fun getSphericalHarmonics(buffer: Buffer): FloatArray? {
|
||||
val sphericalHarmonics = FloatArray(9 * 3)
|
||||
val success = nGetSphericalHarmonics(buffer, buffer.remaining(), sphericalHarmonics)
|
||||
return if (success) sphericalHarmonics else null
|
||||
}
|
||||
|
||||
private external fun nCreateKTXTexture(nativeEngine: Long, buffer: Buffer, remaining: Int, srgb: Boolean): Long
|
||||
private external fun nCreateIndirectLight(nativeEngine: Long, buffer: Buffer, remaining: Int, srgb: Boolean): Long
|
||||
private external fun nGetSphericalHarmonics(buffer: Buffer, remaining: Int, outSphericalHarmonics: FloatArray): Boolean
|
||||
private external fun nCreateSkybox(nativeEngine: Long, buffer: Buffer, remaining: Int, srgb: Boolean): Long
|
||||
}
|
||||
@@ -199,7 +199,7 @@ public class Manipulator {
|
||||
* @return this <code>Builder</code> object for chaining calls
|
||||
*/
|
||||
public Builder flightStartPosition(float x, float y, float z) {
|
||||
nFlightStartPosition(mNativeBuilder, x, y, z);
|
||||
nBuilderFlightStartPosition(mNativeBuilder, x, y, z);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -209,7 +209,7 @@ public class Manipulator {
|
||||
* @return this <code>Builder</code> object for chaining calls
|
||||
*/
|
||||
public Builder flightStartOrientation(float pitch, float yaw) {
|
||||
nFlightStartOrientation(mNativeBuilder, pitch, yaw);
|
||||
nBuilderFlightStartOrientation(mNativeBuilder, pitch, yaw);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -220,7 +220,7 @@ public class Manipulator {
|
||||
* @return this <code>Builder</code> object for chaining calls
|
||||
*/
|
||||
public Builder flightMaxMoveSpeed(float maxSpeed) {
|
||||
nFlightMaxMoveSpeed(mNativeBuilder, maxSpeed);
|
||||
nBuilderFlightMaxMoveSpeed(mNativeBuilder, maxSpeed);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -231,7 +231,7 @@ public class Manipulator {
|
||||
* @return this <code>Builder</code> object for chaining calls
|
||||
*/
|
||||
public Builder flightSpeedSteps(int steps) {
|
||||
nFlightSpeedSteps(mNativeBuilder, steps);
|
||||
nBuilderFlightSpeedSteps(mNativeBuilder, steps);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -242,7 +242,7 @@ public class Manipulator {
|
||||
* @return this <code>Builder</code> object for chaining calls
|
||||
*/
|
||||
public Builder flightPanSpeed(float x, float y) {
|
||||
nFlightPanSpeed(mNativeBuilder, x, y);
|
||||
nBuilderFlightPanSpeed(mNativeBuilder, x, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -255,7 +255,7 @@ public class Manipulator {
|
||||
* @return this <code>Builder</code> object for chaining calls
|
||||
*/
|
||||
public Builder flightMoveDamping(float damping) {
|
||||
nFlightMoveDamping(mNativeBuilder, damping);
|
||||
nBuilderFlightMoveDamping(mNativeBuilder, damping);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -474,12 +474,12 @@ public class Manipulator {
|
||||
private static native void nBuilderFarPlane(long nativeBuilder, float distance);
|
||||
private static native void nBuilderMapExtent(long nativeBuilder, float width, float height);
|
||||
private static native void nBuilderMapMinDistance(long nativeBuilder, float arg);
|
||||
private static native void nFlightStartPosition(long nativeBuilder, float x, float y, float z);
|
||||
private static native void nFlightStartOrientation(long nativeBuilder, float pitch, float yaw);
|
||||
private static native void nFlightMaxMoveSpeed(long nativeBuilder, float maxSpeed);
|
||||
private static native void nFlightSpeedSteps(long nativeBuilder, int steps);
|
||||
private static native void nFlightPanSpeed(long nativeBuilder, float x, float y);
|
||||
private static native void nFlightMoveDamping(long nativeBuilder, float damping);
|
||||
private static native void nBuilderFlightStartPosition(long nativeBuilder, float x, float y, float z);
|
||||
private static native void nBuilderFlightStartOrientation(long nativeBuilder, float pitch, float yaw);
|
||||
private static native void nBuilderFlightMaxMoveSpeed(long nativeBuilder, float maxSpeed);
|
||||
private static native void nBuilderFlightSpeedSteps(long nativeBuilder, int steps);
|
||||
private static native void nBuilderFlightPanSpeed(long nativeBuilder, float x, float y);
|
||||
private static native void nBuilderFlightMoveDamping(long nativeBuilder, float damping);
|
||||
private static native void nBuilderGroundPlane(long nativeBuilder, float a, float b, float c, float d);
|
||||
private static native long nBuilderBuild(long nativeBuilder, int mode);
|
||||
|
||||
|
||||
@@ -27,9 +27,8 @@ import com.google.android.filament.gltfio.*
|
||||
import kotlinx.coroutines.*
|
||||
import java.nio.Buffer
|
||||
|
||||
private const val kNearPlane = 0.5
|
||||
private const val kFarPlane = 10000.0
|
||||
private const val kFovDegrees = 45.0
|
||||
private const val kNearPlane = 0.05 // 5 cm
|
||||
private const val kFarPlane = 1000.0 // 1 km
|
||||
private const val kAperture = 16f
|
||||
private const val kShutterSpeed = 1f / 125f
|
||||
private const val kSensitivity = 100f
|
||||
@@ -73,9 +72,16 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
|
||||
var normalizeSkinningWeights = true
|
||||
var recomputeBoundingBoxes = false
|
||||
|
||||
var cameraFocalLength = 28f
|
||||
set(value) {
|
||||
field = value
|
||||
updateCameraProjection()
|
||||
}
|
||||
|
||||
val scene: Scene
|
||||
val view: View
|
||||
val camera: Camera
|
||||
val renderer: Renderer
|
||||
@Entity val light: Int
|
||||
|
||||
private val uiHelper: UiHelper = UiHelper(UiHelper.ContextErrorPolicy.DONT_CHECK)
|
||||
@@ -87,7 +93,6 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
|
||||
|
||||
private var fetchResourcesJob: Job? = null
|
||||
|
||||
private val renderer: Renderer
|
||||
private var swapChain: SwapChain? = null
|
||||
private var assetLoader: AssetLoader
|
||||
private var resourceLoader: ResourceLoader
|
||||
@@ -100,7 +105,7 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
|
||||
init {
|
||||
renderer = engine.createRenderer()
|
||||
scene = engine.createScene()
|
||||
camera = engine.createCamera().apply { setExposure(kAperture, kShutterSpeed, kSensitivity) }
|
||||
camera = engine.createCamera(engine.entityManager.create()).apply { setExposure(kAperture, kShutterSpeed, kSensitivity) }
|
||||
view = engine.createView()
|
||||
view.scene = scene
|
||||
view.camera = camera
|
||||
@@ -171,12 +176,17 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
|
||||
*
|
||||
* The given callback is triggered for each requested resource.
|
||||
*/
|
||||
fun loadModelGltf(buffer: Buffer, callback: (String) -> Buffer) {
|
||||
fun loadModelGltf(buffer: Buffer, callback: (String) -> Buffer?) {
|
||||
destroyModel()
|
||||
asset = assetLoader.createAssetFromJson(buffer)
|
||||
asset?.let { asset ->
|
||||
for (uri in asset.resourceUris) {
|
||||
resourceLoader.addResourceData(uri, callback(uri))
|
||||
val resourceBuffer = callback(uri)
|
||||
if (resourceBuffer == null) {
|
||||
this.asset = null
|
||||
return
|
||||
}
|
||||
resourceLoader.addResourceData(uri, resourceBuffer)
|
||||
}
|
||||
resourceLoader.asyncBeginLoad(asset)
|
||||
animator = asset.animator
|
||||
@@ -221,6 +231,7 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
|
||||
fun destroyModel() {
|
||||
fetchResourcesJob?.cancel()
|
||||
resourceLoader.asyncCancelLoad()
|
||||
resourceLoader.evictResourceData()
|
||||
asset?.let { asset ->
|
||||
this.scene.removeEntities(asset.entities)
|
||||
assetLoader.destroyAsset(asset)
|
||||
@@ -261,9 +272,14 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
|
||||
}
|
||||
|
||||
private fun populateScene(asset: FilamentAsset) {
|
||||
val rcm = engine.renderableManager
|
||||
var count = 0
|
||||
val popRenderables = {count = asset.popRenderables(readyRenderables); count != 0}
|
||||
while (popRenderables()) {
|
||||
for (i in 0..count-1) {
|
||||
val ri = rcm.getInstance(readyRenderables[i])
|
||||
rcm.setScreenSpaceContactShadows(ri, true)
|
||||
}
|
||||
scene.addEntities(readyRenderables.take(count).toIntArray())
|
||||
}
|
||||
scene.addEntities(asset.lightEntities)
|
||||
@@ -283,7 +299,8 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
|
||||
engine.destroyRenderer(renderer)
|
||||
engine.destroyView(this@ModelViewer.view)
|
||||
engine.destroyScene(scene)
|
||||
engine.destroyCamera(camera)
|
||||
engine.destroyCameraComponent(camera.entity)
|
||||
EntityManager.get().destroy(camera.entity)
|
||||
|
||||
EntityManager.get().destroy(light)
|
||||
|
||||
@@ -322,6 +339,13 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateCameraProjection() {
|
||||
val width = view.viewport.width
|
||||
val height = view.viewport.height
|
||||
val aspect = width.toDouble() / height.toDouble()
|
||||
camera.setLensProjection(cameraFocalLength.toDouble(), aspect, kNearPlane, kFarPlane)
|
||||
}
|
||||
|
||||
inner class SurfaceCallback : UiHelper.RendererCallback {
|
||||
override fun onNativeWindowChanged(surface: Surface) {
|
||||
swapChain?.let { engine.destroySwapChain(it) }
|
||||
@@ -341,9 +365,8 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
|
||||
|
||||
override fun onResized(width: Int, height: Int) {
|
||||
view.viewport = Viewport(0, 0, width, height)
|
||||
val aspect = width.toDouble() / height.toDouble()
|
||||
camera.setProjection(kFovDegrees, aspect, kNearPlane, kFarPlane, Camera.Fov.VERTICAL)
|
||||
cameraManipulator.setViewport(width, height)
|
||||
updateCameraProjection()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.google.android.filament.utils;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
/**
|
||||
* Manages a tiny WebSocket server that can receive model data and viewer settings.
|
||||
*
|
||||
* Client apps can call acquireReceivedMessage to check for new data and pop it off the small
|
||||
* internal queue.
|
||||
*/
|
||||
public class RemoteServer {
|
||||
private long mNativeObject;
|
||||
|
||||
/**
|
||||
* Encapsulates a message sent from the web client.
|
||||
*/
|
||||
public static class ReceivedMessage {
|
||||
public String label;
|
||||
public ByteBuffer buffer;
|
||||
}
|
||||
|
||||
public RemoteServer(int port) {
|
||||
mNativeObject = nCreate(port);
|
||||
if (mNativeObject == 0) throw new IllegalStateException("Couldn't create RemoteServer");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a download is currently in progress and returns its label.
|
||||
* Returns null if nothing is being downloaded.
|
||||
*/
|
||||
public @Nullable String peekIncomingLabel() {
|
||||
return nPeekIncomingLabel(mNativeObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a peeked message has JSON content.
|
||||
*/
|
||||
public static boolean isJson(@Nullable String label) {
|
||||
return label != null && label.endsWith(".json");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a peeked message has binary content.
|
||||
*/
|
||||
public static boolean isBinary(@Nullable String label) {
|
||||
return label != null && !label.endsWith(".json");
|
||||
}
|
||||
|
||||
/**
|
||||
* Pops a message off the incoming queue or returns null if there are no unread messages.
|
||||
*/
|
||||
public @Nullable ReceivedMessage acquireReceivedMessage() {
|
||||
int length = nPeekReceivedBufferLength(mNativeObject);
|
||||
if (length == 0) {
|
||||
return null;
|
||||
}
|
||||
ReceivedMessage message = new ReceivedMessage();
|
||||
message.label = nPeekReceivedLabel(mNativeObject);
|
||||
message.buffer = ByteBuffer.allocateDirect(length);
|
||||
message.buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
nAcquireReceivedMessage(mNativeObject, message.buffer, length);
|
||||
return message;
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroys the native WebSocket server and frees up the port.
|
||||
*
|
||||
* This might need to be done explicitly (as opposed to waiting for gc) to free up the port.
|
||||
*/
|
||||
public void close() {
|
||||
nDestroy(mNativeObject);
|
||||
mNativeObject = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
nDestroy(mNativeObject);
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
private static native long nCreate(int port);
|
||||
private static native String nPeekIncomingLabel(long nativeObject);
|
||||
private static native String nPeekReceivedLabel(long nativeObject);
|
||||
private static native int nPeekReceivedBufferLength(long nativeObject);
|
||||
private static native void nAcquireReceivedMessage(long nativeObject, ByteBuffer buffer, int length);
|
||||
private static native void nDestroy(long nativeObject);
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.6)
|
||||
cmake_minimum_required(VERSION 3.19)
|
||||
project(gltfio-android)
|
||||
|
||||
set(FILAMENT_DIR ${FILAMENT_DIST_DIR})
|
||||
set(GLTFIO_DIR ../../libs/gltfio)
|
||||
@@ -44,7 +45,11 @@ set(GLTFIO_SRCS
|
||||
${GLTFIO_DIR}/src/FilamentInstance.cpp
|
||||
${GLTFIO_DIR}/src/GltfEnums.h
|
||||
${GLTFIO_DIR}/src/MaterialProvider.cpp
|
||||
${GLTFIO_DIR}/src/MorphHelper.h
|
||||
${GLTFIO_DIR}/src/MorphHelper.cpp
|
||||
${GLTFIO_DIR}/src/ResourceLoader.cpp
|
||||
${GLTFIO_DIR}/src/TangentsJob.h
|
||||
${GLTFIO_DIR}/src/TangentsJob.cpp
|
||||
${GLTFIO_DIR}/src/UbershaderLoader.cpp
|
||||
${GLTFIO_DIR}/src/Wireframe.cpp
|
||||
${GLTFIO_DIR}/src/Wireframe.h
|
||||
|
||||
@@ -70,6 +70,13 @@ Java_com_google_android_filament_gltfio_ResourceLoader_nHasResourceData(JNIEnv*
|
||||
return status;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_ResourceLoader_nEvictResourceData(JNIEnv*, jclass,
|
||||
jlong nativeLoader) {
|
||||
ResourceLoader* loader = (ResourceLoader*) nativeLoader;
|
||||
loader->evictResourceData();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_ResourceLoader_nLoadResources(JNIEnv*, jclass,
|
||||
jlong nativeLoader, jlong nativeAsset) {
|
||||
|
||||
@@ -101,6 +101,15 @@ public class ResourceLoader {
|
||||
return nHasResourceData(mNativeObject, uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees memory by evicting the URI cache that was populated via addResourceData.
|
||||
*
|
||||
* This can be called only after a model is fully loaded or after loading has been cancelled.
|
||||
*/
|
||||
public void evictResourceData() {
|
||||
nEvictResourceData(mNativeObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates through all external buffers and images and creates corresponding Filament objects
|
||||
* (vertex buffers, textures, etc), which become owned by the asset.
|
||||
@@ -161,6 +170,7 @@ public class ResourceLoader {
|
||||
private static native void nDestroyResourceLoader(long nativeLoader);
|
||||
private static native void nAddResourceData(long nativeLoader, String url, Buffer buffer,
|
||||
int remaining);
|
||||
private static native void nEvictResourceData(long nativeLoader);
|
||||
private static native boolean nHasResourceData(long nativeLoader, String url);
|
||||
private static native void nLoadResources(long nativeLoader, long nativeAsset);
|
||||
private static native boolean nAsyncBeginLoad(long nativeLoader, long nativeAsset);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
GROUP=com.google.android.filament
|
||||
VERSION_NAME=1.9.12
|
||||
VERSION_NAME=1.10.5
|
||||
|
||||
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
|
||||
|
||||
|
||||
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
@@ -1,6 +1,5 @@
|
||||
#Thu Nov 05 09:33:02 PST 2020
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
|
||||
|
||||
53
android/gradlew
vendored
53
android/gradlew
vendored
@@ -1,5 +1,21 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# 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
|
||||
#
|
||||
# https://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.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
@@ -28,7 +44,7 @@ APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m"'
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
@@ -66,6 +82,7 @@ esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
@@ -109,10 +126,11 @@ if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
@@ -138,19 +156,19 @@ if $cygwin ; then
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
@@ -159,14 +177,9 @@ save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
||||
43
android/gradlew.bat
vendored
43
android/gradlew.bat
vendored
@@ -1,3 +1,19 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@@ -13,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m"
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
@@ -35,7 +54,7 @@ goto fail
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
@@ -45,28 +64,14 @@ echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
|
||||
@@ -36,4 +36,5 @@ dependencies {
|
||||
implementation project(':filament-android')
|
||||
implementation project(':gltfio-android')
|
||||
implementation project(':filament-utils-android')
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.8'
|
||||
}
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
android:largeHeap="true"
|
||||
android:theme="@android:style/Theme.NoTitleBar">
|
||||
<activity android:name="com.google.android.filament.gltf.MainActivity"
|
||||
android:screenOrientation="fullSensor"
|
||||
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden">
|
||||
|
||||
@@ -19,33 +19,58 @@ package com.google.android.filament.gltf
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.os.Bundle
|
||||
import android.view.Choreographer
|
||||
import android.util.Log
|
||||
import android.view.*
|
||||
import android.view.GestureDetector
|
||||
import android.view.MotionEvent
|
||||
import android.view.SurfaceView
|
||||
import com.google.android.filament.utils.KtxLoader
|
||||
import com.google.android.filament.utils.ModelViewer
|
||||
import com.google.android.filament.utils.Utils
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import com.google.android.filament.Fence
|
||||
import com.google.android.filament.IndirectLight
|
||||
import com.google.android.filament.Skybox
|
||||
import com.google.android.filament.utils.*
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.RandomAccessFile
|
||||
import java.nio.Buffer
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.util.zip.ZipInputStream
|
||||
|
||||
class MainActivity : Activity() {
|
||||
|
||||
companion object {
|
||||
// Load the library for the utility layer, which in turn loads gltfio and the Filament core.
|
||||
init { Utils.init() }
|
||||
private const val TAG = "gltf-viewer"
|
||||
}
|
||||
|
||||
private lateinit var surfaceView: SurfaceView
|
||||
private lateinit var choreographer: Choreographer
|
||||
private val frameScheduler = FrameCallback()
|
||||
private lateinit var modelViewer: ModelViewer
|
||||
private lateinit var titlebarHint: TextView
|
||||
private val doubleTapListener = DoubleTapListener()
|
||||
private lateinit var doubleTapDetector: GestureDetector
|
||||
private var remoteServer: RemoteServer? = null
|
||||
private var statusToast: Toast? = null
|
||||
private var statusText: String? = null
|
||||
private var latestDownload: String? = null
|
||||
private val automation = AutomationEngine()
|
||||
private var loadStartTime = 0L
|
||||
private var loadStartFence: Fence? = null
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
surfaceView = SurfaceView(this).apply { setContentView(this) }
|
||||
setContentView(R.layout.simple_layout)
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||
|
||||
titlebarHint = findViewById(R.id.user_hint)
|
||||
surfaceView = findViewById(R.id.main_sv)
|
||||
choreographer = Choreographer.getInstance()
|
||||
|
||||
doubleTapDetector = GestureDetector(applicationContext, doubleTapListener)
|
||||
@@ -58,23 +83,28 @@ class MainActivity : Activity() {
|
||||
true
|
||||
}
|
||||
|
||||
createRenderables()
|
||||
createDefaultRenderables()
|
||||
createIndirectLight()
|
||||
|
||||
val dynamicResolutionOptions = modelViewer.view.dynamicResolutionOptions
|
||||
dynamicResolutionOptions.enabled = true
|
||||
modelViewer.view.dynamicResolutionOptions = dynamicResolutionOptions
|
||||
setStatusText("To load a new model, go to the above URL on your host machine.")
|
||||
|
||||
val ssaoOptions = modelViewer.view.ambientOcclusionOptions
|
||||
ssaoOptions.enabled = true
|
||||
modelViewer.view.ambientOcclusionOptions = ssaoOptions
|
||||
val view = modelViewer.view
|
||||
view.dynamicResolutionOptions = view.dynamicResolutionOptions.apply {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
val bloomOptions = modelViewer.view.bloomOptions
|
||||
bloomOptions.enabled = true
|
||||
modelViewer.view.bloomOptions = bloomOptions
|
||||
view.ambientOcclusionOptions = view.ambientOcclusionOptions.apply {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
view.bloomOptions = view.bloomOptions.apply {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
remoteServer = RemoteServer(8082)
|
||||
}
|
||||
|
||||
private fun createRenderables() {
|
||||
private fun createDefaultRenderables() {
|
||||
val buffer = assets.open("models/scene.gltf").use { input ->
|
||||
val bytes = ByteArray(input.available())
|
||||
input.read(bytes)
|
||||
@@ -90,11 +120,11 @@ class MainActivity : Activity() {
|
||||
val scene = modelViewer.scene
|
||||
val ibl = "default_env"
|
||||
readCompressedAsset("envs/$ibl/${ibl}_ibl.ktx").let {
|
||||
scene.indirectLight = KtxLoader.createIndirectLight(engine, it)
|
||||
scene.indirectLight = KTXLoader.createIndirectLight(engine, it)
|
||||
scene.indirectLight!!.intensity = 30_000.0f
|
||||
}
|
||||
readCompressedAsset("envs/$ibl/${ibl}_skybox.ktx").let {
|
||||
scene.skybox = KtxLoader.createSkybox(engine, it)
|
||||
scene.skybox = KTXLoader.createSkybox(engine, it)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,6 +135,154 @@ class MainActivity : Activity() {
|
||||
return ByteBuffer.wrap(bytes)
|
||||
}
|
||||
|
||||
private fun clearStatusText() {
|
||||
statusToast?.let {
|
||||
it.cancel()
|
||||
statusText = null
|
||||
}
|
||||
}
|
||||
|
||||
private fun setStatusText(text: String) {
|
||||
runOnUiThread {
|
||||
if (statusToast == null || statusText != text) {
|
||||
statusText = text
|
||||
statusToast = Toast.makeText(applicationContext, text, Toast.LENGTH_SHORT)
|
||||
statusToast!!.show()
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun loadGlb(message: RemoteServer.ReceivedMessage) {
|
||||
withContext(Dispatchers.Main) {
|
||||
modelViewer.destroyModel()
|
||||
modelViewer.loadModelGlb(message.buffer)
|
||||
modelViewer.transformToUnitCube()
|
||||
loadStartTime = System.nanoTime()
|
||||
loadStartFence = modelViewer.engine.createFence()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun loadHdr(message: RemoteServer.ReceivedMessage) {
|
||||
withContext(Dispatchers.Main) {
|
||||
val engine = modelViewer.engine
|
||||
val equirect = HDRLoader.createTexture(engine, message.buffer)
|
||||
if (equirect == null) {
|
||||
setStatusText("Could not decode HDR file.")
|
||||
} else {
|
||||
setStatusText("Successfully decoded HDR file.")
|
||||
|
||||
val context = IBLPrefilterContext(engine)
|
||||
val equirectToCubemap = IBLPrefilterContext.EquirectangularToCubemap(context)
|
||||
val skyboxTexture = equirectToCubemap.run(equirect)!!
|
||||
engine.destroyTexture(equirect)
|
||||
|
||||
val specularFilter = IBLPrefilterContext.SpecularFilter(context)
|
||||
val reflections = specularFilter.run(skyboxTexture)
|
||||
|
||||
val ibl = IndirectLight.Builder()
|
||||
.reflections(reflections)
|
||||
.intensity(30000.0f)
|
||||
.build(engine)
|
||||
|
||||
val sky = Skybox.Builder().environment(skyboxTexture).build(engine)
|
||||
|
||||
modelViewer.scene.skybox = sky
|
||||
modelViewer.scene.indirectLight = ibl
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun loadZip(message: RemoteServer.ReceivedMessage) {
|
||||
// To alleviate memory pressure, remove the old model before deflating the zip.
|
||||
withContext(Dispatchers.Main) {
|
||||
modelViewer.destroyModel()
|
||||
}
|
||||
|
||||
// Large zip files should first be written to a file to prevent OOM.
|
||||
// It is also crucial that we null out the message "buffer" field.
|
||||
val (zipStream, zipFile) = withContext(Dispatchers.IO) {
|
||||
val file = File.createTempFile("incoming", "zip", cacheDir)
|
||||
val raf = RandomAccessFile(file, "rw")
|
||||
raf.getChannel().write(message.buffer);
|
||||
message.buffer = null
|
||||
raf.seek(0)
|
||||
Pair(FileInputStream(file), file)
|
||||
}
|
||||
|
||||
// Deflate each resource using the IO dispatcher, one by one.
|
||||
var gltfPath: String? = null
|
||||
var outOfMemory: String? = null
|
||||
val pathToBufferMapping = withContext(Dispatchers.IO) {
|
||||
val deflater = ZipInputStream(zipStream)
|
||||
val mapping = HashMap<String, Buffer>()
|
||||
while (true) {
|
||||
val entry = deflater.nextEntry ?: break
|
||||
if (entry.isDirectory) continue
|
||||
|
||||
// This isn't strictly required, but as an optimization
|
||||
// we ignore common junk that often pollutes ZIP files.
|
||||
if (entry.name.startsWith("__MACOSX")) continue
|
||||
if (entry.name.startsWith(".DS_Store")) continue
|
||||
|
||||
val uri = entry.name
|
||||
val byteArray: ByteArray? = try {
|
||||
deflater.readBytes()
|
||||
}
|
||||
catch (e: OutOfMemoryError) {
|
||||
outOfMemory = uri
|
||||
break
|
||||
}
|
||||
Log.i(TAG, "Deflated ${byteArray!!.size} bytes from $uri")
|
||||
val buffer = ByteBuffer.wrap(byteArray)
|
||||
mapping[uri] = buffer
|
||||
if (uri.endsWith(".gltf") || uri.endsWith(".glb")) {
|
||||
gltfPath = uri
|
||||
}
|
||||
}
|
||||
mapping
|
||||
}
|
||||
|
||||
zipFile.delete()
|
||||
|
||||
if (gltfPath == null) {
|
||||
setStatusText("Could not find .gltf or .glb in the zip.")
|
||||
return
|
||||
}
|
||||
|
||||
if (outOfMemory != null) {
|
||||
setStatusText("Out of memory while deflating $outOfMemory")
|
||||
return
|
||||
}
|
||||
|
||||
val gltfBuffer = pathToBufferMapping[gltfPath]!!
|
||||
|
||||
// The gltf is often not at the root level (e.g. if a folder is zipped) so
|
||||
// we need to extract its path in order to resolve the embedded uri strings.
|
||||
var gltfPrefix = gltfPath!!.substringBeforeLast('/', "")
|
||||
if (gltfPrefix.isNotEmpty()) {
|
||||
gltfPrefix += "/"
|
||||
}
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
if (gltfPath!!.endsWith(".glb")) {
|
||||
modelViewer.loadModelGlb(gltfBuffer)
|
||||
} else {
|
||||
modelViewer.loadModelGltf(gltfBuffer) { uri ->
|
||||
val path = gltfPrefix + uri
|
||||
if (!pathToBufferMapping.contains(path)) {
|
||||
Log.e(TAG, "Could not find $path in the zip.")
|
||||
setStatusText("Zip is missing $path")
|
||||
}
|
||||
pathToBufferMapping[path]
|
||||
}
|
||||
}
|
||||
modelViewer.transformToUnitCube()
|
||||
loadStartTime = System.nanoTime()
|
||||
loadStartFence = modelViewer.engine.createFence()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
choreographer.postFrameCallback(frameScheduler)
|
||||
@@ -118,6 +296,31 @@ class MainActivity : Activity() {
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
choreographer.removeFrameCallback(frameScheduler)
|
||||
remoteServer?.close()
|
||||
}
|
||||
|
||||
fun loadModelData(message: RemoteServer.ReceivedMessage) {
|
||||
Log.i(TAG, "Downloaded model ${message.label} (${message.buffer.capacity()} bytes)")
|
||||
clearStatusText()
|
||||
titlebarHint.text = message.label
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
if (message.label.endsWith(".zip")) {
|
||||
loadZip(message)
|
||||
} else if (message.label.endsWith(".hdr")) {
|
||||
loadHdr(message)
|
||||
} else {
|
||||
loadGlb(message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun loadSettings(message: RemoteServer.ReceivedMessage) {
|
||||
val json = StandardCharsets.UTF_8.decode(message.buffer).toString()
|
||||
automation.applySettings(json, modelViewer.view, null,
|
||||
modelViewer.scene.indirectLight, modelViewer.light, modelViewer.engine.lightManager,
|
||||
modelViewer.scene, modelViewer.renderer)
|
||||
modelViewer.view.colorGrading = automation.getColorGrading((modelViewer.engine))
|
||||
modelViewer.cameraFocalLength = automation.viewerOptions.cameraFocalLength
|
||||
}
|
||||
|
||||
inner class FrameCallback : Choreographer.FrameCallback {
|
||||
@@ -125,6 +328,16 @@ class MainActivity : Activity() {
|
||||
override fun doFrame(frameTimeNanos: Long) {
|
||||
choreographer.postFrameCallback(this)
|
||||
|
||||
loadStartFence?.let {
|
||||
if (it.wait(Fence.Mode.FLUSH, 0) == Fence.FenceStatus.CONDITION_SATISFIED) {
|
||||
val end = System.nanoTime()
|
||||
val total = (end - loadStartTime) / 1_000_000
|
||||
Log.i(TAG, "The Filament backend took ${total} ms to load the model geometry.")
|
||||
modelViewer.engine.destroyFence(it)
|
||||
loadStartFence = null
|
||||
}
|
||||
}
|
||||
|
||||
modelViewer.animator?.apply {
|
||||
if (animationCount > 0) {
|
||||
val elapsedTimeSeconds = (frameTimeNanos - startTime).toDouble() / 1_000_000_000
|
||||
@@ -134,14 +347,35 @@ class MainActivity : Activity() {
|
||||
}
|
||||
|
||||
modelViewer.render(frameTimeNanos)
|
||||
|
||||
// Check if a new download is in progress. If so, let the user know with toast.
|
||||
val currentDownload = remoteServer?.peekIncomingLabel()
|
||||
if (RemoteServer.isBinary(currentDownload) && currentDownload != latestDownload) {
|
||||
latestDownload = currentDownload
|
||||
Log.i(TAG, "Downloading $currentDownload")
|
||||
setStatusText("Downloading $currentDownload")
|
||||
}
|
||||
|
||||
// Check if a new message has been fully received from the client.
|
||||
val message = remoteServer?.acquireReceivedMessage()
|
||||
if (message != null) {
|
||||
if (message.label == latestDownload) {
|
||||
latestDownload = null
|
||||
}
|
||||
if (RemoteServer.isJson(message.label)) {
|
||||
loadSettings(message)
|
||||
} else {
|
||||
loadModelData(message)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Just for testing purposes, this releases the model and reloads it.
|
||||
// Just for testing purposes, this releases the current model and reloads the default model.
|
||||
inner class DoubleTapListener : GestureDetector.SimpleOnGestureListener() {
|
||||
override fun onDoubleTap(e: MotionEvent?): Boolean {
|
||||
modelViewer.destroyModel()
|
||||
createRenderables()
|
||||
createDefaultRenderables()
|
||||
return super.onDoubleTap(e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/simple_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/user_hint"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:gravity="center|center_horizontal|center_vertical"
|
||||
android:text="https://google.github.io/filament/remote"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<SurfaceView
|
||||
android:id="@+id/main_sv"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
</LinearLayout>
|
||||
@@ -109,7 +109,8 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
|
||||
renderer = engine.createRenderer()
|
||||
scene = engine.createScene()
|
||||
view = engine.createView()
|
||||
camera = engine.createCamera()
|
||||
camera = engine.createCamera(engine.entityManager.create())
|
||||
|
||||
}
|
||||
|
||||
private fun setupView() {
|
||||
@@ -342,13 +343,14 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
|
||||
engine.destroyMaterial(material)
|
||||
engine.destroyView(view)
|
||||
engine.destroyScene(scene)
|
||||
engine.destroyCamera(camera)
|
||||
engine.destroyCameraComponent(camera.entity)
|
||||
|
||||
// Engine.destroyEntity() destroys Filament related resources only
|
||||
// (components), not the entity itself
|
||||
val entityManager = EntityManager.get()
|
||||
entityManager.destroy(light)
|
||||
entityManager.destroy(renderable)
|
||||
entityManager.destroy(camera.entity)
|
||||
|
||||
// Destroying the engine will free up any resource you may have forgotten
|
||||
// to destroy, but it's recommended to do the cleanup properly
|
||||
|
||||
@@ -113,7 +113,7 @@ class MainActivity : Activity() {
|
||||
renderer = engine.createRenderer()
|
||||
scene = engine.createScene()
|
||||
view = engine.createView()
|
||||
camera = engine.createCamera()
|
||||
camera = engine.createCamera(engine.entityManager.create())
|
||||
}
|
||||
|
||||
private fun setupView() {
|
||||
@@ -271,12 +271,13 @@ class MainActivity : Activity() {
|
||||
engine.destroyMaterial(material)
|
||||
engine.destroyView(view)
|
||||
engine.destroyScene(scene)
|
||||
engine.destroyCamera(camera)
|
||||
engine.destroyCameraComponent(camera.entity)
|
||||
|
||||
// Engine.destroyEntity() destroys Filament related resources only
|
||||
// (components), not the entity itself
|
||||
val entityManager = EntityManager.get()
|
||||
entityManager.destroy(renderable)
|
||||
entityManager.destroy(camera.entity)
|
||||
|
||||
// Destroying the engine will free up any resource you may have forgotten
|
||||
// to destroy, but it's recommended to do the cleanup properly
|
||||
|
||||
@@ -113,7 +113,7 @@ class MainActivity : Activity() {
|
||||
renderer = engine.createRenderer()
|
||||
scene = engine.createScene()
|
||||
view = engine.createView()
|
||||
camera = engine.createCamera()
|
||||
camera = engine.createCamera(engine.entityManager.create())
|
||||
}
|
||||
|
||||
private fun setupView() {
|
||||
@@ -249,12 +249,13 @@ class MainActivity : Activity() {
|
||||
engine.destroyMaterial(material)
|
||||
engine.destroyView(view)
|
||||
engine.destroyScene(scene)
|
||||
engine.destroyCamera(camera)
|
||||
engine.destroyCameraComponent(camera.entity)
|
||||
|
||||
// Engine.destroyEntity() destroys Filament related resources only
|
||||
// (components), not the entity itself
|
||||
val entityManager = EntityManager.get()
|
||||
entityManager.destroy(light)
|
||||
entityManager.destroy(camera.entity)
|
||||
|
||||
// Destroying the engine will free up any resource you may have forgotten
|
||||
// to destroy, but it's recommended to do the cleanup properly
|
||||
|
||||
@@ -114,7 +114,7 @@ class MainActivity : Activity() {
|
||||
renderer = engine.createRenderer()
|
||||
scene = engine.createScene()
|
||||
view = engine.createView()
|
||||
camera = engine.createCamera()
|
||||
camera = engine.createCamera(engine.entityManager.create())
|
||||
}
|
||||
|
||||
private fun setupView() {
|
||||
@@ -358,13 +358,14 @@ class MainActivity : Activity() {
|
||||
engine.destroyMaterial(material)
|
||||
engine.destroyView(view)
|
||||
engine.destroyScene(scene)
|
||||
engine.destroyCamera(camera)
|
||||
engine.destroyCameraComponent(camera.entity)
|
||||
|
||||
// Engine.destroyEntity() destroys Filament related resources only
|
||||
// (components), not the entity itself
|
||||
val entityManager = EntityManager.get()
|
||||
entityManager.destroy(light)
|
||||
entityManager.destroy(renderable)
|
||||
entityManager.destroy(camera.entity)
|
||||
|
||||
// Destroying the engine will free up any resource you may have forgotten
|
||||
// to destroy, but it's recommended to do the cleanup properly
|
||||
|
||||
@@ -101,7 +101,7 @@ class FilamentLiveWallpaper : WallpaperService() {
|
||||
renderer = engine.createRenderer()
|
||||
scene = engine.createScene()
|
||||
view = engine.createView()
|
||||
camera = engine.createCamera()
|
||||
camera = engine.createCamera(engine.entityManager.create())
|
||||
}
|
||||
|
||||
private fun setupView() {
|
||||
@@ -167,7 +167,8 @@ class FilamentLiveWallpaper : WallpaperService() {
|
||||
engine.destroyRenderer(renderer)
|
||||
engine.destroyView(view)
|
||||
engine.destroyScene(scene)
|
||||
engine.destroyCamera(camera)
|
||||
engine.destroyCameraComponent(camera.entity)
|
||||
EntityManager.get().destroy(camera.entity)
|
||||
|
||||
// Destroying the engine will free up any resource you may have forgotten
|
||||
// to destroy, but it's recommended to do the cleanup properly
|
||||
@@ -221,4 +222,4 @@ class FilamentLiveWallpaper : WallpaperService() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ class MainActivity : Activity() {
|
||||
renderer = engine.createRenderer()
|
||||
scene = engine.createScene()
|
||||
view = engine.createView()
|
||||
camera = engine.createCamera()
|
||||
camera = engine.createCamera(engine.entityManager.create())
|
||||
}
|
||||
|
||||
private fun setupView() {
|
||||
@@ -289,12 +289,13 @@ class MainActivity : Activity() {
|
||||
engine.destroyMaterial(material)
|
||||
engine.destroyView(view)
|
||||
engine.destroyScene(scene)
|
||||
engine.destroyCamera(camera)
|
||||
engine.destroyCameraComponent(camera.entity)
|
||||
|
||||
// Engine.destroyEntity() destroys Filament related resources only
|
||||
// (components), not the entity itself
|
||||
val entityManager = EntityManager.get()
|
||||
entityManager.destroy(light)
|
||||
entityManager.destroy(camera.entity)
|
||||
|
||||
// Destroying the engine will free up any resource you may have forgotten
|
||||
// to destroy, but it's recommended to do the cleanup properly
|
||||
|
||||
@@ -65,6 +65,7 @@ class MainActivity : Activity() {
|
||||
private lateinit var view1: View
|
||||
private lateinit var view2: View
|
||||
private lateinit var view3: View
|
||||
private lateinit var view4: View
|
||||
// We need skybox to set the background color
|
||||
private lateinit var skybox: Skybox
|
||||
// Should be pretty obvious :)
|
||||
@@ -119,16 +120,20 @@ class MainActivity : Activity() {
|
||||
view1 = engine.createView()
|
||||
view2 = engine.createView()
|
||||
view3 = engine.createView()
|
||||
view4 = engine.createView()
|
||||
|
||||
view0.setName("view0");
|
||||
view1.setName("view1");
|
||||
view2.setName("view2");
|
||||
view3.setName("view3");
|
||||
view4.setName("view4");
|
||||
|
||||
view4.blendMode = View.BlendMode.TRANSLUCENT;
|
||||
|
||||
skybox = Skybox.Builder().build(engine);
|
||||
scene.skybox = skybox
|
||||
|
||||
camera = engine.createCamera()
|
||||
camera = engine.createCamera(engine.entityManager.create())
|
||||
}
|
||||
|
||||
private fun setupViews() {
|
||||
@@ -136,11 +141,13 @@ class MainActivity : Activity() {
|
||||
view1.camera = camera
|
||||
view2.camera = camera
|
||||
view3.camera = camera
|
||||
view4.camera = camera
|
||||
|
||||
view0.scene = scene
|
||||
view1.scene = scene
|
||||
view2.scene = scene
|
||||
view3.scene = scene
|
||||
view4.scene = scene
|
||||
}
|
||||
|
||||
private fun setupScene() {
|
||||
@@ -373,15 +380,17 @@ class MainActivity : Activity() {
|
||||
engine.destroyView(view1)
|
||||
engine.destroyView(view2)
|
||||
engine.destroyView(view3)
|
||||
engine.destroyView(view4)
|
||||
engine.destroySkybox(skybox)
|
||||
engine.destroyScene(scene)
|
||||
engine.destroyCamera(camera)
|
||||
engine.destroyCameraComponent(camera.entity)
|
||||
|
||||
// Engine.destroyEntity() destroys Filament related resources only
|
||||
// (components), not the entity itself
|
||||
val entityManager = EntityManager.get()
|
||||
entityManager.destroy(light)
|
||||
entityManager.destroy(renderable)
|
||||
entityManager.destroy(camera.entity)
|
||||
|
||||
// Destroying the engine will free up any resource you may have forgotten
|
||||
// to destroy, but it's recommended to do the cleanup properly
|
||||
@@ -410,6 +419,9 @@ class MainActivity : Activity() {
|
||||
skybox.setColor(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
renderer.render(view3)
|
||||
|
||||
skybox.setColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
renderer.render(view4)
|
||||
|
||||
renderer.endFrame()
|
||||
}
|
||||
}
|
||||
@@ -442,6 +454,7 @@ class MainActivity : Activity() {
|
||||
view1.viewport = Viewport(width / 2, 0, width / 2, height / 2)
|
||||
view2.viewport = Viewport(0, height / 2, width / 2, height / 2)
|
||||
view3.viewport = Viewport(width / 2, height / 2, width / 2, height / 2)
|
||||
view4.viewport = Viewport(width / 4, height / 4, width / 2, height / 2)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ public class MainActivity extends Activity
|
||||
mRenderer = mEngine.createRenderer();
|
||||
mScene = mEngine.createScene();
|
||||
mView = mEngine.createView();
|
||||
mCamera = mEngine.createCamera();
|
||||
mCamera = mEngine.createCamera(mEngine.getEntityManager().create());
|
||||
|
||||
mCamera.lookAt(0, 0, 3, 0, 0, 0, 0, 1, 0);
|
||||
|
||||
@@ -223,9 +223,10 @@ public class MainActivity extends Activity
|
||||
|
||||
mEngine.destroyView(mView);
|
||||
mEngine.destroyScene(mScene);
|
||||
mEngine.destroyCamera(mCamera);
|
||||
mEngine.destroyCameraComponent(mCamera.getEntity());
|
||||
|
||||
EntityManager.get().destroy(mPage.renderable);
|
||||
EntityManager.get().destroy(mCamera.getEntity());
|
||||
|
||||
mEngine.destroy();
|
||||
}
|
||||
@@ -298,4 +299,4 @@ public class MainActivity extends Activity
|
||||
canvas.drawBitmap(bmp, borderSize, borderSize, null);
|
||||
return modified;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
|
||||
renderer = engine.createRenderer()
|
||||
scene = engine.createScene()
|
||||
view = engine.createView()
|
||||
camera = engine.createCamera()
|
||||
camera = engine.createCamera(engine.entityManager.create())
|
||||
}
|
||||
|
||||
private fun setupView() {
|
||||
@@ -328,13 +328,14 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
|
||||
engine.destroyMaterial(material)
|
||||
engine.destroyView(view)
|
||||
engine.destroyScene(scene)
|
||||
engine.destroyCamera(camera)
|
||||
engine.destroyCameraComponent(camera.entity)
|
||||
|
||||
// Engine.destroyEntity() destroys Filament related resources only
|
||||
// (components), not the entity itself
|
||||
val entityManager = EntityManager.get()
|
||||
entityManager.destroy(light)
|
||||
entityManager.destroy(renderable)
|
||||
entityManager.destroy(camera.entity)
|
||||
|
||||
// Destroying the engine will free up any resource you may have forgotten
|
||||
// to destroy, but it's recommended to do the cleanup properly
|
||||
|
||||
@@ -113,7 +113,7 @@ class MainActivity : Activity() {
|
||||
renderer = engine.createRenderer()
|
||||
scene = engine.createScene()
|
||||
view = engine.createView()
|
||||
camera = engine.createCamera()
|
||||
camera = engine.createCamera(engine.entityManager.create())
|
||||
}
|
||||
|
||||
private fun setupView() {
|
||||
@@ -271,12 +271,13 @@ class MainActivity : Activity() {
|
||||
engine.destroyMaterial(material)
|
||||
engine.destroyView(view)
|
||||
engine.destroyScene(scene)
|
||||
engine.destroyCamera(camera)
|
||||
engine.destroyCameraComponent(camera.entity)
|
||||
|
||||
// Engine.destroyEntity() destroys Filament related resources only
|
||||
// (components), not the entity itself
|
||||
val entityManager = EntityManager.get()
|
||||
entityManager.destroy(renderable)
|
||||
entityManager.destroy(camera.entity)
|
||||
|
||||
// Destroying the engine will free up any resource you may have forgotten
|
||||
// to destroy, but it's recommended to do the cleanup properly
|
||||
|
||||
@@ -39,5 +39,5 @@ dependencies {
|
||||
implementation deps.kotlin
|
||||
implementation project(':filament-android')
|
||||
implementation project(':gltfio-android')
|
||||
implementation project(':filament-utils-android') // required for KtxLoader
|
||||
implementation project(':filament-utils-android') // required for KTXLoader
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ class MainActivity : Activity() {
|
||||
renderer = engine.createRenderer()
|
||||
scene = engine.createScene()
|
||||
view = engine.createView()
|
||||
camera = engine.createCamera()
|
||||
camera = engine.createCamera(engine.entityManager.create())
|
||||
}
|
||||
|
||||
private fun setupView() {
|
||||
@@ -269,12 +269,13 @@ class MainActivity : Activity() {
|
||||
engine.destroyMaterial(material)
|
||||
engine.destroyView(view)
|
||||
engine.destroyScene(scene)
|
||||
engine.destroyCamera(camera)
|
||||
engine.destroyCameraComponent(camera.entity)
|
||||
|
||||
// Engine.destroyEntity() destroys Filament related resources only
|
||||
// (components), not the entity itself
|
||||
val entityManager = EntityManager.get()
|
||||
entityManager.destroy(light)
|
||||
entityManager.destroy(camera.entity)
|
||||
|
||||
// Destroying the engine will free up any resource you may have forgotten
|
||||
// to destroy, but it's recommended to do the cleanup properly
|
||||
|
||||
@@ -136,7 +136,7 @@ class MainActivity : Activity() {
|
||||
renderer = engine.createRenderer()
|
||||
scene = engine.createScene()
|
||||
view = engine.createView()
|
||||
camera = engine.createCamera()
|
||||
camera = engine.createCamera(engine.entityManager.create())
|
||||
|
||||
// clear the swapchain with transparent pixels
|
||||
val options = renderer.clearOptions
|
||||
@@ -294,12 +294,13 @@ class MainActivity : Activity() {
|
||||
engine.destroyMaterial(material)
|
||||
engine.destroyView(view)
|
||||
engine.destroyScene(scene)
|
||||
engine.destroyCamera(camera)
|
||||
engine.destroyCameraComponent(camera.entity)
|
||||
|
||||
// Engine.destroyEntity() destroys Filament related resources only
|
||||
// (components), not the entity itself
|
||||
val entityManager = EntityManager.get()
|
||||
entityManager.destroy(renderable)
|
||||
entityManager.destroy(camera.entity)
|
||||
|
||||
// Destroying the engine will free up any resource you may have forgotten
|
||||
// to destroy, but it's recommended to do the cleanup properly
|
||||
|
||||
144
build.sh
144
build.sh
@@ -17,6 +17,12 @@ function print_help {
|
||||
echo " Generate .tgz build archives, implies -i."
|
||||
echo " -c"
|
||||
echo " Clean build directories."
|
||||
echo " -C"
|
||||
echo " Clean build directories and revert android/ to a freshly sync'ed state."
|
||||
echo " All (and only) git-ignored files under android/ are deleted."
|
||||
echo " This is sometimes needed instead of -c (which still misses some clean steps)."
|
||||
echo " -d"
|
||||
echo " Enable matdbg and disable material optimization."
|
||||
echo " -f"
|
||||
echo " Always invoke CMake before incremental builds."
|
||||
echo " -i"
|
||||
@@ -46,6 +52,10 @@ function print_help {
|
||||
echo " For macOS, this builds universal binaries for both Apple silicon and Intel-based Macs."
|
||||
echo " -w"
|
||||
echo " Build Web documents (compiles .md.html files to .html)."
|
||||
echo " -k sample1,sample2,..."
|
||||
echo " When building for Android, also build select sample APKs."
|
||||
echo " sampleN is an Android sample, e.g., sample-gltf-viewer."
|
||||
echo " This automatically performs a partial desktop build and install."
|
||||
echo ""
|
||||
echo "Build types:"
|
||||
echo " release"
|
||||
@@ -80,13 +90,37 @@ function print_help {
|
||||
echo ""
|
||||
}
|
||||
|
||||
function print_matdbg_help {
|
||||
echo "matdbg is enabled in the build, but some extra steps are needed."
|
||||
echo ""
|
||||
echo "FOR DESKTOP BUILDS:"
|
||||
echo ""
|
||||
echo "Please set the port environment variable before launching. e.g., on macOS do:"
|
||||
echo " export FILAMENT_MATDBG_PORT=8080"
|
||||
echo ""
|
||||
echo "FOR ANDROID BUILDS:"
|
||||
echo ""
|
||||
echo "1) The most reliable way to enable matdbg is to bypass Gradle and"
|
||||
echo " directly modify the appropriate two lines in the following file:"
|
||||
echo " ./android/filament-android/CMakeLists.txt"
|
||||
echo ""
|
||||
echo "2) The port number is hardcoded to 8081 so you will need to do:"
|
||||
echo " adb forward tcp:8081 tcp:8081"
|
||||
echo ""
|
||||
echo "3) Be sure to enable INTERNET permission in your app's manifest file."
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Unless explicitly specified, NDK version will be selected as highest available version within same major release chain
|
||||
FILAMENT_NDK_VERSION=${FILAMENT_NDK_VERSION:-$(cat `dirname $0`/build/android/ndk.version | cut -f 1 -d ".")}
|
||||
|
||||
# Requirements
|
||||
CMAKE_MAJOR=3
|
||||
CMAKE_MINOR=10
|
||||
ANDROID_NDK_VERSION=21
|
||||
CMAKE_MINOR=19
|
||||
|
||||
# Internal variables
|
||||
ISSUE_CLEAN=false
|
||||
ISSUE_CLEAN_AGGRESSIVE=false
|
||||
|
||||
ISSUE_DEBUG_BUILD=false
|
||||
ISSUE_RELEASE_BUILD=false
|
||||
@@ -111,6 +145,9 @@ ISSUE_CMAKE_ALWAYS=false
|
||||
|
||||
ISSUE_WEB_DOCS=false
|
||||
|
||||
ANDROID_SAMPLES=()
|
||||
BUILD_ANDROID_SAMPLES=false
|
||||
|
||||
RUN_TESTS=false
|
||||
|
||||
FILAMENT_ENABLE_JAVA=ON
|
||||
@@ -122,6 +159,8 @@ VULKAN_ANDROID_GRADLE_OPTION=""
|
||||
|
||||
SWIFTSHADER_OPTION="-DFILAMENT_USE_SWIFTSHADER=OFF"
|
||||
|
||||
MATDBG_OPTION="-DFILAMENT_ENABLE_MATDBG=OFF"
|
||||
|
||||
IOS_BUILD_SIMULATOR=false
|
||||
BUILD_UNIVERSAL_LIBRARIES=false
|
||||
|
||||
@@ -143,6 +182,12 @@ function build_clean {
|
||||
rm -Rf android/filament-utils-android/build android/filament-utils-android/.externalNativeBuild android/filament-utils-android/.cxx
|
||||
}
|
||||
|
||||
function build_clean_aggressive {
|
||||
echo "Cleaning build directories..."
|
||||
rm -Rf out
|
||||
git clean -qfX android
|
||||
}
|
||||
|
||||
function build_desktop_target {
|
||||
local lc_target=$(echo "$1" | tr '[:upper:]' '[:lower:]')
|
||||
local build_targets=$2
|
||||
@@ -174,6 +219,7 @@ function build_desktop_target {
|
||||
-DCMAKE_INSTALL_PREFIX="../${lc_target}/filament" \
|
||||
-DFILAMENT_ENABLE_JAVA="${FILAMENT_ENABLE_JAVA}" \
|
||||
${SWIFTSHADER_OPTION} \
|
||||
${MATDBG_OPTION} \
|
||||
${deployment_target} \
|
||||
${architectures} \
|
||||
../..
|
||||
@@ -296,8 +342,10 @@ function build_android_target {
|
||||
-G "${BUILD_GENERATOR}" \
|
||||
-DIMPORT_EXECUTABLES_DIR=out \
|
||||
-DCMAKE_BUILD_TYPE="$1" \
|
||||
-DFILAMENT_NDK_VERSION="${FILAMENT_NDK_VERSION}" \
|
||||
-DCMAKE_INSTALL_PREFIX="../android-${lc_target}/filament" \
|
||||
-DCMAKE_TOOLCHAIN_FILE="../../build/toolchain-${arch}-linux-android.cmake" \
|
||||
${MATDBG_OPTION} \
|
||||
${VULKAN_ANDROID_OPTION} \
|
||||
../..
|
||||
fi
|
||||
@@ -339,16 +387,9 @@ function ensure_android_build {
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local ndk_side_by_side="${ANDROID_HOME}/ndk/"
|
||||
if [[ -d ${ndk_side_by_side} ]]; then
|
||||
# shellcheck disable=SC2012
|
||||
local ndk_version=$(ls "${ndk_side_by_side}" | sort -V | tail -n 1 | cut -f 1 -d ".")
|
||||
if [[ ${ndk_version} -lt ${ANDROID_NDK_VERSION} ]]; then
|
||||
echo "Error: Android NDK side-by-side version ${ANDROID_NDK_VERSION} or higher must be installed, exiting"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "Error: Android NDK side-by-side version ${ANDROID_NDK_VERSION} or higher must be installed, exiting"
|
||||
# shellcheck disable=SC2012
|
||||
if [[ -z $(ls "${ANDROID_HOME}/ndk/" | sort -V | grep "^${FILAMENT_NDK_VERSION}") ]]; then
|
||||
echo "Error: Android NDK side-by-side version ${FILAMENT_NDK_VERSION} or compatible must be installed, exiting"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -372,6 +413,24 @@ function build_android {
|
||||
|
||||
build_desktop "${MOBILE_HOST_TOOLS}"
|
||||
|
||||
# When building the samples, we need to partially "install" the host tools so Gradle can see
|
||||
# them.
|
||||
if [[ "${BUILD_ANDROID_SAMPLES}" == "true" ]]; then
|
||||
if [[ "${ISSUE_DEBUG_BUILD}" == "true" ]]; then
|
||||
mkdir -p out/debug/filament/bin
|
||||
for tool in ${MOBILE_HOST_TOOLS}; do
|
||||
cp out/cmake-debug/tools/${tool}/${tool} out/debug/filament/bin/
|
||||
done
|
||||
fi
|
||||
|
||||
if [[ "${ISSUE_RELEASE_BUILD}" == "true" ]]; then
|
||||
mkdir -p out/release/filament/bin
|
||||
for tool in ${MOBILE_HOST_TOOLS}; do
|
||||
cp out/cmake-release/tools/${tool}/${tool} out/release/filament/bin/
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
INSTALL_COMMAND=${old_install_command}
|
||||
|
||||
if [[ "${ABI_ARM64_V8A}" == "true" ]]; then
|
||||
@@ -411,6 +470,15 @@ function build_android {
|
||||
-Pfilament_abis=${ABI_GRADLE_OPTION} \
|
||||
:filamat-android:assembleDebug
|
||||
|
||||
if [[ "${BUILD_ANDROID_SAMPLES}" == "true" ]]; then
|
||||
for sample in ${ANDROID_SAMPLES}; do
|
||||
./gradlew \
|
||||
-Pfilament_dist_dir=../out/android-debug/filament \
|
||||
-Pfilament_abis=${ABI_GRADLE_OPTION} \
|
||||
:samples:${sample}:assembleDebug
|
||||
done
|
||||
fi
|
||||
|
||||
if [[ "${INSTALL_COMMAND}" ]]; then
|
||||
echo "Installing out/filamat-android-debug.aar..."
|
||||
cp filamat-android/build/outputs/aar/filamat-android-lite-debug.aar ../out/
|
||||
@@ -426,6 +494,14 @@ function build_android {
|
||||
echo "Installing out/filament-utils-android-debug.aar..."
|
||||
cp filament-utils-android/build/outputs/aar/filament-utils-android-lite-debug.aar ../out/
|
||||
cp filament-utils-android/build/outputs/aar/filament-utils-android-full-debug.aar ../out/filament-utils-android-debug.aar
|
||||
|
||||
if [[ "${BUILD_ANDROID_SAMPLES}" == "true" ]]; then
|
||||
for sample in ${ANDROID_SAMPLES}; do
|
||||
echo "Installing out/${sample}-debug.apk"
|
||||
cp samples/${sample}/build/outputs/apk/debug/${sample}-debug-unsigned.apk \
|
||||
../out/${sample}-debug.apk
|
||||
done
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -443,6 +519,15 @@ function build_android {
|
||||
-Pfilament_abis=${ABI_GRADLE_OPTION} \
|
||||
:filamat-android:assembleRelease
|
||||
|
||||
if [[ "${BUILD_ANDROID_SAMPLES}" == "true" ]]; then
|
||||
for sample in ${ANDROID_SAMPLES}; do
|
||||
./gradlew \
|
||||
-Pfilament_dist_dir=../out/android-release/filament \
|
||||
-Pfilament_abis=${ABI_GRADLE_OPTION} \
|
||||
:samples:${sample}:assembleRelease
|
||||
done
|
||||
fi
|
||||
|
||||
if [[ "${INSTALL_COMMAND}" ]]; then
|
||||
echo "Installing out/filamat-android-release.aar..."
|
||||
cp filamat-android/build/outputs/aar/filamat-android-lite-release.aar ../out/
|
||||
@@ -458,6 +543,14 @@ function build_android {
|
||||
echo "Installing out/filament-utils-android-release.aar..."
|
||||
cp filament-utils-android/build/outputs/aar/filament-utils-android-lite-release.aar ../out/
|
||||
cp filament-utils-android/build/outputs/aar/filament-utils-android-full-release.aar ../out/filament-utils-android-release.aar
|
||||
|
||||
if [[ "${BUILD_ANDROID_SAMPLES}" == "true" ]]; then
|
||||
for sample in ${ANDROID_SAMPLES}; do
|
||||
echo "Installing out/${sample}-release.apk"
|
||||
cp samples/${sample}/build/outputs/apk/release/${sample}-release-unsigned.apk \
|
||||
../out/${sample}-release.apk
|
||||
done
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -484,6 +577,7 @@ function build_ios_target {
|
||||
-DPLATFORM_NAME="${platform}" \
|
||||
-DIOS=1 \
|
||||
-DCMAKE_TOOLCHAIN_FILE=../../third_party/clang/iOS.cmake \
|
||||
${MATDBG_OPTION} \
|
||||
../..
|
||||
fi
|
||||
|
||||
@@ -563,11 +657,10 @@ function build_web_docs {
|
||||
echo "Building Web documents..."
|
||||
|
||||
mkdir -p out/web-docs
|
||||
cp -f docs/web-docs-package.json out/web-docs/package.json
|
||||
cd out/web-docs
|
||||
|
||||
# Create an empty npm package to link markdeep-rasterizer into
|
||||
npm list | grep web-docs@1.0.0 > /dev/null || npm init --yes > /dev/null
|
||||
npm list | grep markdeep-rasterizer > /dev/null || npm install ../../third_party/markdeep-rasterizer > /dev/null
|
||||
npm install > /dev/null
|
||||
|
||||
# Generate documents
|
||||
npx markdeep-rasterizer ../../docs/Filament.md.html ../../docs/Materials.md.html ../../docs/
|
||||
@@ -655,7 +748,7 @@ function run_tests {
|
||||
|
||||
pushd "$(dirname "$0")" > /dev/null
|
||||
|
||||
while getopts ":hacfijmp:q:uvslwt" opt; do
|
||||
while getopts ":hacCfijmp:q:uvslwtdk:" opt; do
|
||||
case ${opt} in
|
||||
h)
|
||||
print_help
|
||||
@@ -668,6 +761,13 @@ while getopts ":hacfijmp:q:uvslwt" opt; do
|
||||
c)
|
||||
ISSUE_CLEAN=true
|
||||
;;
|
||||
C)
|
||||
ISSUE_CLEAN_AGGRESSIVE=true
|
||||
;;
|
||||
d)
|
||||
PRINT_MATDBG_HELP=true
|
||||
MATDBG_OPTION="-DFILAMENT_ENABLE_MATDBG=ON, -DFILAMENT_DISABLE_MATOPT=ON"
|
||||
;;
|
||||
f)
|
||||
ISSUE_CMAKE_ALWAYS=true
|
||||
;;
|
||||
@@ -765,6 +865,10 @@ while getopts ":hacfijmp:q:uvslwt" opt; do
|
||||
w)
|
||||
ISSUE_WEB_DOCS=true
|
||||
;;
|
||||
k)
|
||||
BUILD_ANDROID_SAMPLES=true
|
||||
ANDROID_SAMPLES=$(echo "${OPTARG}" | tr ',' '\n')
|
||||
;;
|
||||
\?)
|
||||
echo "Invalid option: -${OPTARG}" >&2
|
||||
echo ""
|
||||
@@ -803,6 +907,10 @@ if [[ "${ISSUE_CLEAN}" == "true" ]]; then
|
||||
build_clean
|
||||
fi
|
||||
|
||||
if [[ "${ISSUE_CLEAN_AGGRESSIVE}" == "true" ]]; then
|
||||
build_clean_aggressive
|
||||
fi
|
||||
|
||||
if [[ "${ISSUE_DESKTOP_BUILD}" == "true" ]]; then
|
||||
build_desktop
|
||||
fi
|
||||
@@ -826,3 +934,7 @@ fi
|
||||
if [[ "${RUN_TESTS}" == "true" ]]; then
|
||||
run_tests
|
||||
fi
|
||||
|
||||
if [[ "${PRINT_MATDBG_HELP}" == "true" ]]; then
|
||||
print_matdbg_help
|
||||
fi
|
||||
|
||||
@@ -8,12 +8,6 @@
|
||||
#
|
||||
# The default is release
|
||||
|
||||
NDK_VERSION="ndk;22.0.7026061"
|
||||
ANDROID_NDK_VERSION=22
|
||||
|
||||
# Exclude Vulkan from CI builds for Android. (It is enabled for other platforms.)
|
||||
EXCLUDE_VULKAN=-v
|
||||
|
||||
echo "This script is intended to run in a CI environment and may modify your current environment."
|
||||
echo "Please refer to BUILDING.md for more information."
|
||||
|
||||
@@ -50,20 +44,12 @@ elif [[ "$LC_UNAME" == "darwin" ]]; then
|
||||
fi
|
||||
source `dirname $0`/../common/build-common.sh
|
||||
|
||||
# For continuous builds, do not exclude Vulkan.
|
||||
if [[ "$TARGET" == "continuous" ]]; then
|
||||
EXCLUDE_VULKAN=
|
||||
fi
|
||||
# Unless explicitly specified, NDK version will be set to match exactly the required one
|
||||
FILAMENT_NDK_VERSION=${FILAMENT_NDK_VERSION:-$(cat `dirname $0`/ndk.version)}
|
||||
|
||||
# Only update and install the NDK if necessary, as this can be slow
|
||||
ndk_side_by_side="${ANDROID_HOME}/ndk/"
|
||||
if [[ -d $ndk_side_by_side ]]; then
|
||||
ndk_version=`ls ${ndk_side_by_side} | sort -V | tail -n 1 | cut -f 1 -d "."`
|
||||
if [[ ${ndk_version} -lt ${ANDROID_NDK_VERSION} ]]; then
|
||||
${ANDROID_HOME}/tools/bin/sdkmanager "${NDK_VERSION}" > /dev/null
|
||||
fi
|
||||
else
|
||||
${ANDROID_HOME}/tools/bin/sdkmanager "${NDK_VERSION}" > /dev/null
|
||||
# Install the required NDK version specifically (if not present)
|
||||
if [[ ! -d "${ANDROID_HOME}/ndk/$FILAMENT_NDK_VERSION" ]]; then
|
||||
${ANDROID_HOME}/tools/bin/sdkmanager "ndk;$FILAMENT_NDK_VERSION" > /dev/null
|
||||
fi
|
||||
|
||||
# Only build 1 32 bit and 1 64 bit target during presubmit to cut down build times
|
||||
@@ -73,5 +59,11 @@ if [[ "$TARGET" == "presubmit" ]]; then
|
||||
ANDROID_ABIS="-q arm64-v8a,x86"
|
||||
fi
|
||||
|
||||
# Build the Android sample-gltf-viewer APK during release.
|
||||
BUILD_SAMPLES=
|
||||
if [[ "$TARGET" == "release" ]]; then
|
||||
BUILD_SAMPLES="-k sample-gltf-viewer"
|
||||
fi
|
||||
|
||||
pushd `dirname $0`/../.. > /dev/null
|
||||
./build.sh -p android $EXCLUDE_VULKAN $ANDROID_ABIS -c $GENERATE_ARCHIVES $BUILD_DEBUG $BUILD_RELEASE
|
||||
FILAMENT_NDK_VERSION=${FILAMENT_NDK_VERSION} ./build.sh -p android $ANDROID_ABIS -c $BUILD_SAMPLES $GENERATE_ARCHIVES $BUILD_DEBUG $BUILD_RELEASE
|
||||
|
||||
1
build/android/ndk.version
Normal file
1
build/android/ndk.version
Normal file
@@ -0,0 +1 @@
|
||||
22.1.7171670
|
||||
@@ -134,7 +134,7 @@ git commit --amend -C HEAD
|
||||
####################################################################################################
|
||||
|
||||
git checkout main
|
||||
git branch --track "${NEW_RC_BRANCH}"
|
||||
git branch "${NEW_RC_BRANCH}"
|
||||
|
||||
####################################################################################################
|
||||
# Delete the old release candidate branch
|
||||
@@ -154,7 +154,7 @@ if [[ "${PUSH_CHANGES}" == "true" ]]; then
|
||||
git push origin --delete "${RC_BRANCH}"
|
||||
|
||||
# Push the new rc branch
|
||||
git push origin "${NEW_RC_BRANCH}"
|
||||
git push origin -u "${NEW_RC_BRANCH}"
|
||||
else
|
||||
echo ""
|
||||
echo "Done."
|
||||
@@ -164,7 +164,7 @@ else
|
||||
echo "---------------------------------------------------------"
|
||||
echo "git push origin release"
|
||||
echo "git push origin --delete ${RC_BRANCH}"
|
||||
echo "git push origin ${NEW_RC_BRANCH}"
|
||||
echo "git push origin -u ${NEW_RC_BRANCH}"
|
||||
echo "---------------------------------------------------------"
|
||||
echo "Or, to undo everything:"
|
||||
echo "---------------------------------------------------------"
|
||||
|
||||
@@ -10,7 +10,7 @@ XCODEBUILD_FLAGS='CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_AL
|
||||
# This sets the BUILD_DEBUG and BUILD_RELEASE variables based on the CI job.
|
||||
pushd `dirname $0`/../../ios/samples
|
||||
|
||||
PROJECTS="hello-ar hello-gltf hello-pbr hello-triangle transparent-rendering"
|
||||
PROJECTS="gltf-viewer hello-ar hello-gltf hello-pbr hello-triangle transparent-rendering"
|
||||
|
||||
function build_project {
|
||||
local project="$1"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
curl -OL https://github.com/ninja-build/ninja/releases/download/v1.8.2/ninja-mac.zip
|
||||
curl -OL https://github.com/ninja-build/ninja/releases/download/v1.10.2/ninja-mac.zip
|
||||
unzip -q ninja-mac.zip
|
||||
chmod +x ninja
|
||||
export PATH="$PWD:$PATH"
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
# version of clang we want to use
|
||||
GITHUB_CLANG_VERSION=8
|
||||
# version of CMake to use instead of the default one
|
||||
CMAKE_VERSION=3.13.4
|
||||
CMAKE_VERSION=3.19.5
|
||||
# version of ninja to use
|
||||
NINJA_VERSION=1.8.2
|
||||
NINJA_VERSION=1.10.2
|
||||
|
||||
# Steps for GitHub Workflows
|
||||
if [[ "$GITHUB_WORKFLOW" ]]; then
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
curl -OL https://github.com/ninja-build/ninja/releases/download/v1.8.2/ninja-mac.zip
|
||||
curl -OL https://github.com/ninja-build/ninja/releases/download/v1.10.2/ninja-mac.zip
|
||||
unzip -q ninja-mac.zip
|
||||
chmod +x ninja
|
||||
export PATH="$PWD:$PATH"
|
||||
|
||||
@@ -31,7 +31,11 @@ set(DIST_ARCH arm64-v8a)
|
||||
string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} HOST_NAME_L)
|
||||
file(TO_CMAKE_PATH $ENV{ANDROID_HOME} ANDROID_HOME_UNIX)
|
||||
|
||||
file(GLOB NDK_VERSIONS LIST_DIRECTORIES true ${ANDROID_HOME_UNIX}/ndk/*)
|
||||
if (NOT FILAMENT_NDK_VERSION)
|
||||
file(READ "${CMAKE_CURRENT_LIST_DIR}/android/ndk.version" FILAMENT_NDK_VERSION)
|
||||
string(REGEX MATCH "^\\d+" FILAMENT_NDK_VERSION ${FILAMENT_NDK_VERSION})
|
||||
endif()
|
||||
file(GLOB NDK_VERSIONS LIST_DIRECTORIES true ${ANDROID_HOME_UNIX}/ndk/${FILAMENT_NDK_VERSION}*)
|
||||
list(SORT NDK_VERSIONS)
|
||||
list(GET NDK_VERSIONS -1 NDK_VERSION)
|
||||
get_filename_component(NDK_VERSION ${NDK_VERSION} NAME)
|
||||
|
||||
@@ -32,7 +32,11 @@ set(DIST_ARCH armeabi-v7a)
|
||||
string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} HOST_NAME_L)
|
||||
file(TO_CMAKE_PATH $ENV{ANDROID_HOME} ANDROID_HOME_UNIX)
|
||||
|
||||
file(GLOB NDK_VERSIONS LIST_DIRECTORIES true ${ANDROID_HOME_UNIX}/ndk/*)
|
||||
if (NOT FILAMENT_NDK_VERSION)
|
||||
file(READ "${CMAKE_CURRENT_LIST_DIR}/android/ndk.version" FILAMENT_NDK_VERSION)
|
||||
string(REGEX MATCH "^\\d+" FILAMENT_NDK_VERSION ${FILAMENT_NDK_VERSION})
|
||||
endif()
|
||||
file(GLOB NDK_VERSIONS LIST_DIRECTORIES true ${ANDROID_HOME_UNIX}/ndk/${FILAMENT_NDK_VERSION}*)
|
||||
list(SORT NDK_VERSIONS)
|
||||
list(GET NDK_VERSIONS -1 NDK_VERSION)
|
||||
get_filename_component(NDK_VERSION ${NDK_VERSION} NAME)
|
||||
|
||||
@@ -31,7 +31,11 @@ set(DIST_ARCH x86)
|
||||
string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} HOST_NAME_L)
|
||||
file(TO_CMAKE_PATH $ENV{ANDROID_HOME} ANDROID_HOME_UNIX)
|
||||
|
||||
file(GLOB NDK_VERSIONS LIST_DIRECTORIES true ${ANDROID_HOME_UNIX}/ndk/*)
|
||||
if (NOT FILAMENT_NDK_VERSION)
|
||||
file(READ "${CMAKE_CURRENT_LIST_DIR}/android/ndk.version" FILAMENT_NDK_VERSION)
|
||||
string(REGEX MATCH "^\\d+" FILAMENT_NDK_VERSION ${FILAMENT_NDK_VERSION})
|
||||
endif()
|
||||
file(GLOB NDK_VERSIONS LIST_DIRECTORIES true ${ANDROID_HOME_UNIX}/ndk/${FILAMENT_NDK_VERSION}*)
|
||||
list(SORT NDK_VERSIONS)
|
||||
list(GET NDK_VERSIONS -1 NDK_VERSION)
|
||||
get_filename_component(NDK_VERSION ${NDK_VERSION} NAME)
|
||||
|
||||
@@ -31,7 +31,11 @@ set(DIST_ARCH x86_64)
|
||||
string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} HOST_NAME_L)
|
||||
file(TO_CMAKE_PATH $ENV{ANDROID_HOME} ANDROID_HOME_UNIX)
|
||||
|
||||
file(GLOB NDK_VERSIONS LIST_DIRECTORIES true ${ANDROID_HOME_UNIX}/ndk/*)
|
||||
if (NOT FILAMENT_NDK_VERSION)
|
||||
file(READ "${CMAKE_CURRENT_LIST_DIR}/android/ndk.version" FILAMENT_NDK_VERSION)
|
||||
string(REGEX MATCH "^\\d+" FILAMENT_NDK_VERSION ${FILAMENT_NDK_VERSION})
|
||||
endif()
|
||||
file(GLOB NDK_VERSIONS LIST_DIRECTORIES true ${ANDROID_HOME_UNIX}/ndk/${FILAMENT_NDK_VERSION}*)
|
||||
list(SORT NDK_VERSIONS)
|
||||
list(GET NDK_VERSIONS -1 NDK_VERSION)
|
||||
get_filename_component(NDK_VERSION ${NDK_VERSION} NAME)
|
||||
|
||||
@@ -9,7 +9,7 @@ export PATH="$PWD:$PATH"
|
||||
# npm install -g typescript
|
||||
|
||||
# Install emscripten.
|
||||
curl -L https://github.com/emscripten-core/emsdk/archive/1.39.19.zip > emsdk.zip
|
||||
curl -L https://github.com/emscripten-core/emsdk/archive/2.0.23.zip > emsdk.zip
|
||||
unzip emsdk.zip ; mv emsdk-* emsdk ; cd emsdk
|
||||
./emsdk install latest
|
||||
./emsdk activate latest
|
||||
|
||||
1618
docs/Filament.html
1618
docs/Filament.html
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user