Compare commits
693 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 | ||
|
|
b96bc30fbd | ||
|
|
7bf04e1f71 | ||
|
|
939f3b975c | ||
|
|
62b50eb8ba | ||
|
|
e247ffad9b | ||
|
|
fb29ae9fa5 | ||
|
|
706a685ca6 | ||
|
|
4ad947f0ad | ||
|
|
a1939189ea | ||
|
|
fe49c1eb82 | ||
|
|
4d18c0d61c | ||
|
|
6fa8f48be5 | ||
|
|
ba32cef717 | ||
|
|
e6d3d26c6b | ||
|
|
180cf24b58 | ||
|
|
0f9cee0b83 | ||
|
|
317c82711b | ||
|
|
3f32146849 | ||
|
|
9da69dac46 | ||
|
|
b4932e384a | ||
|
|
1516b135fd | ||
|
|
06538145b5 | ||
|
|
ec486b888c | ||
|
|
7b7d63a91f | ||
|
|
466629d967 | ||
|
|
5e68dc5f8d | ||
|
|
c4d0dcf639 | ||
|
|
ad90fa1183 | ||
|
|
ed57d6a40f | ||
|
|
f222f1b925 | ||
|
|
22e4a54782 | ||
|
|
1289922c5f | ||
|
|
2839c352b8 | ||
|
|
6a01cbc312 | ||
|
|
00f50c5f5a | ||
|
|
23c90a624d | ||
|
|
0e27f0c162 | ||
|
|
297f3d9808 | ||
|
|
b4f6400d2e | ||
|
|
4d905eb4bb | ||
|
|
83a58033d1 | ||
|
|
edc8162ebb | ||
|
|
da2c9b8092 | ||
|
|
2cf3fb569a | ||
|
|
0c6de2cb58 | ||
|
|
07ddd52dcf | ||
|
|
f6425fdcfb | ||
|
|
521c7fc713 | ||
|
|
3175711323 | ||
|
|
d669b1b26f | ||
|
|
c2b4b6347e | ||
|
|
8d13b7634c | ||
|
|
89bf201b6c | ||
|
|
9f68daeb8f | ||
|
|
c62b88013b | ||
|
|
2e8df10e6e | ||
|
|
2f9c310127 | ||
|
|
6193156556 | ||
|
|
6eec2cde81 | ||
|
|
98ae61ffe5 | ||
|
|
adb489c77a | ||
|
|
eeccfed8e4 | ||
|
|
893ed861e9 | ||
|
|
411ae23512 | ||
|
|
8f05984551 | ||
|
|
4567b01c1d | ||
|
|
29315f9a1b | ||
|
|
d4a2d30a1c | ||
|
|
cec5f3e988 | ||
|
|
02501c6e60 | ||
|
|
4d8da14c1f | ||
|
|
4fae917fb5 | ||
|
|
c84036c8c4 | ||
|
|
34429f5490 | ||
|
|
59c2d5bef3 | ||
|
|
a3412c4f45 | ||
|
|
564d846be5 | ||
|
|
41186340c9 | ||
|
|
96bba71739 | ||
|
|
5ab7a9e3ab | ||
|
|
4c30067dac | ||
|
|
243ba77025 | ||
|
|
229f1f6d95 | ||
|
|
bc2eae2ecd | ||
|
|
e468ec91b7 | ||
|
|
ca2829461a | ||
|
|
7805687f7a | ||
|
|
af82aaa0fc | ||
|
|
410ecfd014 | ||
|
|
0df1f9fcce | ||
|
|
45f7e07832 | ||
|
|
1aefe741b2 | ||
|
|
d1842919cf | ||
|
|
6473771f1e | ||
|
|
2d57a82b49 | ||
|
|
dc2d55c409 | ||
|
|
c0b8e98a93 | ||
|
|
8252bbe512 | ||
|
|
a4817f3e2a | ||
|
|
fa879b4bd0 | ||
|
|
005e4ba2ec | ||
|
|
d2299c4502 | ||
|
|
5c666c254e | ||
|
|
a09c17bd4f | ||
|
|
57df4481e9 | ||
|
|
47af85aed1 | ||
|
|
44fc295913 | ||
|
|
6878b0be36 | ||
|
|
6c222bf4e3 | ||
|
|
eb70fd5dee | ||
|
|
986a3869cc | ||
|
|
9ad3d88d74 | ||
|
|
a3bfdb89fa | ||
|
|
2895530e09 | ||
|
|
f8069aa99f | ||
|
|
b70eea9556 | ||
|
|
44a8da6a8e | ||
|
|
3bd066f993 | ||
|
|
1b10afa9e6 | ||
|
|
024910ba8e | ||
|
|
f2e3a132db | ||
|
|
87abd1f8bc | ||
|
|
57662c52f2 | ||
|
|
a50cd1f8c8 | ||
|
|
fe907398d4 | ||
|
|
8b6ddfe97a | ||
|
|
3226b20ece | ||
|
|
61d473887f | ||
|
|
b3d7819e78 | ||
|
|
de6220594d | ||
|
|
d9dfe69a81 | ||
|
|
22d4e63787 | ||
|
|
f033799a43 | ||
|
|
30e150c016 | ||
|
|
f5f27749a4 | ||
|
|
b5f95213db | ||
|
|
d42865373d | ||
|
|
f83eb114bc | ||
|
|
9c20294e4b | ||
|
|
40e7a86f5f | ||
|
|
34707431f7 |
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.0.1 or more recent
|
||||
- Android Studio 4.2.0 or more recent
|
||||
- Android SDK
|
||||
- Android NDK "side-by-side" 21.3 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/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
|
||||
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."
|
||||
)
|
||||
@@ -88,7 +92,6 @@ if (UNIX AND NOT APPLE AND NOT ANDROID AND NOT WEBGL)
|
||||
endif()
|
||||
|
||||
if (LINUX)
|
||||
|
||||
if (FILAMENT_SUPPORTS_XCB)
|
||||
add_definitions(-DFILAMENT_SUPPORTS_XCB)
|
||||
endif()
|
||||
@@ -96,14 +99,6 @@ if (LINUX)
|
||||
if (FILAMENT_SUPPORTS_XLIB)
|
||||
add_definitions(-DFILAMENT_SUPPORTS_XLIB)
|
||||
endif()
|
||||
|
||||
execute_process(COMMAND uname -p
|
||||
OUTPUT_VARIABLE PROCESSOR_ARCH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
if ("${PROCESSOR_ARCH}" STREQUAL "aarch64")
|
||||
set(LINUX_AARCH64 TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (ANDROID OR WEBGL OR IOS)
|
||||
@@ -271,7 +266,10 @@ if (LINUX)
|
||||
# /usr/bin/ld: ../bluegl/libbluegl.a(BlueGL.cpp.o): relocation R_X86_64_32S
|
||||
# against `.bss' can not be used when making a shared object; recompile with -fPIC
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
|
||||
endif()
|
||||
|
||||
if (ANDROID)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
|
||||
endif()
|
||||
|
||||
if (CYGWIN)
|
||||
@@ -305,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()
|
||||
|
||||
@@ -371,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)
|
||||
@@ -406,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
|
||||
# ==================================================================================================
|
||||
@@ -419,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()
|
||||
@@ -429,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()
|
||||
|
||||
@@ -441,8 +451,23 @@ set(MATC_BASE_FLAGS ${MATC_API_FLAGS} -p ${MATC_TARGET} ${MATC_OPT_FLAGS})
|
||||
# ==================================================================================================
|
||||
# choose where to put the objects in the dist folder
|
||||
if (NOT DIST_ARCH)
|
||||
set(DIST_ARCH x86_64)
|
||||
# On Apple silicon, the value of CMAKE_HOST_SYSTEM_PROCESSOR varies based on the CMake process's
|
||||
# own architecture. Because of this, running a x86_64 CMake binary on Apple silicon will cause
|
||||
# DIST_ARCH to be set incorrectly.
|
||||
set(DIST_ARCH "${CMAKE_HOST_SYSTEM_PROCESSOR}")
|
||||
|
||||
if (CMAKE_OSX_ARCHITECTURES MATCHES ".*;.*")
|
||||
set(DIST_ARCH "universal")
|
||||
else()
|
||||
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()
|
||||
@@ -567,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)
|
||||
|
||||
@@ -597,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()
|
||||
@@ -619,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)
|
||||
@@ -633,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)
|
||||
|
||||
51
README.md
51
README.md
@@ -31,7 +31,7 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.android.filament:filament-android:1.9.10'
|
||||
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.10'
|
||||
pod 'Filament', '~> 1.10.5'
|
||||
```
|
||||
|
||||
### Snapshots
|
||||
@@ -131,17 +131,19 @@ 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
|
||||
- Anisotropic lighting
|
||||
- Approximated translucent (subsurface) materials
|
||||
- Cloth shading
|
||||
- Cloth/fabric/sheen shading
|
||||
- Normal mapping & ambient occlusion mapping
|
||||
- Image-based lighting
|
||||
- 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,52 @@ 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
|
||||
|
||||
- Encodings
|
||||
- [x] Embeded
|
||||
- [x] Binary
|
||||
|
||||
- Primitive Types
|
||||
- [x] Points
|
||||
- [x] Lines
|
||||
- [ ] Line Loop
|
||||
- [ ] Line Strip
|
||||
- [x] Triangles
|
||||
- [ ] Triangle Strip
|
||||
- [ ] Triangle Fan
|
||||
|
||||
- Animation
|
||||
- [x] Transform animation
|
||||
- [x] Linear interpolation
|
||||
- [x] Morph animation
|
||||
- [x] Sparse accessor
|
||||
- [x] Skin animation
|
||||
- [x] Joint animation
|
||||
|
||||
- Extensions
|
||||
- [x] KHR_draco_mesh_compression
|
||||
- [x] KHR_lights_punctual
|
||||
- [x] KHR_materials_clearcoat
|
||||
- [x] KHR_materials_pbrSpecularGlossiness
|
||||
- [x] KHR_materials_sheen
|
||||
- [x] KHR_materials_transmission
|
||||
- [x] KHR_materials_unlit
|
||||
- [x] KHR_mesh_quantization
|
||||
- [x] KHR_texture_transform
|
||||
|
||||
|
||||
## Rendering with Filament
|
||||
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
255
RELEASE_NOTES.md
255
RELEASE_NOTES.md
@@ -3,32 +3,263 @@
|
||||
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)
|
||||
|
||||
## v.1.9.11
|
||||
## 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
|
||||
|
||||
- engine: Fixed GL errors seen with MSAA on WebGL.
|
||||
Warning: this can affect multisampling behavior on devices that do not support OpenGL ES 3.1
|
||||
- materials: Added new `getVertexIndex()` API for vertex shaders.
|
||||
- samples: RenderTarget demo now disables post-processing in offscreen view and creates depth attachment.
|
||||
- gltfio: Fix, animation jolt when time delta is very small.
|
||||
|
||||
## v1.9.11
|
||||
|
||||
- Added support for Apple silicon Macs. build.sh can now be used to build on either Apple silicon or
|
||||
Intel-based Macs. Pass the `-l` flag to build universal binaries.
|
||||
- Added `sheenColor` and `sheenRoughness` properties to materials to create cloth/fabric.
|
||||
- Materials generation using `libfilamat` is now multi-threaded.
|
||||
- `MaterialBuilder::build()` now expects a reference to a `JobSystem` to multi-thread shaders
|
||||
generation. A `JobSystem` can be obtained with `Engine::getJobSystem()` when using Filament,
|
||||
or created directly otherwise. (⚠️ **API change**)
|
||||
- Add planar reflection RenderTarget demo.
|
||||
- Metal: honor inverseFrontFaces RasterState.
|
||||
- Metal: Fix crash when switching between views with shadowing enabled.
|
||||
- Metal: Fix crash when calling Texture::setImage() on SAMPLER_2D_ARRAY texture.
|
||||
- gltfio: added support for `KHR_materials_sheen`.
|
||||
- gltfio: shader optimizations are now disabled by default, unless opting in or using ubershaders.
|
||||
- gltfio: Fix "_maskThreshold not found" error.
|
||||
- gltfio on Java: fix potential memory leak in AssetLoader#destroy.
|
||||
- gltfio: fix crash during async texture decode.
|
||||
- gltfio: support animation in dynamically-added instances.
|
||||
- gltfio: Improve robustness when decoding textures.
|
||||
- gltfio: Fix animator crash for orphaned nodes.
|
||||
- gltfio: fix tangents with morphing.
|
||||
- gltf_viewer: fix very sporadic crash when exiting.
|
||||
- gltf_viewer: fix crash when rapidly switching between glTF models.
|
||||
- WebGL: Fix samples erroring on Windows with Chrome.
|
||||
- WebGL: Support `highlight` for setBloomOptions in JavaScript.
|
||||
- WebGL: Include TypeScript bindings in releases.
|
||||
- engine: Fix, punctual lights get clipped at certain angles.
|
||||
- engine: Fix memory leak when calling `View::setViewport` frequently.
|
||||
- engine: Fix, materials not working on some Qualcomm devices.
|
||||
- engine: Modulate emissive by alpha on blended objects.
|
||||
- engine: Fix, RenderTarget cleared multiple times.
|
||||
- Java: Fix JNI bindings for color grading.
|
||||
- Android: reduced binary size.
|
||||
|
||||
## v1.9.10
|
||||
|
||||
- Introduce libibl_lite library.
|
||||
- engine: Fix EXC_BAD_INSTRUCTION seen when using headless SwapChains on macOS with OpenGL.
|
||||
- engine: Add new callback API to SwapChain.
|
||||
- Introduce `libibl_lite` library.
|
||||
- engine: Fix `EXC_BAD_INSTRUCTION` seen when using headless SwapChains on macOS with OpenGL.
|
||||
- engine: Add new callback API to `SwapChain`.
|
||||
- engine: Fix SwiftShader crash when using an IBL without a reflections texture.
|
||||
- filamat: Shrink internal Skybox material size.
|
||||
- filamat: Shrink internal `Skybox` material size.
|
||||
- filamat: improvements to generated material size.
|
||||
- filamat: silence spirv-opt warnings in release builds.
|
||||
- matc: Add fog variant filter.
|
||||
- matc: Fix crash when building mobile materials.
|
||||
- math: reduce template bloat for matrices.
|
||||
- Vulkan: robustness improvements.
|
||||
|
||||
## v1.9.9
|
||||
|
||||
- Vulkan: internal robustness improvements
|
||||
- Metal: Support CVPixelBuffer SwapChains
|
||||
- Metal: Support copyFrame
|
||||
- Vulkan: internal robustness improvements.
|
||||
- Metal: Support CVPixelBuffer SwapChains.
|
||||
- Metal: Support copyFrame.
|
||||
- Fix clear behavior with RenderTarget API.
|
||||
- Fix GetRefractionMode JNI binding
|
||||
- Additional fixes for Fence bug
|
||||
- Fix GetRefractionMode JNI binding.
|
||||
- Additional fixes for Fence bug.
|
||||
|
||||
## v1.9.8
|
||||
|
||||
|
||||
@@ -64,9 +64,9 @@ buildscript {
|
||||
'minSdk': 19,
|
||||
'targetSdk': 30,
|
||||
'compileSdk': 30,
|
||||
'kotlin': '1.4.10',
|
||||
'buildTools': '30.0.2',
|
||||
'ndk': '21.3.6528147'
|
||||
'kotlin': '1.5.0',
|
||||
'buildTools': '30.0.3',
|
||||
'ndk': '22.1.7171670'
|
||||
]
|
||||
|
||||
ext.deps = [
|
||||
@@ -78,7 +78,7 @@ buildscript {
|
||||
]
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.1.0'
|
||||
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)
|
||||
|
||||
@@ -33,13 +34,16 @@ add_library(shaders STATIC IMPORTED)
|
||||
set_target_properties(shaders PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libshaders.a)
|
||||
|
||||
set(FILAMAT_INCLUDE_DIRS
|
||||
../../libs/utils/include
|
||||
)
|
||||
|
||||
include_directories(${FILAMENT_DIR}/include)
|
||||
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -Wl,--version-script=${CMAKE_SOURCE_DIR}/libfilamat-jni.map")
|
||||
|
||||
add_library(filamat-jni SHARED
|
||||
src/main/cpp/MaterialBuilder.cpp
|
||||
)
|
||||
add_library(filamat-jni SHARED src/main/cpp/MaterialBuilder.cpp)
|
||||
target_include_directories(filamat-jni PRIVATE ${FILAMAT_INCLUDE_DIRS})
|
||||
|
||||
target_link_libraries(filamat-jni
|
||||
${FILAMAT_FLAVOR}
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#include <filamat/MaterialBuilder.h>
|
||||
|
||||
#include <utils/JobSystem.h>
|
||||
|
||||
using namespace filament;
|
||||
using namespace filamat;
|
||||
|
||||
@@ -45,9 +47,23 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nDestroyMaterialBuilder
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nBuilderBuild(JNIEnv*, jclass,
|
||||
jlong nativeBuilder) {
|
||||
jlong nativeBuilder, jlong nativeJobSystem) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
return (jlong) new Package(builder->build());
|
||||
auto jobSystem = (utils::JobSystem*) nativeJobSystem;
|
||||
|
||||
if (nativeJobSystem == 0) {
|
||||
jobSystem = new utils::JobSystem;
|
||||
jobSystem->adopt();
|
||||
}
|
||||
|
||||
jlong result = (jlong) new Package(builder->build(*jobSystem));
|
||||
|
||||
if (nativeJobSystem == 0) {
|
||||
jobSystem->emancipate();
|
||||
delete jobSystem;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jbyteArray JNICALL
|
||||
@@ -275,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) {
|
||||
|
||||
@@ -17,17 +17,29 @@
|
||||
package com.google.android.filament.filamat;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class MaterialBuilder {
|
||||
|
||||
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
|
||||
// Keep to finalize native resources
|
||||
private final BuilderFinalizer mFinalizer;
|
||||
private final long mNativeObject;
|
||||
|
||||
private static Class<?> sEngineClass = null;
|
||||
private static Method sGetNativeJobSystemMethod = null;
|
||||
|
||||
static {
|
||||
System.loadLibrary("filamat-jni");
|
||||
try {
|
||||
sEngineClass = Class.forName("com.google.android.filament.Engine");
|
||||
sGetNativeJobSystemMethod = sEngineClass.getDeclaredMethod("getNativeJobSystem");
|
||||
} catch (ClassNotFoundException | NoSuchMethodException e) {
|
||||
// It's okay if we don't find it, this is to avoid creating dependencies
|
||||
}
|
||||
}
|
||||
|
||||
public enum Shading {
|
||||
@@ -379,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);
|
||||
@@ -421,9 +439,55 @@ public class MaterialBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates, builds, and returns the compiled material. While this method never
|
||||
* returns null, the returned {@link MaterialPackage} may be invalid. Call
|
||||
* {@link MaterialPackage#isValid()} before using it.
|
||||
*
|
||||
* Calling this method is equivalent to calling {@link #build(Object)} and passing
|
||||
* <code>null</code> as the job system provider.
|
||||
*
|
||||
* @see #build(Object)
|
||||
*/
|
||||
@NonNull
|
||||
public MaterialPackage build() {
|
||||
long nativePackage = nBuilderBuild(mNativeObject);
|
||||
return build(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates, builds, and returns the compiled material. While this method never
|
||||
* returns null, the returned {@link MaterialPackage} may be invalid. Call
|
||||
* {@link MaterialPackage#isValid()} before using it.
|
||||
*
|
||||
* You can pass a job system provider to this method, or null. When passing null
|
||||
* or an invalid job system provider, a temporary job system will be created which
|
||||
* is less efficient than reusing an existing job system.
|
||||
*
|
||||
* Currently the only valid type of job system provider is an <code>Engine</code>
|
||||
* instance from the main Filament library (<code>com.google.android.filament.Engine</code>).
|
||||
*
|
||||
* If you are using Filament and the filamat library together you <em>must</em> pass an
|
||||
* <code>Engine</code> as the job system provider, <em>or</em> invoke
|
||||
* <code>MaterialBuilder</code> from a thread other than the thread used to invoke Filament
|
||||
* APIs.
|
||||
*
|
||||
* @param jobSystemProvider An <code>Engine</code> instance or null
|
||||
*/
|
||||
@NonNull
|
||||
public MaterialPackage build(@Nullable Object jobSystemProvider) {
|
||||
long nativeJobSystem = 0;
|
||||
if (jobSystemProvider != null && sEngineClass != null) {
|
||||
if (sEngineClass.isInstance(jobSystemProvider) && sGetNativeJobSystemMethod != null) {
|
||||
try {
|
||||
//noinspection ConstantConditions
|
||||
nativeJobSystem = (Long) sGetNativeJobSystemMethod.invoke(jobSystemProvider);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long nativePackage = nBuilderBuild(mNativeObject, nativeJobSystem);
|
||||
byte[] data = nGetPackageBytes(nativePackage);
|
||||
MaterialPackage result =
|
||||
new MaterialPackage(ByteBuffer.wrap(data), nGetPackageIsValid(nativePackage));
|
||||
@@ -455,7 +519,7 @@ public class MaterialBuilder {
|
||||
private static native long nCreateMaterialBuilder();
|
||||
private static native void nDestroyMaterialBuilder(long nativeBuilder);
|
||||
|
||||
private static native long nBuilderBuild(long nativeBuilder);
|
||||
private static native long nBuilderBuild(long nativeBuilder, long nativeJobSystem);
|
||||
private static native byte[] nGetPackageBytes(long nativePackage);
|
||||
private static native boolean nGetPackageIsValid(long nativePackage);
|
||||
private static native void nDestroyPackage(long nativePackage);
|
||||
@@ -498,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})
|
||||
|
||||
@@ -37,6 +39,10 @@ add_library(bluevk STATIC IMPORTED)
|
||||
set_target_properties(bluevk PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libbluevk.a)
|
||||
|
||||
add_library(vkshaders STATIC IMPORTED)
|
||||
set_target_properties(vkshaders PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libvkshaders.a)
|
||||
|
||||
add_library(smol-v STATIC IMPORTED)
|
||||
set_target_properties(smol-v PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libsmol-v.a)
|
||||
@@ -51,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
|
||||
@@ -91,7 +98,6 @@ target_link_libraries(filament-jni
|
||||
PRIVATE backend
|
||||
PRIVATE filaflat
|
||||
PRIVATE filabridge
|
||||
PRIVATE geometry
|
||||
PRIVATE ibl-lite
|
||||
PRIVATE log
|
||||
PRIVATE GLESv3
|
||||
@@ -99,8 +105,13 @@ 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>
|
||||
$<$<STREQUAL:${FILAMENT_SUPPORTS_VULKAN},ON>:smol-v>
|
||||
)
|
||||
|
||||
|
||||
@@ -1,4 +1,27 @@
|
||||
LIBFILAMENT {
|
||||
global: *filament*; JNI*;
|
||||
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*;
|
||||
|
||||
local: *;
|
||||
};
|
||||
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
|
||||
@@ -306,3 +300,15 @@ Java_com_google_android_filament_Engine_nGetRenderableManager(JNIEnv*, jclass,
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
return (jlong) &engine->getRenderableManager();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_Engine_nGetJobSystem(JNIEnv*, jclass, jlong nativeEngine) {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -204,9 +204,20 @@ Java_com_google_android_filament_Material_nGetParameters(JNIEnv* env, jclass,
|
||||
jfieldID parameterSamplerOffset = env->GetStaticFieldID(parameterClass,
|
||||
"SAMPLER_OFFSET", "I");
|
||||
|
||||
jfieldID parameterSubpassOffset = env->GetStaticFieldID(parameterClass,
|
||||
"SUBPASS_OFFSET", "I");
|
||||
|
||||
jint offset = env->GetStaticIntField(parameterClass, parameterSamplerOffset);
|
||||
jint subpassOffset = env->GetStaticIntField(parameterClass, parameterSubpassOffset);
|
||||
for (size_t i = 0; i < received; i++) {
|
||||
jint type = info[i].isSampler ? (jint) info[i].samplerType + offset : (jint) info[i].type;
|
||||
jint type;
|
||||
if (info[i].isSampler) {
|
||||
type = (jint) info[i].samplerType + offset;
|
||||
} else if (info[i].isSubpass) {
|
||||
type = subpassOffset;
|
||||
} else {
|
||||
type = (jint) info[i].type;
|
||||
}
|
||||
|
||||
env->CallStaticVoidMethod(
|
||||
parameterClass, parameterAdd,
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -38,7 +38,14 @@ bool acquireDrawingSurface(JNIEnv* env, jobject surface,
|
||||
jboolean foundJawt = JNI_FALSE;
|
||||
for (int jawtVersion : jawtVersions) {
|
||||
awt.version = jawtVersion;
|
||||
#if defined(__APPLE__) && defined(__aarch64__)
|
||||
// FIXME: enable Apple Silicon build. The problem here is that we attempt to link an x86 jdk and that fails
|
||||
// so JAWT_GetAWT doesn't exist at link time.
|
||||
#warning "FIXME: JAWT_GetAWT() not supported"
|
||||
foundJawt = {};
|
||||
#else
|
||||
foundJawt = JAWT_GetAWT(env, &awt);
|
||||
#endif
|
||||
if (foundJawt == JNI_TRUE) {
|
||||
#ifndef NDEBUG
|
||||
printf("Found valid AWT v%08x.\n", jawtVersion);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -270,7 +271,7 @@ public class ColorGrading {
|
||||
*
|
||||
* @return This Builder, for chaining calls
|
||||
*/
|
||||
Builder shadowsMidtonesHighlights(
|
||||
public Builder shadowsMidtonesHighlights(
|
||||
@NonNull @Size(min = 4) float[] shadows,
|
||||
@NonNull @Size(min = 4) float[] midtones,
|
||||
@NonNull @Size(min = 4) float[] highlights,
|
||||
@@ -309,7 +310,7 @@ public class ColorGrading {
|
||||
*
|
||||
* @return This Builder, for chaining calls
|
||||
*/
|
||||
Builder slopeOffsetPower(
|
||||
public Builder slopeOffsetPower(
|
||||
@NonNull @Size(min = 3) float[] slope,
|
||||
@NonNull @Size(min = 3) float[] offset,
|
||||
@NonNull @Size(min = 3) float[] power) {
|
||||
@@ -360,7 +361,7 @@ public class ColorGrading {
|
||||
*
|
||||
* @return This Builder, for chaining calls
|
||||
*/
|
||||
Builder vibrance(float vibrance) {
|
||||
public Builder vibrance(float vibrance) {
|
||||
nBuilderVibrance(mNativeBuilder, vibrance);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -568,7 +557,7 @@ public class Engine {
|
||||
* Destroys a {@link ColorGrading} and frees all its associated resources.
|
||||
* @param colorGrading the {@link ColorGrading} to destroy
|
||||
*/
|
||||
public void destroySkybox(@NonNull ColorGrading colorGrading) {
|
||||
public void destroyColorGrading(@NonNull ColorGrading colorGrading) {
|
||||
assertDestroy(nDestroyColorGrading(getNativeObject(), colorGrading.getNativeObject()));
|
||||
colorGrading.clearNativeObject();
|
||||
}
|
||||
@@ -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
|
||||
@@ -654,13 +651,21 @@ public class Engine {
|
||||
return mNativeObject;
|
||||
}
|
||||
|
||||
@UsedByReflection("MaterialBuilder.java")
|
||||
public long getNativeJobSystem() {
|
||||
if (mNativeObject == 0) {
|
||||
throw new IllegalStateException("Calling method on destroyed Engine");
|
||||
}
|
||||
return nGetJobSystem(getNativeObject());
|
||||
}
|
||||
|
||||
private void clearNativeObject() {
|
||||
mNativeObject = 0;
|
||||
}
|
||||
|
||||
private static void assertDestroy(boolean success) {
|
||||
if (!success) {
|
||||
throw new IllegalStateException("Object couldn't be destoyed (double destroy()?)");
|
||||
throw new IllegalStateException("Object couldn't be destroyed (double destroy()?)");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -675,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);
|
||||
@@ -698,4 +702,6 @@ public class Engine {
|
||||
private static native long nGetTransformManager(long nativeEngine);
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -233,7 +233,8 @@ public class Material {
|
||||
SAMPLER_2D_ARRAY,
|
||||
SAMPLER_CUBEMAP,
|
||||
SAMPLER_EXTERNAL,
|
||||
SAMPLER_3D
|
||||
SAMPLER_3D,
|
||||
SUBPASS_INPUT
|
||||
}
|
||||
|
||||
public enum Precision {
|
||||
@@ -247,6 +248,10 @@ public class Material {
|
||||
@UsedByNative("Material.cpp")
|
||||
private static final int SAMPLER_OFFSET = Type.MAT4.ordinal() + 1;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@UsedByNative("Material.cpp")
|
||||
private static final int SUBPASS_OFFSET = Type.SAMPLER_3D.ordinal() + 1;
|
||||
|
||||
@NonNull
|
||||
public final String name;
|
||||
@NonNull
|
||||
@@ -755,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:
|
||||
@@ -763,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()
|
||||
@@ -784,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:
|
||||
@@ -792,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()
|
||||
@@ -813,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:
|
||||
@@ -821,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
|
||||
)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
|
||||
android {
|
||||
flavorDimensions "functionality"
|
||||
@@ -46,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
|
||||
|
||||
@@ -34,3 +34,10 @@ Java_com_google_android_filament_gltfio_MaterialProvider_nDestroyMaterialProvide
|
||||
auto provider = (MaterialProvider*) nativeProvider;
|
||||
delete provider;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_MaterialProvider_nDestroyMaterials(JNIEnv*, jclass,
|
||||
jlong nativeProvider) {
|
||||
auto provider = (MaterialProvider*) nativeProvider;
|
||||
provider->destroyMaterials();
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -78,9 +78,10 @@ import java.nio.Buffer;
|
||||
public class AssetLoader {
|
||||
private long mNativeObject;
|
||||
private Engine mEngine;
|
||||
private MaterialProvider mMaterialCache;
|
||||
|
||||
/**
|
||||
* Constructs an <code>AssetLoader </code>that can be used to create and destroy instances of
|
||||
* Constructs an <code>AssetLoader</code> that can be used to create and destroy instances of
|
||||
* {@link FilamentAsset}.
|
||||
*
|
||||
* @param engine the engine that the loader should pass to builder objects
|
||||
@@ -100,6 +101,7 @@ public class AssetLoader {
|
||||
}
|
||||
|
||||
mEngine = engine;
|
||||
mMaterialCache = generator;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,6 +109,7 @@ public class AssetLoader {
|
||||
*/
|
||||
public void destroy() {
|
||||
nDestroyAssetLoader(mNativeObject);
|
||||
mMaterialCache.destroyMaterials();
|
||||
mNativeObject = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,10 +47,21 @@ public class MaterialProvider {
|
||||
mNativeObject = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys all cached materials.
|
||||
*
|
||||
* This is not called automatically when MaterialProvider is destroyed, which allows
|
||||
* clients to take ownership of the cache if desired.
|
||||
*/
|
||||
public void destroyMaterials() {
|
||||
nDestroyMaterials(mNativeObject);
|
||||
}
|
||||
|
||||
long getNativeObject() {
|
||||
return mNativeObject;
|
||||
}
|
||||
|
||||
private static native long nCreateMaterialProvider(long nativeEngine);
|
||||
private static native void nDestroyMaterialProvider(long nativeProvider);
|
||||
private static native void nDestroyMaterials(long nativeProvider);
|
||||
}
|
||||
|
||||
@@ -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.10
|
||||
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
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
apply plugin: FilamentToolsPlugin
|
||||
|
||||
project.ext.isSample = true
|
||||
@@ -37,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>
|
||||
@@ -1,6 +1,5 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
apply plugin: FilamentToolsPlugin
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
apply plugin: FilamentToolsPlugin
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
apply plugin: FilamentToolsPlugin
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
apply plugin: FilamentToolsPlugin
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
|
||||
@@ -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() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
apply plugin: FilamentToolsPlugin
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
@@ -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() {
|
||||
@@ -216,7 +216,9 @@ class MainActivity : Activity() {
|
||||
// variant of the filamat library.
|
||||
.optimization(MaterialBuilder.Optimization.NONE)
|
||||
|
||||
.build()
|
||||
// When compiling more than one material variant, it is more efficient to pass an Engine
|
||||
// instance to reuse the Engine's job system
|
||||
.build(engine)
|
||||
|
||||
if (matPackage.isValid) {
|
||||
val buffer = matPackage.buffer
|
||||
@@ -287,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
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
apply plugin: FilamentToolsPlugin
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
apply plugin: FilamentToolsPlugin
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
apply plugin: FilamentToolsPlugin
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
apply plugin: FilamentToolsPlugin
|
||||
|
||||
project.ext.isSample = true
|
||||
@@ -40,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
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
apply plugin: FilamentToolsPlugin
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user