Compare commits
750 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
82793f9b82 | ||
|
|
597218963f | ||
|
|
0d29b3ddc8 | ||
|
|
e0e3b42623 | ||
|
|
0995ca6614 | ||
|
|
3d741fc8d4 | ||
|
|
47e30c337e | ||
|
|
fb627d8b66 | ||
|
|
1cb59685c5 | ||
|
|
2b395f1d89 | ||
|
|
e9718fa346 | ||
|
|
81fc2c1d23 | ||
|
|
c20772b458 | ||
|
|
dc60f57a9a | ||
|
|
5c4f12fa00 | ||
|
|
00ffd9ca74 | ||
|
|
166f859c72 | ||
|
|
1969186fe1 | ||
|
|
e1e7854d97 | ||
|
|
9d5220e28e | ||
|
|
fc0b41d587 | ||
|
|
4a6b659098 | ||
|
|
2b93f08ca5 | ||
|
|
e4cb861817 | ||
|
|
fca62b8fff | ||
|
|
640f080ea6 | ||
|
|
eed4b3b839 | ||
|
|
f48dafe87e | ||
|
|
daff8fea9f | ||
|
|
51b4a38e20 | ||
|
|
2171e372ce | ||
|
|
1a30709121 | ||
|
|
2ed9b11f50 | ||
|
|
dee6d9de2c | ||
|
|
574e3e7521 | ||
|
|
1797ff5d90 | ||
|
|
8c46e6de9b | ||
|
|
613adfa342 | ||
|
|
684b0622eb | ||
|
|
426f345f19 | ||
|
|
f80df6e061 | ||
|
|
29fdf82ac5 | ||
|
|
e2177e8b36 | ||
|
|
c8cf2a54e8 | ||
|
|
bfd32e67d4 | ||
|
|
37353cca55 | ||
|
|
c72817fc25 | ||
|
|
81c1d3ed1a | ||
|
|
0e1234c57d | ||
|
|
50fa816a6e | ||
|
|
07f4211dd3 | ||
|
|
44a433398f | ||
|
|
6821cb60b5 | ||
|
|
b8788bc390 | ||
|
|
94c59d9d97 | ||
|
|
5201b5a1ba | ||
|
|
215ef460ef | ||
|
|
90be8ebfa2 | ||
|
|
f62d58bd45 | ||
|
|
9e5da2d75f | ||
|
|
e12f079ac1 | ||
|
|
3c0f18753f | ||
|
|
a0e4d3df32 | ||
|
|
4f590e3326 | ||
|
|
6fdfe606e6 | ||
|
|
1baab6c3ae | ||
|
|
61e67a2766 | ||
|
|
8277015785 | ||
|
|
97952e0ddc | ||
|
|
95915367fa | ||
|
|
b769cfda62 | ||
|
|
b80d73f3cf | ||
|
|
40ac88dfed | ||
|
|
6d96082f07 | ||
|
|
21f913db1c | ||
|
|
a1bf6a427d | ||
|
|
67144bec73 | ||
|
|
699a578966 | ||
|
|
f801763e6b | ||
|
|
542dd331d7 | ||
|
|
4ac3454dc6 | ||
|
|
23b578ef89 | ||
|
|
b6c26ab4e4 | ||
|
|
4fbcfc3168 | ||
|
|
9d0aab4d21 | ||
|
|
babbfa1394 | ||
|
|
73f0d58e10 | ||
|
|
6420bc6dd8 | ||
|
|
9fa41d06d6 | ||
|
|
805227d6fc | ||
|
|
67d4632868 | ||
|
|
7efe967add | ||
|
|
a8cdfc6b23 | ||
|
|
7964ebf3c5 | ||
|
|
49b8e5e5d2 | ||
|
|
54e6b6b24a | ||
|
|
0fe6cfb224 | ||
|
|
0ee540df9c | ||
|
|
249f0a80d8 | ||
|
|
9cb4b74bbd | ||
|
|
b3368a3fb2 | ||
|
|
327576274f | ||
|
|
0e7004a7f8 | ||
|
|
ca8549549c | ||
|
|
fa6d9a4b01 | ||
|
|
3693e4909b | ||
|
|
697a8370cb | ||
|
|
155a362d60 | ||
|
|
fed95d70b0 | ||
|
|
cd126138e0 | ||
|
|
7e7398aa92 | ||
|
|
ede7c579f9 | ||
|
|
67aa6f1913 | ||
|
|
80eba1de10 | ||
|
|
5e05a23e94 | ||
|
|
8c8061a637 | ||
|
|
9ef3c59698 | ||
|
|
5f7c6c2fbf | ||
|
|
991360da97 | ||
|
|
50d9fb2b5b | ||
|
|
001a3e3dc8 | ||
|
|
b6eca61786 | ||
|
|
cc75eb3aa2 | ||
|
|
f5fda88cf6 | ||
|
|
e99f13b14d | ||
|
|
08e809bf75 | ||
|
|
1d6aeb5de1 | ||
|
|
d13ccd1c26 | ||
|
|
f2c8456971 | ||
|
|
54482e6451 | ||
|
|
9491b36a25 | ||
|
|
d387e14d4c | ||
|
|
5c41b332ad | ||
|
|
e571600c30 | ||
|
|
e84c94d3eb | ||
|
|
fd69c7ed75 | ||
|
|
e791d4818f | ||
|
|
3ff8d6dc22 | ||
|
|
af6fd21e11 | ||
|
|
5bd5c50c8d | ||
|
|
2c8d296044 | ||
|
|
df6a100fcb | ||
|
|
3f6188edff | ||
|
|
cc0486b3cc | ||
|
|
8314bafc0e | ||
|
|
764c695e4e | ||
|
|
808ca42992 | ||
|
|
4a8428318b | ||
|
|
c93059783b | ||
|
|
d21f092645 | ||
|
|
9844803b26 | ||
|
|
cdadb43e50 | ||
|
|
2e0ace5026 | ||
|
|
edaff60fbf | ||
|
|
b8725ffa22 | ||
|
|
d2da478923 | ||
|
|
0b3e557b65 | ||
|
|
0d2faa4573 | ||
|
|
1924810c17 | ||
|
|
6ab45a4cf0 | ||
|
|
3f64e46557 | ||
|
|
32dab23bc6 | ||
|
|
362de7dd31 | ||
|
|
5e2c94c31a | ||
|
|
6b01fbb903 | ||
|
|
4934d9f7bc | ||
|
|
c1a99921b0 | ||
|
|
4a0dbbce12 | ||
|
|
7398183d6f | ||
|
|
ed73955b00 | ||
|
|
3f1f2726c4 | ||
|
|
edf405c8fd | ||
|
|
4cc8f88a21 | ||
|
|
5dba7fdae0 | ||
|
|
e2b8573bd7 | ||
|
|
6eeb4c9d3a | ||
|
|
996981b102 | ||
|
|
4f4330c95e | ||
|
|
e48f54a863 | ||
|
|
1a7bd7ea8d | ||
|
|
2aa8ea4687 | ||
|
|
cde055e5bf | ||
|
|
19729db982 | ||
|
|
2029c9584e | ||
|
|
d9cbe60ca6 | ||
|
|
04337fdb68 | ||
|
|
a43b17716f | ||
|
|
63032ed0a6 | ||
|
|
946ea43436 | ||
|
|
b6cd6668a6 | ||
|
|
dee41e6120 | ||
|
|
7b03cb9b76 | ||
|
|
8aa83d4886 | ||
|
|
c17b3756ea | ||
|
|
7f42385f5f | ||
|
|
8845ac2b75 | ||
|
|
73e339b05d | ||
|
|
42172c7395 | ||
|
|
fbc0b8dab5 | ||
|
|
91b45d2890 | ||
|
|
9df13c1cd2 | ||
|
|
5a3853a442 | ||
|
|
70e14a1757 | ||
|
|
4c4a93d9b5 | ||
|
|
da85001d4d | ||
|
|
001dcefd8a | ||
|
|
d114d547be | ||
|
|
8d15079937 | ||
|
|
adc542b5cd | ||
|
|
72feb044a3 | ||
|
|
c0ba260ddf | ||
|
|
2da215e8e7 | ||
|
|
4d0368b5f1 | ||
|
|
d11c78857d | ||
|
|
e829d90c4a | ||
|
|
a8006acd33 | ||
|
|
6403e0ce44 | ||
|
|
41cf507746 | ||
|
|
c49fcf9018 | ||
|
|
354c39be6b | ||
|
|
26bbe8ade1 | ||
|
|
1952f0a1f7 | ||
|
|
61fdc0d375 | ||
|
|
4060b558c7 | ||
|
|
a783df39ba | ||
|
|
a9ccaf2ffb | ||
|
|
f40b08d826 | ||
|
|
9fd0397d45 | ||
|
|
69fb7170a7 | ||
|
|
b69546c229 | ||
|
|
45054eece9 | ||
|
|
785f7de25d | ||
|
|
509fb4ad23 | ||
|
|
6577519bd7 | ||
|
|
43948421d7 | ||
|
|
328650df17 | ||
|
|
86ec502040 | ||
|
|
b19a73cc50 | ||
|
|
b657ccd75a | ||
|
|
a99c695932 | ||
|
|
11cbb3d395 | ||
|
|
c21d7c3f5e | ||
|
|
975665c9c9 | ||
|
|
613e1052c7 | ||
|
|
ba9e7fa17f | ||
|
|
fa54bdd682 | ||
|
|
1678d02c87 | ||
|
|
5e535165a6 | ||
|
|
3de427b74f | ||
|
|
15899af7cf | ||
|
|
443181c719 | ||
|
|
02f96e2a1e | ||
|
|
67e0aa5488 | ||
|
|
c969005bcc | ||
|
|
5417d0953b | ||
|
|
ddb4865ceb | ||
|
|
7b5cac6d4f | ||
|
|
fb76f8ed80 | ||
|
|
4b572cf065 | ||
|
|
3e3fc76688 | ||
|
|
700b4d5d38 | ||
|
|
9e29d042b9 | ||
|
|
13f3ebca89 | ||
|
|
3e30632b8c | ||
|
|
8cd720b53a | ||
|
|
04df79e58f | ||
|
|
a8d72bb226 | ||
|
|
a4b3717762 | ||
|
|
bf3f7e0aef | ||
|
|
0fb04c576d | ||
|
|
caaa404d96 | ||
|
|
2fa6e6d031 | ||
|
|
62bb25b26d | ||
|
|
8d1402d37b | ||
|
|
afd657d6af | ||
|
|
27a5158147 | ||
|
|
dead7ab2ac | ||
|
|
352acff396 | ||
|
|
00d9c6921d | ||
|
|
6805940bbf | ||
|
|
954f9112e4 | ||
|
|
6465b9ade8 | ||
|
|
b67963176b | ||
|
|
fb1eb35ba5 | ||
|
|
047543a4a6 | ||
|
|
5e0615040d | ||
|
|
1ceed1519b | ||
|
|
1035e442ee | ||
|
|
60d3638f15 | ||
|
|
a1a3adf8af | ||
|
|
3e7d3c9035 | ||
|
|
eb360be2ad | ||
|
|
620a693c11 | ||
|
|
4511af6f9e | ||
|
|
214e54f2ad | ||
|
|
2eefbe11ae | ||
|
|
74ea3d50c2 | ||
|
|
9a8159ab04 | ||
|
|
2f3aac29da | ||
|
|
9d7f5f593e | ||
|
|
2596273a94 | ||
|
|
210a8c2260 | ||
|
|
485ac8704d | ||
|
|
dc74540423 | ||
|
|
eaefaf8e59 | ||
|
|
96219c22db | ||
|
|
f3b7048775 | ||
|
|
aaed6fb376 | ||
|
|
7873e6f5aa | ||
|
|
251abf0545 | ||
|
|
b5c4b30ff6 | ||
|
|
eb941a0868 | ||
|
|
304ffe0049 | ||
|
|
88edbc7df8 | ||
|
|
6fa82ea73d | ||
|
|
92e7ff3de7 | ||
|
|
35a5d3310f | ||
|
|
2739eb146a | ||
|
|
59ccc3021f | ||
|
|
36e9fa42f4 | ||
|
|
9da79a1d2d | ||
|
|
595b355d1b | ||
|
|
8111c50a5a | ||
|
|
0e5e7e940c | ||
|
|
9f75d34bb8 | ||
|
|
df42213daf | ||
|
|
b73caceb1f | ||
|
|
c91f28b6be | ||
|
|
078de4e422 | ||
|
|
332d5681e6 | ||
|
|
3a67d769f4 | ||
|
|
de1281dd9f | ||
|
|
f3849a1f57 | ||
|
|
3fd63b1b3d | ||
|
|
6fb536a937 | ||
|
|
bb460d78d8 | ||
|
|
3a33220dad | ||
|
|
09a9deafc0 | ||
|
|
4de3470de5 | ||
|
|
f03d654862 | ||
|
|
b8a39c2f3d | ||
|
|
291b5dcec5 | ||
|
|
087f29c6c9 | ||
|
|
aac3ac579c | ||
|
|
838835a715 | ||
|
|
c275f61aeb | ||
|
|
f297948216 | ||
|
|
dbe1386785 | ||
|
|
687f4aff13 | ||
|
|
dd4853bcc5 | ||
|
|
ffbfc13530 | ||
|
|
2aa160a98c | ||
|
|
477a3a8771 | ||
|
|
63acd53e23 | ||
|
|
fcd2d0457b | ||
|
|
c0e8686297 | ||
|
|
01f18caf53 | ||
|
|
56971520a2 | ||
|
|
f5e38b1198 | ||
|
|
984ef2a089 | ||
|
|
ad960c73b6 | ||
|
|
0dcc631aa8 | ||
|
|
af9b670cfd | ||
|
|
58fc26461b | ||
|
|
fd82f6b04e | ||
|
|
519ae4d143 | ||
|
|
8d72869437 | ||
|
|
2cbacb532a | ||
|
|
1da2bf2f7a | ||
|
|
cef3200533 | ||
|
|
634500c398 | ||
|
|
802bc7a5dc | ||
|
|
8875806c5d | ||
|
|
c9df807f1f | ||
|
|
b3e294ac54 | ||
|
|
3feef4e84b | ||
|
|
2bf7535ad0 | ||
|
|
3315f75de9 | ||
|
|
bbe7dbfa92 | ||
|
|
15001524bd | ||
|
|
c1713e7501 | ||
|
|
0181584735 | ||
|
|
df06e8dc41 | ||
|
|
5697922a65 | ||
|
|
4da83df2b9 | ||
|
|
8f156d6588 | ||
|
|
b0ce077ace | ||
|
|
9d29d2e32c | ||
|
|
a29b438161 | ||
|
|
50a042bb16 | ||
|
|
cec0871c11 | ||
|
|
41a809368b | ||
|
|
f690015a88 | ||
|
|
342deb5a64 | ||
|
|
fdc480ff6e | ||
|
|
378b7cd4dd | ||
|
|
f779fc7a0e | ||
|
|
fe11f495d6 | ||
|
|
265876c849 | ||
|
|
c9c52518c0 | ||
|
|
96c9ac6f8b | ||
|
|
bdeb30a847 | ||
|
|
ea53eb9290 | ||
|
|
05875057c9 | ||
|
|
d67210155b | ||
|
|
ae92c50cee | ||
|
|
43429dc0ec | ||
|
|
04cf92a27f | ||
|
|
57a57f50f6 | ||
|
|
5e5a75e6c5 | ||
|
|
109c86aaf7 | ||
|
|
10e7e7727a | ||
|
|
a39775050a | ||
|
|
44125926d1 | ||
|
|
60734349de | ||
|
|
fbfd5ec0ec | ||
|
|
157c0264af | ||
|
|
9bacfdb390 | ||
|
|
f9aaf5c42e | ||
|
|
a74a95cc65 | ||
|
|
21db695e79 | ||
|
|
cf917f1093 | ||
|
|
a8d3a61c25 | ||
|
|
80f13a8149 | ||
|
|
e172f3a67f | ||
|
|
c382c0a9cc | ||
|
|
bc0ea16ff0 | ||
|
|
b2dc8aa84c | ||
|
|
78b29fe967 | ||
|
|
9987e8b6ab | ||
|
|
0d9bdcc008 | ||
|
|
81fa33abeb | ||
|
|
af7f87e19b | ||
|
|
3073b03d56 | ||
|
|
23dab0a013 | ||
|
|
fd68144ba2 | ||
|
|
51e92cd142 | ||
|
|
50f33f7196 | ||
|
|
b5c634045e | ||
|
|
1f05531d53 | ||
|
|
88f382f0e3 | ||
|
|
3e59925900 | ||
|
|
1182d30fb9 | ||
|
|
095179eeb3 | ||
|
|
69b48eaadb | ||
|
|
4031c6f0d3 | ||
|
|
7a22f7dfc5 | ||
|
|
728ebf5023 | ||
|
|
62476d2f06 | ||
|
|
ea404f8d4f | ||
|
|
602a550d93 | ||
|
|
12abbe2d23 | ||
|
|
5fea428243 | ||
|
|
fb0ee97588 | ||
|
|
56ef48c9c3 | ||
|
|
47c3dd3dd1 | ||
|
|
9a3c9ccbf3 | ||
|
|
ef4dfcecd6 | ||
|
|
5943382d23 | ||
|
|
c181648bfa | ||
|
|
0cf78b3abe | ||
|
|
1dcf347b87 | ||
|
|
47714007f7 | ||
|
|
22889a7ad9 | ||
|
|
a14451d0ac | ||
|
|
5dfdab10b7 | ||
|
|
54277572d2 | ||
|
|
52f2c0e107 | ||
|
|
59abc8cc20 | ||
|
|
e15796b348 | ||
|
|
1711eaa4d6 | ||
|
|
acbd6a5ca8 | ||
|
|
775090fdda | ||
|
|
0915b86927 | ||
|
|
c10f7b01f4 | ||
|
|
84142ac506 | ||
|
|
ff190847a1 | ||
|
|
3ceec28189 | ||
|
|
d6f2e3b8e9 | ||
|
|
481038152f | ||
|
|
60bd72730d | ||
|
|
df30517743 | ||
|
|
8f80643c1a | ||
|
|
eabfd08473 | ||
|
|
a66af0ac58 | ||
|
|
15187e9d99 | ||
|
|
681e8f8b59 | ||
|
|
fbb406ca7d | ||
|
|
5aea9be2fb | ||
|
|
aacaf5055e | ||
|
|
a5dbddfd12 | ||
|
|
764a0df669 | ||
|
|
f04864c216 | ||
|
|
11a1b31a4c | ||
|
|
fb86a77cf8 | ||
|
|
d512357928 | ||
|
|
b850bc827e | ||
|
|
0229077293 | ||
|
|
23f2679bbe | ||
|
|
e6243b3df3 | ||
|
|
375b46d866 | ||
|
|
4577c8d57f | ||
|
|
24d1e9c3d2 | ||
|
|
f7a630d614 | ||
|
|
1c1cb11cf5 | ||
|
|
3ac8a6a21c | ||
|
|
c524c39867 | ||
|
|
ad02e483d0 | ||
|
|
f463d53036 | ||
|
|
e203edc12a | ||
|
|
b8d4408524 | ||
|
|
5447baab00 | ||
|
|
904989f7f4 | ||
|
|
4846ccd86d | ||
|
|
0fd1c3182e | ||
|
|
7d80052dae | ||
|
|
b71ee48477 | ||
|
|
7a285dc55a | ||
|
|
a0f3a4d9bb | ||
|
|
304090d39f | ||
|
|
fef70be848 | ||
|
|
bdb12d9b24 | ||
|
|
510f51d934 | ||
|
|
47c9fd67e2 | ||
|
|
43ad283a83 | ||
|
|
1f403fdae0 | ||
|
|
2e4936afc4 | ||
|
|
891ffabd11 | ||
|
|
e2c19498b4 | ||
|
|
c32630b265 | ||
|
|
1a3cee9da9 | ||
|
|
3acfd6fc78 | ||
|
|
bf21e78d02 | ||
|
|
83a9bb3a6f | ||
|
|
0744876327 | ||
|
|
8b92519113 | ||
|
|
525d4e08a3 | ||
|
|
2e9bf6d694 | ||
|
|
1980107925 | ||
|
|
e845f01d85 | ||
|
|
409a84be1f | ||
|
|
b2fef7988e | ||
|
|
82623c8fd4 | ||
|
|
552a3ab103 | ||
|
|
52c376a8a7 | ||
|
|
dd3b7ca65c | ||
|
|
9776a38d48 | ||
|
|
ceeccde92c | ||
|
|
1a8550e8e0 | ||
|
|
2feb0ad325 | ||
|
|
7f2c9c2326 | ||
|
|
9e5f4be85d | ||
|
|
b5874af40b | ||
|
|
bef48be7b4 | ||
|
|
b54fdc9e6e | ||
|
|
cc70b827a8 | ||
|
|
cedbf2e30b | ||
|
|
9ff195ce19 | ||
|
|
8e7aaaa662 | ||
|
|
77a744b20b | ||
|
|
51fd1ef645 | ||
|
|
592f8d1b0d | ||
|
|
29612a684e | ||
|
|
3500cc693d | ||
|
|
807b9882c5 | ||
|
|
b2920a68fb | ||
|
|
f4ef283908 | ||
|
|
09a38f4e43 | ||
|
|
04acd1885a | ||
|
|
d9fde833b4 | ||
|
|
378ba4e1df | ||
|
|
4522ce342b | ||
|
|
04402ed412 | ||
|
|
dc3cf5df49 | ||
|
|
9261769c5a | ||
|
|
f5e74f8d5a | ||
|
|
e87c140255 | ||
|
|
00d36110d5 | ||
|
|
c11364b89f | ||
|
|
89f8b8663c | ||
|
|
6734cdd923 | ||
|
|
3bf4ff78d9 | ||
|
|
b52cef2fd0 | ||
|
|
66747e69c5 | ||
|
|
4085336db5 | ||
|
|
c666a79d12 | ||
|
|
22a464f76f | ||
|
|
60e88a6069 | ||
|
|
ff3a9a46cc | ||
|
|
8c53ad0906 | ||
|
|
93cc32f34d | ||
|
|
dd764d2c3f | ||
|
|
5a7ae8f1c7 | ||
|
|
4ed5085422 | ||
|
|
0e574f3fce | ||
|
|
dcfc27857f | ||
|
|
e6d5807399 | ||
|
|
fa2553251f | ||
|
|
b04c398202 | ||
|
|
fe8e1d0734 | ||
|
|
7387718852 | ||
|
|
a503a6209a | ||
|
|
9f5d6e79da | ||
|
|
ce3e5f74e8 | ||
|
|
9b06ab6084 | ||
|
|
f37112358e | ||
|
|
76d4fc08f1 | ||
|
|
90548a148b | ||
|
|
270bbe4218 | ||
|
|
3f26c8b893 | ||
|
|
f368b14621 | ||
|
|
6960b1148a | ||
|
|
9cea332f61 | ||
|
|
93ce14659a | ||
|
|
2d49b36b3e | ||
|
|
3cc23aac25 | ||
|
|
ab9d132964 | ||
|
|
11dc8740f2 | ||
|
|
b30e4f9a4b | ||
|
|
4b797cff88 | ||
|
|
22afc3a93b | ||
|
|
8aba6f0dcd | ||
|
|
97cee30383 | ||
|
|
7f4832706b | ||
|
|
5f16fe45b1 | ||
|
|
8c8e0ce8a3 | ||
|
|
1b9dea5b75 | ||
|
|
7ed073ec3f | ||
|
|
e2c5bb025b | ||
|
|
a86077e9fe | ||
|
|
cd903b412f | ||
|
|
dd914066f3 | ||
|
|
7af07a1c0f | ||
|
|
b980d0a7fd | ||
|
|
5f10ab56bc | ||
|
|
383da5f661 | ||
|
|
8f0591c9a6 | ||
|
|
afb0ceac57 | ||
|
|
fc2660eb39 | ||
|
|
1b8f4b97dd | ||
|
|
3671469046 | ||
|
|
53d4fa3095 | ||
|
|
94999e55e1 | ||
|
|
ba9415b514 | ||
|
|
fe1c1736cd | ||
|
|
abb6ae304c | ||
|
|
885a69710e | ||
|
|
4058ef5f09 | ||
|
|
d25ca01624 | ||
|
|
e7bebcdea9 | ||
|
|
5ef234153d | ||
|
|
d96f87dbbf | ||
|
|
bbee5599f1 | ||
|
|
a4212d5ace | ||
|
|
6d0e719e06 | ||
|
|
3fa9b08a52 | ||
|
|
4b1a451804 | ||
|
|
f9d7d60f7d | ||
|
|
aaf9d95411 | ||
|
|
90d1ebefae | ||
|
|
a7e4a759e9 | ||
|
|
283992088f | ||
|
|
75c9ee5982 | ||
|
|
4d88ff116c | ||
|
|
cf3cc37392 | ||
|
|
f804c9e346 | ||
|
|
8a2e31023f | ||
|
|
4e33e9c3d1 | ||
|
|
18ac9fd0cc | ||
|
|
d0f28a48a8 | ||
|
|
706780e3a6 | ||
|
|
b5f9c66503 | ||
|
|
41f34b8d55 | ||
|
|
04731b937a | ||
|
|
7278e5b5ba | ||
|
|
891184bc77 | ||
|
|
3d51f9ab23 | ||
|
|
1ea8e171d9 | ||
|
|
e2be3dd0ac | ||
|
|
35c0092b84 | ||
|
|
d249f70750 | ||
|
|
0dc25cd2a8 | ||
|
|
1c51164e7b | ||
|
|
91b5cc4bea | ||
|
|
f190f03530 | ||
|
|
af6f19e390 | ||
|
|
47446e6cfd | ||
|
|
8fada7d6c7 | ||
|
|
8a81486f5d | ||
|
|
e483699fba | ||
|
|
ae40a12f54 | ||
|
|
73d4279f00 | ||
|
|
a0e2f722f6 | ||
|
|
5c0da86e04 | ||
|
|
055fc7cbc1 | ||
|
|
37d8f96927 | ||
|
|
e9e3ce78ca | ||
|
|
2dadad1e87 | ||
|
|
8c36e6d95f | ||
|
|
2b6d99f5e7 | ||
|
|
6f29358cb6 | ||
|
|
4e9dcb45ea | ||
|
|
282b6f72c1 | ||
|
|
cd48be5265 | ||
|
|
3cba26a4c5 | ||
|
|
dd2119268b | ||
|
|
5e51ff78d9 | ||
|
|
6bf27c7356 | ||
|
|
3abd4fdf09 | ||
|
|
2409dc9bc4 | ||
|
|
432434e7e9 | ||
|
|
6586c8d70b | ||
|
|
ba68ea89cd | ||
|
|
26661375ae | ||
|
|
f45b7626eb | ||
|
|
2aa21e2a43 | ||
|
|
ad876b91e7 | ||
|
|
73514f6c91 | ||
|
|
385a05d197 | ||
|
|
306f6e1ca3 | ||
|
|
41baa7bcf0 | ||
|
|
694204d54a | ||
|
|
85bc1c1758 | ||
|
|
0c9cb72e53 | ||
|
|
d113c0f01f | ||
|
|
98b8871f34 | ||
|
|
7cb16afcb5 | ||
|
|
1a79e5463f | ||
|
|
fd444b2fd0 | ||
|
|
15db005dc6 | ||
|
|
a26b05bbbb | ||
|
|
12b9ee46b9 | ||
|
|
ce1eb83a0e | ||
|
|
27529730ca | ||
|
|
7b398c01f6 | ||
|
|
cdb0bb9490 | ||
|
|
ee82f76846 | ||
|
|
b77a23ff9d | ||
|
|
0d8cdab4e4 | ||
|
|
67b53d0115 | ||
|
|
c3291d0137 | ||
|
|
7f2ebd25bc | ||
|
|
fc32fa3a78 | ||
|
|
a3cf2ee61a | ||
|
|
cc287386aa | ||
|
|
9ea1dbad93 | ||
|
|
4a849c7caf | ||
|
|
a77a9ade29 | ||
|
|
090d23434c | ||
|
|
83850c8201 |
3
.github/workflows/mac-continuous.yml
vendored
3
.github/workflows/mac-continuous.yml
vendored
@@ -21,3 +21,6 @@ jobs:
|
||||
with:
|
||||
name: filament-mac
|
||||
path: out/filament-release-darwin.tgz
|
||||
- name: Check public headers
|
||||
run: |
|
||||
build/common/check-headers.sh out/release/filament/include
|
||||
|
||||
2
.github/workflows/presubmit.yml
vendored
2
.github/workflows/presubmit.yml
vendored
@@ -29,7 +29,7 @@ jobs:
|
||||
|
||||
build-windows:
|
||||
name: build-windows
|
||||
runs-on: windows-latest
|
||||
runs-on: windows-2019
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2.0.0
|
||||
|
||||
31
.github/workflows/release.yml
vendored
31
.github/workflows/release.yml
vendored
@@ -1,14 +1,25 @@
|
||||
name: Release
|
||||
|
||||
# This Workflow can be triggered two ways:
|
||||
# 1. A GitHub release is created (using the GitHub web UI). This triggers all of the platforms to build and upload assets.
|
||||
# 2. A repository_dispatch API event is sent. This triggers a build for only the platform specified in the dispatch event.
|
||||
# 1. A GitHub release is created (using the GitHub web UI). This triggers all of the platforms to
|
||||
# build and upload assets.
|
||||
# 2. A workflow_dispatch event is triggered from the GitHub web UI. This triggers a build for only
|
||||
# the platform specified in the dispatch event.
|
||||
|
||||
env:
|
||||
RELEASE_TAG: ${{ github.event.client_payload.release_tag }}
|
||||
RELEASE_TAG: ${{ github.event.inputs.release_tag }}
|
||||
|
||||
on:
|
||||
repository_dispatch:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
platform:
|
||||
description: 'Platform to build (desktop, web, android, ios, windows)'
|
||||
required: true
|
||||
default: 'desktop'
|
||||
release_tag:
|
||||
description: 'Release tag to build (e.g., v1.13.0)'
|
||||
required: true
|
||||
default: 'v1.13.0'
|
||||
release:
|
||||
types: [created]
|
||||
|
||||
@@ -16,7 +27,7 @@ jobs:
|
||||
build-desktop:
|
||||
name: build-desktop
|
||||
runs-on: ${{ matrix.os }}
|
||||
if: github.event_name == 'release' || github.event.client_payload.platform == 'desktop'
|
||||
if: github.event_name == 'release' || github.event.inputs.platform == 'desktop'
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
@@ -51,7 +62,7 @@ jobs:
|
||||
build-web:
|
||||
name: build-web
|
||||
runs-on: macos-latest
|
||||
if: github.event_name == 'release' || github.event.client_payload.platform == 'web'
|
||||
if: github.event_name == 'release' || github.event.inputs.platform == 'web'
|
||||
|
||||
steps:
|
||||
- name: Decide Git ref
|
||||
@@ -80,7 +91,7 @@ jobs:
|
||||
build-android:
|
||||
name: build-android
|
||||
runs-on: macos-latest
|
||||
if: github.event_name == 'release' || github.event.client_payload.platform == 'android'
|
||||
if: github.event_name == 'release' || github.event.inputs.platform == 'android'
|
||||
|
||||
steps:
|
||||
- name: Decide Git ref
|
||||
@@ -129,7 +140,7 @@ jobs:
|
||||
build-ios:
|
||||
name: build-ios
|
||||
runs-on: macos-latest
|
||||
if: github.event_name == 'release' || github.event.client_payload.platform == 'ios'
|
||||
if: github.event_name == 'release' || github.event.inputs.platform == 'ios'
|
||||
|
||||
steps:
|
||||
- name: Decide Git ref
|
||||
@@ -157,8 +168,8 @@ jobs:
|
||||
|
||||
build-windows:
|
||||
name: build-windows
|
||||
runs-on: windows-latest
|
||||
if: github.event_name == 'release' || github.event.client_payload.platform == 'windows'
|
||||
runs-on: windows-2019
|
||||
if: github.event_name == 'release' || github.event.inputs.platform == 'windows'
|
||||
|
||||
steps:
|
||||
- name: Decide Git ref
|
||||
|
||||
2
.github/workflows/windows-continuous.yml
vendored
2
.github/workflows/windows-continuous.yml
vendored
@@ -10,7 +10,7 @@ on:
|
||||
jobs:
|
||||
build-windows:
|
||||
name: build-windows
|
||||
runs-on: windows-latest
|
||||
runs-on: windows-2019
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2.0.0
|
||||
|
||||
12
BUILDING.md
12
BUILDING.md
@@ -13,9 +13,9 @@ section below.
|
||||
|
||||
To build Filament for Android you must also install the following:
|
||||
|
||||
- Android Studio 4.2.0 or more recent
|
||||
- Android Studio Arctic Fox or more recent
|
||||
- Android SDK
|
||||
- Android NDK "side-by-side" 22.1 or higher
|
||||
- Android NDK "side-by-side" 23.1 or higher
|
||||
|
||||
### Environment variables
|
||||
|
||||
@@ -291,11 +291,11 @@ Alternatively you can build the AAR from the command line by executing the follo
|
||||
`android/` directory:
|
||||
|
||||
```
|
||||
$ ./gradlew -Pfilament_dist_dir=../../out/android-release/filament assembleRelease
|
||||
$ ./gradlew -Pcom.google.android.filament.dist-dir=../../out/android-release/filament assembleRelease
|
||||
```
|
||||
|
||||
The `-Pfilament_dist_dir` can be used to specify a different installation directory (it must match
|
||||
the CMake install prefix used in the previous steps).
|
||||
The `-Pcom.google.android.filament.dist-dir` can be used to specify a different installation
|
||||
directory (it must match the CMake install prefix used in the previous steps).
|
||||
|
||||
#### Using Filament's AAR
|
||||
|
||||
@@ -349,7 +349,7 @@ same version that our continuous builds use.
|
||||
|
||||
```
|
||||
cd <your chosen parent folder for the emscripten SDK>
|
||||
curl -L https://github.com/emscripten-core/emsdk/archive/2.0.23.zip > emsdk.zip
|
||||
curl -L https://github.com/emscripten-core/emsdk/archive/refs/tags/3.1.5.zip > emsdk.zip
|
||||
unzip emsdk.zip ; mv emsdk-* emsdk ; cd emsdk
|
||||
python ./emsdk.py install latest
|
||||
python ./emsdk.py activate latest
|
||||
|
||||
100
CMakeLists.txt
100
CMakeLists.txt
@@ -23,6 +23,12 @@ option(FILAMENT_SUPPORTS_XCB "Include XCB support in Linux builds" ON)
|
||||
|
||||
option(FILAMENT_SUPPORTS_XLIB "Include XLIB support in Linux builds" ON)
|
||||
|
||||
option(FILAMENT_SUPPORTS_WAYLAND "Include Wayland support in Linux builds" OFF)
|
||||
|
||||
option(FILAMENT_SKIP_SDL2 "Skip dependencies of SDL2, and SDL2" OFF)
|
||||
|
||||
option(FILAMENT_LINUX_IS_MOBILE "Treat Linux as Mobile" OFF)
|
||||
|
||||
set(FILAMENT_NDK_VERSION "" CACHE STRING
|
||||
"Android NDK version or version prefix to be used when building for Android."
|
||||
)
|
||||
@@ -94,20 +100,34 @@ if (UNIX AND NOT APPLE AND NOT ANDROID AND NOT WEBGL)
|
||||
endif()
|
||||
|
||||
if (LINUX)
|
||||
if (FILAMENT_SUPPORTS_XCB)
|
||||
add_definitions(-DFILAMENT_SUPPORTS_XCB)
|
||||
endif()
|
||||
if (FILAMENT_SUPPORTS_WAYLAND)
|
||||
add_definitions(-DFILAMENT_SUPPORTS_WAYLAND)
|
||||
set(FILAMENT_SUPPORTS_X11 FALSE)
|
||||
else ()
|
||||
if (FILAMENT_SUPPORTS_XCB)
|
||||
add_definitions(-DFILAMENT_SUPPORTS_XCB)
|
||||
endif()
|
||||
|
||||
if (FILAMENT_SUPPORTS_XLIB)
|
||||
add_definitions(-DFILAMENT_SUPPORTS_XLIB)
|
||||
if (FILAMENT_SUPPORTS_XLIB)
|
||||
add_definitions(-DFILAMENT_SUPPORTS_XLIB)
|
||||
endif()
|
||||
|
||||
if (FILAMENT_SUPPORTS_XCB OR FILAMENT_SUPORTS_XLIB)
|
||||
add_definitions(-DFILAMENT_SUPPORTS_X11)
|
||||
set(FILAMENT_SUPPORTS_X11 TRUE)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (ANDROID OR WEBGL OR IOS)
|
||||
if (ANDROID OR WEBGL OR IOS OR FILAMENT_LINUX_IS_MOBILE)
|
||||
set(IS_MOBILE_TARGET TRUE)
|
||||
endif()
|
||||
|
||||
if (NOT ANDROID AND NOT WEBGL AND NOT IOS)
|
||||
if (ANDROID)
|
||||
add_definitions(-D__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__)
|
||||
endif()
|
||||
|
||||
if (NOT ANDROID AND NOT WEBGL AND NOT IOS AND NOT FILAMENT_LINUX_IS_MOBILE)
|
||||
set(IS_HOST_PLATFORM TRUE)
|
||||
endif()
|
||||
|
||||
@@ -131,27 +151,35 @@ if (WIN32)
|
||||
# __declspec(dllexport) in front of each functions).
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
|
||||
# The CMAKE_CXX_FLAGS vars can be overriden by some Visual Studio generators, so we use an alternative
|
||||
# global method here:
|
||||
if (${USE_STATIC_CRT})
|
||||
set(CRT_FLAGS_RELEASE "/MT")
|
||||
set(CRT_FLAGS_DEBUG "/MTd")
|
||||
add_compile_options(
|
||||
$<$<CONFIG:>:/MT>
|
||||
$<$<CONFIG:Debug>:/MTd>
|
||||
$<$<CONFIG:Release>:/MT>
|
||||
)
|
||||
else()
|
||||
set(CRT_FLAGS_RELEASE "/MD")
|
||||
set(CRT_FLAGS_DEBUG "/MDd")
|
||||
add_compile_options(
|
||||
$<$<CONFIG:>:/MD>
|
||||
$<$<CONFIG:Debug>:/MDd>
|
||||
$<$<CONFIG:Release>:/MD>
|
||||
)
|
||||
endif()
|
||||
|
||||
# TODO: Figure out why pdb generation messes with incremental compilaton.
|
||||
# IN RELEASE_WITH_DEBUG_INFO, generate debug info in .obj, no in pdb.
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${CRT_FLAGS_RELEASE} /Z7")
|
||||
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} ${CRT_FLAGS_RELEASE} /Z7")
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Z7")
|
||||
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} /Z7")
|
||||
|
||||
# In RELEASE, also generate PDBs.
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${CRT_FLAGS_RELEASE} /Zi")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${CRT_FLAGS_RELEASE} /Zi")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /Zi")
|
||||
|
||||
# In DEBUG, avoid generating a PDB file which seems to mess with incremental compilation.
|
||||
# Instead generate debug info directly inside obj files.
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${CRT_FLAGS_DEBUG} /Z7")
|
||||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${CRT_FLAGS_DEBUG} /Z7")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Z7")
|
||||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Z7")
|
||||
|
||||
# Special settings when building on CI.
|
||||
if (${FILAMENT_WINDOWS_CI_BUILD})
|
||||
@@ -271,7 +299,7 @@ if (LINUX)
|
||||
endif()
|
||||
|
||||
if (ANDROID)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -Werror=unguarded-availability")
|
||||
endif()
|
||||
|
||||
if (CYGWIN)
|
||||
@@ -494,11 +522,15 @@ function(list_licenses OUTPUT MODULES)
|
||||
foreach(module ${_MODULES})
|
||||
set(license_path "../../third_party/${module}/LICENSE")
|
||||
get_filename_component(fullname "${license_path}" ABSOLUTE)
|
||||
string(APPEND CONTENT "${STR_OPENER}License and copyrights for ${module}:\n${STR_CLOSER},\n")
|
||||
file(READ ${license_path} license_long)
|
||||
string(REPLACE "\n" "${STR_CLOSER},\n${STR_OPENER}" license ${license_long})
|
||||
string(APPEND CONTENT ${STR_OPENER}${license}\n${STR_CLOSER},)
|
||||
string(APPEND CONTENT "\n\n")
|
||||
if(EXISTS ${fullname})
|
||||
string(APPEND CONTENT "${STR_OPENER}License and copyrights for ${module}:\n${STR_CLOSER},\n")
|
||||
file(READ ${license_path} license_long)
|
||||
string(REPLACE "\n" "${STR_CLOSER},\n${STR_OPENER}" license ${license_long})
|
||||
string(APPEND CONTENT ${STR_OPENER}${license}\n${STR_CLOSER},)
|
||||
string(APPEND CONTENT "\n\n")
|
||||
else()
|
||||
message(AUTHOR_WARNING "${license_path} not found. You can ignore this warning if you have devendored ${module}.")
|
||||
endif()
|
||||
endforeach()
|
||||
configure_file(${FILAMENT}/build/licenses.inc.in ${OUTPUT})
|
||||
endfunction(list_licenses)
|
||||
@@ -514,7 +546,12 @@ function(combine_static_libs TARGET OUTPUT DEPS)
|
||||
# Loop through the dependent libraries and query their location on disk.
|
||||
set(DEPS_FILES )
|
||||
foreach(DEPENDENCY ${DEPS})
|
||||
list(APPEND DEPS_FILES "$<TARGET_FILE:${DEPENDENCY}>")
|
||||
if(TARGET ${DEPENDENCY})
|
||||
get_property(dep_type TARGET ${DEPENDENCY} PROPERTY TYPE)
|
||||
if(dep_type STREQUAL "STATIC_LIBRARY")
|
||||
list(APPEND DEPS_FILES "$<TARGET_FILE:${DEPENDENCY}>")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
add_custom_command(
|
||||
@@ -547,12 +584,14 @@ if (FILAMENT_USE_SWIFTSHADER)
|
||||
find_library(SWIFTSHADER_VK NAMES vk_swiftshader HINTS "$ENV{SWIFTSHADER_LD_LIBRARY_PATH}")
|
||||
message(STATUS "Found SwiftShader VK library in: ${SWIFTSHADER_VK}.")
|
||||
add_definitions(-DFILAMENT_VKLIBRARY_PATH=\"${SWIFTSHADER_VK}\")
|
||||
elseif (FILAMENT_SUPPORTS_VULKAN AND APPLE)
|
||||
find_library(Vulkan_LIBRARY NAMES vulkan HINTS "$ENV{VULKAN_SDK}/lib" "$ENV{VULKAN_SDK}/macOS/lib")
|
||||
if (Vulkan_LIBRARY)
|
||||
set(Vulkan_FOUND ON)
|
||||
message(STATUS "Found Vulkan library in SDK: ${Vulkan_LIBRARY}.")
|
||||
add_definitions(-DFILAMENT_VKLIBRARY_PATH=\"${Vulkan_LIBRARY}\")
|
||||
elseif (FILAMENT_SUPPORTS_VULKAN)
|
||||
if (APPLE OR FILAMENT_LINUX_IS_MOBILE)
|
||||
find_library(Vulkan_LIBRARY NAMES vulkan HINTS "$ENV{VULKAN_SDK}/lib" "$ENV{VULKAN_SDK}/macOS/lib")
|
||||
if (Vulkan_LIBRARY)
|
||||
set(Vulkan_FOUND ON)
|
||||
message(STATUS "Found Vulkan library in SDK: ${Vulkan_LIBRARY}.")
|
||||
add_definitions(-DFILAMENT_VKLIBRARY_PATH=\"${Vulkan_LIBRARY}\")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -683,6 +722,7 @@ if (IS_HOST_PLATFORM)
|
||||
add_subdirectory(${TOOLS}/mipgen)
|
||||
add_subdirectory(${TOOLS}/normal-blending)
|
||||
add_subdirectory(${TOOLS}/resgen)
|
||||
add_subdirectory(${TOOLS}/rgb-to-lmsr)
|
||||
add_subdirectory(${TOOLS}/roughness-prefilter)
|
||||
add_subdirectory(${TOOLS}/specular-color)
|
||||
endif()
|
||||
|
||||
22
README.md
22
README.md
@@ -31,7 +31,7 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.android.filament:filament-android:1.11.1'
|
||||
implementation 'com.google.android.filament:filament-android:1.20.4'
|
||||
}
|
||||
```
|
||||
|
||||
@@ -52,7 +52,7 @@ Here are all the libraries available in the group `com.google.android.filament`:
|
||||
iOS projects can use CocoaPods to install the latest release:
|
||||
|
||||
```
|
||||
pod 'Filament', '~> 1.11.1'
|
||||
pod 'Filament', '~> 1.20.4'
|
||||
```
|
||||
|
||||
### Snapshots
|
||||
@@ -63,7 +63,7 @@ steps:
|
||||
1. Find the [commit](https://github.com/google/filament/commits/main) you're interested in.
|
||||
2. Click the green check mark under the commit message.
|
||||
3. Click on the _Details_ link for the platform you're interested in.
|
||||
4. On the top right, click on the _Artifacts_ dropdown and choose an artifact.
|
||||
4. On the top left click _Summary_, then in the _Artifacts_ section choose the desired artifact.
|
||||
|
||||
## Documentation
|
||||
|
||||
@@ -122,21 +122,23 @@ steps:
|
||||
- Specular anti-aliasing
|
||||
- Spot and directional light shadows
|
||||
- Cascaded shadows
|
||||
- EVSM or PCF shadows
|
||||
- EVSM, PCSS, DPCF, or PCF shadows
|
||||
- Transparent shadows
|
||||
- Contact shadows
|
||||
- Screen-space ambient occlusion
|
||||
- Screen-space reflections
|
||||
- Screen-space refraction
|
||||
- Global fog
|
||||
- Dynamic resolution
|
||||
- Dynamic resolution (with support for AMD FidelityFX FSR)
|
||||
|
||||
### 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.
|
||||
- Multiple tone mappers: generic (customizable), ACES, filmic, etc.
|
||||
- Color and tone management: luminance scaling, gamut mapping
|
||||
- Color grading: exposure, night adaptation, white balance, channel mixer,
|
||||
shadows/mid-tones/highlights, ASC CDL, contrast, saturation, etc.
|
||||
- TAA, FXAA, MSAA
|
||||
- Screen-space lens flares
|
||||
|
||||
@@ -150,9 +152,9 @@ steps:
|
||||
- [x] Points
|
||||
- [x] Lines
|
||||
- [ ] Line Loop
|
||||
- [ ] Line Strip
|
||||
- [x] Line Strip
|
||||
- [x] Triangles
|
||||
- [ ] Triangle Strip
|
||||
- [x] Triangle Strip
|
||||
- [ ] Triangle Fan
|
||||
|
||||
- Animation
|
||||
|
||||
230
RELEASE_NOTES.md
230
RELEASE_NOTES.md
@@ -3,7 +3,235 @@
|
||||
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.
|
||||
|
||||
## v1.11.2 (currently main branch)
|
||||
## v1.20.5 (currently main branch)
|
||||
|
||||
## v1.20.4
|
||||
|
||||
- gltfio: Java clients must now destroy the MaterialProvider [⚠️ **API Change**].
|
||||
- gltfio: Fix, bone pose not applied if glTF model doesn't have animations.
|
||||
- libs: Added `math::quat::fromDirectedRotation` [**NEW API**].
|
||||
- WebGL: Restore GL state when frame ends.
|
||||
|
||||
## v1.20.3
|
||||
|
||||
- Java: Fix URI bug in Android Viewer sample when dropping some zips.
|
||||
- Vulkan: Fix "uninitialized texture" warnings from the Vulkan backend.
|
||||
|
||||
## v1.20.2
|
||||
|
||||
- engine: Binary size optimizations.
|
||||
- engine: Fix, Mat4 from Quaternion was transposed.
|
||||
- Vulkan: Internal bug fixes and robustness improvements.
|
||||
- Vulkan: Reduced log spam.
|
||||
|
||||
## v1.20.1
|
||||
|
||||
- engine: Binary size improvements.
|
||||
- engine: Add basic support for instanced renderables [**NEW API**].
|
||||
- engine: Fix, first imaged passsed to `Stream::SetAcquiredImage` is ignored and leaked.
|
||||
- Vulkan: Robustness improvements.
|
||||
- Java: Fix, lookAt z axis negated.
|
||||
- gltfio: Be graceful when model has > 4 weights per vert.
|
||||
|
||||
## v1.20.0
|
||||
|
||||
- engine: Support rough screen-space reflections [⚠️ **Material breakage**].
|
||||
- engine: Added `Scene::forEach` API to iterate through a scene's entities.
|
||||
- engine: Fix incorrect normals with skinned models.
|
||||
- Vulkan: Fix segfault during shutdown.
|
||||
- WebGL: Support web apps that have multiple `FilamentViewer`s.
|
||||
- gltfio: Performance enhancements when loading models.
|
||||
|
||||
## v1.19.0
|
||||
|
||||
- engine: Support 256 morph targets.
|
||||
- engine: Screen-space reflection improvements.
|
||||
- engine: Morphing improvements and bug fixes.
|
||||
- gltfio: Generate morphing normals when they are missing.
|
||||
- gltfio: Support material extras.
|
||||
- Java: Add bindings for new morphing API.
|
||||
- Vulkan: Fix segfault on macOS.
|
||||
|
||||
## v1.18.0
|
||||
|
||||
- engine: Add support separate samplers in fragment and vertex shaders [⚠️ **Material breakage**].
|
||||
- engine: Support legacy morphing mode with vertex attributes.
|
||||
- engine: Allow more flexible quality settings for the ColorGrading LUT.
|
||||
- engine: Improve screen-space reflections quality and allow reflections and refractions together.
|
||||
- Vulkan: Bug fixes and improvements.
|
||||
|
||||
## v1.17.0
|
||||
|
||||
- engine: Add experimental glossy screen-space reflections.
|
||||
- engine: Add support for GPU morphing and 128 morph targets.
|
||||
- engine: Fix crash with non-shadow receiving renderables and VSM.
|
||||
- engine: Bring back the 3x3 filter for PCF shadows.
|
||||
- engine: Correct AABB calculation for skinned glTF models.
|
||||
|
||||
## v1.16.1
|
||||
|
||||
- engine: Added line/triangle strip support.
|
||||
|
||||
## v1.16.0
|
||||
|
||||
- engine: Fixes skinning calculations (#4887) [⚠️ **Material breakage**].
|
||||
- engine: Add support for the glTF extension KHR_materials_emissive_strength.
|
||||
- engine: Improvements and fixes to skinning calculations.
|
||||
- engine: Fix debug checks for compressed textures.
|
||||
- Metal: Fix `readPixels` when dimensions are greater than the render target's.
|
||||
|
||||
## v1.15.2
|
||||
|
||||
- engine: Add support for PCSS (Percentage Closer Soft Shadows).
|
||||
- engine: Fix spotlight shadow bias.
|
||||
- samples: Avoid leaking IBLs in Android sample-gltf-viewer.
|
||||
- libs: Fix `libibl` on mobile.
|
||||
|
||||
## v1.15.1
|
||||
|
||||
- engine: add support for DPCF (PCF shadows with contact hardening).
|
||||
- engine: add support for Wayland and Vulkan.
|
||||
- engine: Fade lights out when close to light far plane.
|
||||
- Java: Add missing `Engine#destroySkinningBuffer` method.
|
||||
|
||||
## v1.15.0
|
||||
|
||||
- engine: Fix spotlights normal bias calculation [⚠️ **Material breakage**].
|
||||
- libimage: Fix loading spherical harmonics on certain locals.
|
||||
|
||||
## v1.14.2
|
||||
|
||||
- Metal: Fix validation error when rendering to `RenderTarget` without depth attachment.
|
||||
- engine: Fix rendering glitch with zero-scale bone transforms.
|
||||
|
||||
## v1.14.1
|
||||
|
||||
- engine: Improvements to shadowing.
|
||||
|
||||
## v1.14.0
|
||||
|
||||
- engine: Internal materials can use structures as parameters [⚠️ **Material breakage**].
|
||||
- engine: `readPixels` on a `SwapChain` must be called within `beginFrame` / `endFrame` [⚠️ **API
|
||||
Change**].
|
||||
- engine: Fix normal bias and improve spotlight quality.
|
||||
- Java: Fix shadow biases.
|
||||
|
||||
## v1.13.0
|
||||
|
||||
- Android: Gradle configuration caching is now enabled.
|
||||
- Android: Filament's Gradle properties have all been renamed to `com.google.android.filament.xxx`
|
||||
where `xxx` is the property name. See `android/build.gradle` for a complete list [⚠️]
|
||||
- Android: The Gradle property `filament_tools_dir` (now called
|
||||
`com.google.android.filament.tools-dir`) does not have a default value anymore. Please specify one
|
||||
in your `gradle.properties` if you reuse the Gradle plugin in your projects [⚠️]
|
||||
- engine: Fix spotlights direction and falloff [⚠️ **Material breakage**].
|
||||
- engine: Improvements to VSM and spotlight shadows.
|
||||
|
||||
## v1.12.11
|
||||
|
||||
- Metal: Color grading performance improvement on M1 devices.
|
||||
- samples: Fix glitchy animation seen in gltf-viewer iOS sample.
|
||||
|
||||
## v1.12.10
|
||||
|
||||
- engine: rewrite dynamic resolution scaling controller for better accuracy and less jittering.
|
||||
- Java: fix missing ASTC texture enum.
|
||||
- tools: Fix normal map issues in mipgen.
|
||||
- WebGL: expose some `SurfaceOrientation` functions.
|
||||
|
||||
## v1.12.9
|
||||
|
||||
- engine: New API: `MultiSampleAntiAliasingOptions` and HDR-aware MSAA resolve. When `customResolve`
|
||||
is enabled, improves anti-aliasing quality [**NEW API**].
|
||||
- engine: Fixes and improvements for FSR.
|
||||
- engine: All APIs that take a callback as argument now also take a `CallbackHandler*`, a new
|
||||
interface that provides more flexibility around callback dispatch [**NEW API**].
|
||||
- Android: Fix JNI bindings for `DepthOfFieldOptions`.
|
||||
- Android: workarounds for Adreno-specific fraembuffer issue.
|
||||
- JavaScript: updates to JS bindings.
|
||||
|
||||
## v1.12.8
|
||||
|
||||
- engine: Added picking API to `View` [⚠️ **Materials need to be rebuilt to access this new feature**].
|
||||
- engine: A new `Engine::pumpMessageQueues()` method can be used to trigger all pending user
|
||||
callbacks right away [**NEW API**].
|
||||
- engine: new inline helpers to more easily use lambdas, functors and method callbacks with
|
||||
`{Pixel}BufferDescriptor`.
|
||||
- Vulkan: fix vertical offset for `readPixels`.
|
||||
- Vulkan: various internal improvements.
|
||||
- Metal: support integer formats with `readPixels`.
|
||||
|
||||
## v1.12.7
|
||||
|
||||
- engine: Fix, apply emissive after shadowing.
|
||||
|
||||
## v1.12.6
|
||||
|
||||
- engine: Added concept of lod bias to materials.
|
||||
[⚠️ **Materials need to be rebuilt to access this new feature**].
|
||||
- engine: Fix, BGRA ordering respected for external images with OpenGL on iOS.
|
||||
- engine: Use more sensible defaults for spot light inner outer cone angles.
|
||||
- engine: Fix potential race condition that caused stalls in `endFrame`.
|
||||
- gltfio: Improved handling of transparent materials.
|
||||
- Metal: Fix potential crash on earlier versions of iOS (<= 13.0).
|
||||
- Android: Fix `filament-utils-android` 'lite' flavor.
|
||||
- Java: Fix potential crash with `IBLPrefilter`.
|
||||
|
||||
## v1.12.5
|
||||
|
||||
- engine: work around a job scheduling issue in `endFrame` that caused stuttering on some Android
|
||||
devices.
|
||||
|
||||
## v1.12.4
|
||||
|
||||
- engine: New night adaptation API on `ColorGrading`. This API can be used to create an effect that
|
||||
that simulates color and brightness shifts in human vision in low-light conditions.
|
||||
- engine: improved performance of AMD FidelityFX FSR1 by 4.6x, it now runs in about 2ms in 4K.
|
||||
- engine: Dynamic resolution quality `MEDIUM`, `HIGH` and `ULTRA` now all use AMD FidelityFX FSR1.
|
||||
- engine: Fix crash when duplicating material instances.
|
||||
- gltfio: generate tangents if requested by the material.
|
||||
|
||||
## v1.12.3
|
||||
|
||||
- engine: Support AMD FidelityFX Super Resolution for dynamic resolution scaling
|
||||
|
||||
## v1.12.2
|
||||
|
||||
- engine: New API on `ColorGrading` to enable or disable gamut mapping at will [**New API**].
|
||||
- engine: Fix typo causing ShadowOptions::shadowFar to not work properly.
|
||||
- engine: Fix, CSM glitch when using shadowMultiplier materials.
|
||||
- engine: Improve precision when computing camera projection.
|
||||
- engine: Increase the number of supported spot shadows to 14 (from 6).
|
||||
- Metal: Add texture swizzling support for external textures.
|
||||
|
||||
## v1.12.1
|
||||
|
||||
- engine: `double` precision translation support in TransformManager. Disabled by default.
|
||||
Augment model (and view) matrix on `Camera` to accept double precision matrices. When enabled,
|
||||
double precision translations allow filament to handle a very large world space [**New API**].
|
||||
- engine: Fix, Views with custom render targets are now blendable.
|
||||
|
||||
## v1.12.0
|
||||
|
||||
- engine: Option to automatically compute bent normals from SSAO & apply to specular AO
|
||||
[⚠️ **Material breakage**].
|
||||
- engine: New APIs: Light channels. Geometry and lights now have a channel associated to them, at
|
||||
least one channel must match for lighting to occur [⚠️ **Material breakage**].
|
||||
- engine: Fix potential GPU crash with punctual lights near the far clipping plane.
|
||||
- materials: The `inverseTonemap` API is now an exact inverse of the Filmic tonemapper.
|
||||
- Metal: Better support for texture formats on M1 Macs.
|
||||
|
||||
## v1.11.2
|
||||
|
||||
- engine: New API: `ColorGrading::Builder::toneMapper(const ToneMapper*)`.
|
||||
- engine: New tone mapper: `GenericToneMapper`, a configurable tone mapper.
|
||||
- engine: `ColorGrading::Builder::toneMapping(ColorGrading::ToneMapping)` is now deprecated.
|
||||
- engine: Removed `REINHARD` tonemap operator[⚠️ **API Change**].
|
||||
- engine: Improve s3tc_srgb detection on desktop.
|
||||
- engine: Add bilateral threshold in SSAO options.
|
||||
- gltfio: Fix AssetLoader leak, remove unwanted destructor.
|
||||
- Metal/Vulkan: Fix uploading texture data with padding or offset.
|
||||
- Metal: fix GPU crash seen with large amounts of geometry.
|
||||
|
||||
## v1.11.1
|
||||
|
||||
|
||||
@@ -122,20 +122,20 @@ The Gradle project used to generate the AAR is located at `<filament>\android`.
|
||||
|
||||
```
|
||||
cd android
|
||||
gradlew -Pfilament_dist_dir=..\out\android-release\filament assembleRelease
|
||||
gradlew -Pcom.google.android.filament.dist-dir=..\out\android-release\filament assembleRelease
|
||||
copy filament-android\build\outputs\aar\filament-android-release.aar ..\..\out\
|
||||
```
|
||||
|
||||
If you're only interested in building for a single ABI, you'll need to pass a `filament_abis` parameter:
|
||||
If you're only interested in building for a single ABI, you'll need to pass a `com.google.android.filament.abis` parameter:
|
||||
|
||||
```
|
||||
gradlew -Pfilament_dist_dir=..\out\android-release\filament assembleRelease -Pfilament_abis=x86
|
||||
gradlew -Pcom.google.android.filament.dist-dir=..\out\android-release\filament assembleRelease -Pcom.google.android.filament.abis=x86
|
||||
```
|
||||
|
||||
If you're only interested in building SDK, you may skip samples build by passing a `filament_skip_samples` flag:
|
||||
If you're only interested in building SDK, you may skip samples build by passing a `com.google.android.filament.skip-samples` flag:
|
||||
|
||||
```
|
||||
gradlew -Pfilament_dist_dir=..\out\android-release\filament assembleRelease -Pfilament_skip_samples
|
||||
gradlew -Pcom.google.android.filament.dist-dir=..\out\android-release\filament assembleRelease -Pfilament_skip_samples
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -1,26 +1,28 @@
|
||||
// This script accepts the following parameters:
|
||||
//
|
||||
// filament_dist_dir
|
||||
// com.google.android.filament.dist-dir
|
||||
// Path to the Filament distribution/install directory for Android
|
||||
// (produced by make/ninja install). This directory must contain lib/arm64-v8a/ etc.
|
||||
//
|
||||
// filament_tools_dir
|
||||
// com.google.android.filament.tools-dir
|
||||
// Path to the Filament distribution/install directory for desktop.
|
||||
// This directory must contain bin/matc.
|
||||
//
|
||||
// filament_exclude_vulkan
|
||||
// com.google.android.filament.exclude-vulkan
|
||||
// When set, support for Vulkan will be excluded.
|
||||
//
|
||||
// filament_skip_samples
|
||||
// com.google.android.filament.skip-samples
|
||||
// Exclude samples from the project. Useful to speed up compilation.
|
||||
//
|
||||
// filament_abis
|
||||
// com.google.android.filament.abis
|
||||
// List of supported ABIs to build as a comma separated list. Available options are:
|
||||
// arm64-v8a, armeabi-v7a, x86_64, x86, all
|
||||
// Defaults to all.
|
||||
//
|
||||
// Example:
|
||||
// ./gradlew -Pfilament_dist_dir=../dist-android-release assembleRelease -Pfilament_abis=x86
|
||||
// ./gradlew -Pcom.google.android.filament.dist-dir=../dist-android-release \
|
||||
// -Pcom.google.android.filament.abis=x86 \
|
||||
// assembleRelease
|
||||
|
||||
// Publishing to Maven Central:
|
||||
// - Build and upload artifacts with ./gradlew publish
|
||||
@@ -40,45 +42,58 @@
|
||||
//
|
||||
|
||||
buildscript {
|
||||
def filamentPath = file("../out/android-release/filament").absolutePath
|
||||
if (project.hasProperty("filament_dist_dir")) {
|
||||
filamentPath = file(project.property("filament_dist_dir")).absolutePath
|
||||
}
|
||||
def path = providers
|
||||
.gradleProperty("com.google.android.filament.dist-dir")
|
||||
.forUseAtConfigurationTime().get()
|
||||
|
||||
def directory = objects.fileProperty().fileValue(new File(path)).getAsFile().get()
|
||||
def filamentPath = directory.absolutePath
|
||||
|
||||
// Our CMake scripts require a forward-slash path for the FILAMENT_DIST_DIR
|
||||
// variable, so here we convert the native path to a forward-slash path.
|
||||
filamentPath = filamentPath.replace(File.separator, '/')
|
||||
|
||||
// Warning: changing this property does not work well with incremental builds.
|
||||
def excludeVulkan = project.hasProperty("filament_exclude_vulkan")
|
||||
def excludeVulkan = providers
|
||||
.gradleProperty("com.google.android.filament.exclude-vulkan")
|
||||
.forUseAtConfigurationTime()
|
||||
.isPresent()
|
||||
|
||||
def abis = ["arm64-v8a", "armeabi-v7a", "x86_64", "x86"]
|
||||
if (project.hasProperty("filament_abis")) {
|
||||
def newAbis = project.property("filament_abis").split(',')
|
||||
if (!newAbis.contains("all")) {
|
||||
abis = newAbis
|
||||
}
|
||||
def newAbis = providers
|
||||
.gradleProperty("com.google.android.filament.abis")
|
||||
.forUseAtConfigurationTime()
|
||||
.get()
|
||||
.split(',')
|
||||
if (!newAbis.contains("all")) {
|
||||
abis = newAbis
|
||||
}
|
||||
|
||||
// Our minSdkVersion is 19.
|
||||
ext.versions = [
|
||||
'minSdk': 19,
|
||||
'targetSdk': 30,
|
||||
'compileSdk': 30,
|
||||
'kotlin': '1.5.0',
|
||||
'buildTools': '30.0.3',
|
||||
'ndk': '22.1.7171670'
|
||||
'targetSdk': 31,
|
||||
'compileSdk': 31,
|
||||
'kotlin': '1.6.10',
|
||||
'kotlin_coroutines': '1.6.0',
|
||||
'buildTools': '32.0.0',
|
||||
'ndk': '23.1.7779620'
|
||||
]
|
||||
|
||||
ext.deps = [
|
||||
'androidx': [
|
||||
'annotations': "androidx.annotation:annotation:1.1.0",
|
||||
'core': "androidx.core:core:1.3.0",
|
||||
'annotations': "androidx.annotation:annotation:1.3.0",
|
||||
'core': "androidx.core:core:1.7.0",
|
||||
],
|
||||
'kotlin': "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${versions.kotlin}"
|
||||
'kotlin': "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${versions.kotlin}",
|
||||
'coroutines': [
|
||||
'core': "org.jetbrains.kotlinx:kotlinx-coroutines-core:${versions.kotlin_coroutines}",
|
||||
'android': "org.jetbrains.kotlinx:kotlinx-coroutines-android:${versions.kotlin_coroutines}",
|
||||
]
|
||||
]
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.2.0'
|
||||
// NOTE: See TODO in gradle.properties once we move to Gradle 7.4
|
||||
classpath 'com.android.tools.build:gradle:7.1.1'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}"
|
||||
}
|
||||
|
||||
@@ -93,8 +108,7 @@ buildscript {
|
||||
ext.cppFlags = [
|
||||
"-std=c++17",
|
||||
"-Wno-unused-command-line-argument",
|
||||
// Required to support API levels below 23
|
||||
"-Wl,--hash-style=both",
|
||||
"-Wl,--hash-style=both", // Required to support API levels below 23
|
||||
"-fno-stack-protector",
|
||||
"-fno-exceptions",
|
||||
"-fno-unwind-tables",
|
||||
@@ -120,7 +134,7 @@ buildscript {
|
||||
}
|
||||
|
||||
plugins {
|
||||
id 'io.codearte.nexus-staging' version '0.22.0'
|
||||
id 'io.codearte.nexus-staging' version '0.30.0'
|
||||
}
|
||||
|
||||
// Nexus Staging configuration
|
||||
@@ -189,7 +203,8 @@ subprojects {
|
||||
gradle.taskGraph.whenReady {
|
||||
gradle.taskGraph.allTasks.each {
|
||||
it.onlyIf {
|
||||
!it.project.ext.has('isSample') || !project.hasProperty('filament_skip_samples')
|
||||
!it.project.ext.has('isSample') ||
|
||||
!project.hasProperty('com.google.android.filament.skip-samples')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
|
||||
plugins {
|
||||
id 'groovy-gradle-plugin'
|
||||
}
|
||||
|
||||
gradlePlugin {
|
||||
plugins {
|
||||
create("filament-tools-plugin") {
|
||||
id = "filament-tools-plugin"
|
||||
implementationClass = "FilamentToolsPlugin"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
// This plugin accepts the following parameters:
|
||||
//
|
||||
// filament_tools_dir
|
||||
// com.google.android.filament.tools-dir
|
||||
// Path to the Filament distribution/install directory for desktop.
|
||||
// This directory must contain bin/matc.
|
||||
//
|
||||
// filament_exclude_vulkan
|
||||
// com.google.android.filament.exclude-vulkan
|
||||
// When set, support for Vulkan will be excluded.
|
||||
//
|
||||
// Example:
|
||||
// ./gradlew -Pfilament_tools_dir=../../dist-release assembleDebug
|
||||
// ./gradlew -Pcom.google.android.filament.tools-dir=../../dist-release assembleDebug
|
||||
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.GradleException
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.provider.ProviderFactory
|
||||
import org.gradle.api.file.DirectoryProperty
|
||||
import org.gradle.api.file.FileSystemOperations
|
||||
import org.gradle.api.file.FileType
|
||||
import org.gradle.api.file.RegularFileProperty
|
||||
import org.gradle.api.logging.LogLevel
|
||||
@@ -27,14 +29,18 @@ 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
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.internal.os.OperatingSystem
|
||||
import org.gradle.process.ExecOperations
|
||||
import org.gradle.work.ChangeType
|
||||
import org.gradle.work.Incremental
|
||||
import org.gradle.work.InputChanges
|
||||
|
||||
import java.nio.file.Paths
|
||||
|
||||
class TaskWithBinary extends DefaultTask {
|
||||
import javax.inject.Inject
|
||||
|
||||
abstract class TaskWithBinary extends DefaultTask {
|
||||
private final String binaryName
|
||||
private Property<String> binaryPath = null
|
||||
|
||||
@@ -42,15 +48,23 @@ class TaskWithBinary extends DefaultTask {
|
||||
binaryName = name
|
||||
}
|
||||
|
||||
@Inject abstract ObjectFactory getObjects()
|
||||
@Inject abstract ProviderFactory getProviders()
|
||||
|
||||
@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()
|
||||
def filamentToolsPath = providers
|
||||
.gradleProperty("com.google.android.filament.tools-dir")
|
||||
.forUseAtConfigurationTime().get()
|
||||
def directory = objects.fileProperty()
|
||||
.fileValue(new File(filamentToolsPath)).getAsFile().get()
|
||||
Paths.get(directory.absolutePath, path).toFile()
|
||||
}
|
||||
|
||||
binaryPath = project.objects.property(String.class)
|
||||
binaryPath = objects.property(String.class)
|
||||
binaryPath.set(
|
||||
(OperatingSystem.current().isWindows() ? fullPath[0] : fullPath[1]).toString())
|
||||
}
|
||||
@@ -84,6 +98,11 @@ abstract class MaterialCompiler extends TaskWithBinary {
|
||||
@OutputDirectory
|
||||
abstract DirectoryProperty getOutputDir()
|
||||
|
||||
@Inject abstract FileSystemOperations getFs()
|
||||
@Inject abstract ExecOperations getExec()
|
||||
@Inject abstract ObjectFactory getObjects()
|
||||
@Inject abstract ProviderFactory getProviders()
|
||||
|
||||
MaterialCompiler() {
|
||||
super("matc")
|
||||
}
|
||||
@@ -91,7 +110,9 @@ abstract class MaterialCompiler extends TaskWithBinary {
|
||||
@TaskAction
|
||||
void execute(InputChanges inputs) {
|
||||
if (!inputs.incremental) {
|
||||
project.delete(project.fileTree(outputDir.asFile.get()).matching { include '*.filamat' })
|
||||
fs.delete({
|
||||
delete(objects.fileTree().from(outputDir).matching { include '*.filamat' })
|
||||
})
|
||||
}
|
||||
|
||||
inputs.getFileChanges(inputDir).each { InputFileDetails change ->
|
||||
@@ -115,12 +136,15 @@ abstract class MaterialCompiler extends TaskWithBinary {
|
||||
}
|
||||
|
||||
def matcArgs = []
|
||||
if (!project.hasProperty("filament_exclude_vulkan")) {
|
||||
def exclude_vulkan = providers
|
||||
.gradleProperty("com.google.android.filament.exclude-vulkan")
|
||||
.forUseAtConfigurationTime().present
|
||||
if (!exclude_vulkan) {
|
||||
matcArgs += ['-a', 'vulkan']
|
||||
}
|
||||
matcArgs += ['-a', 'opengl', '-p', 'mobile', '-o', getOutputFile(file), file]
|
||||
|
||||
project.exec {
|
||||
exec.exec {
|
||||
standardOutput out
|
||||
errorOutput err
|
||||
executable "${binary.get()}"
|
||||
@@ -149,6 +173,10 @@ abstract class IblGenerator extends TaskWithBinary {
|
||||
@OutputDirectory
|
||||
abstract DirectoryProperty getOutputDir()
|
||||
|
||||
@Inject abstract FileSystemOperations getFs()
|
||||
@Inject abstract ExecOperations getExec()
|
||||
@Inject abstract ObjectFactory getObjects()
|
||||
|
||||
IblGenerator() {
|
||||
super("cmgen")
|
||||
}
|
||||
@@ -156,7 +184,9 @@ abstract class IblGenerator extends TaskWithBinary {
|
||||
@TaskAction
|
||||
void execute(InputChanges inputs) {
|
||||
if (!inputs.incremental) {
|
||||
project.delete(project.fileTree(outputDir.asFile.get()).matching { include '*' })
|
||||
fs.delete({
|
||||
delete(objects.fileTree().from(outputDir).matching { include '*' })
|
||||
})
|
||||
}
|
||||
|
||||
inputs.getFileChanges(inputFile).each { InputFileDetails change ->
|
||||
@@ -188,7 +218,7 @@ abstract class IblGenerator extends TaskWithBinary {
|
||||
}
|
||||
commandArgs = commandArgs + " " + file
|
||||
|
||||
project.exec {
|
||||
exec.exec {
|
||||
standardOutput out
|
||||
errorOutput err
|
||||
executable "${binary.get()}"
|
||||
@@ -213,6 +243,9 @@ abstract class MeshCompiler extends TaskWithBinary {
|
||||
@OutputDirectory
|
||||
abstract DirectoryProperty getOutputDir()
|
||||
|
||||
@Inject abstract FileSystemOperations getFs()
|
||||
@Inject abstract ExecOperations getExec()
|
||||
|
||||
MeshCompiler() {
|
||||
super("filamesh")
|
||||
}
|
||||
@@ -220,7 +253,9 @@ abstract class MeshCompiler extends TaskWithBinary {
|
||||
@TaskAction
|
||||
void execute(InputChanges inputs) {
|
||||
if (!inputs.incremental) {
|
||||
project.delete(project.fileTree(outputDir.asFile.get()).matching { include '*.filamesh' })
|
||||
fs.delete({
|
||||
delete(objects.fileTree().from(outputDir).matching { include '*.filamesh' })
|
||||
})
|
||||
}
|
||||
|
||||
inputs.getFileChanges(inputFile).each { InputFileDetails change ->
|
||||
@@ -243,7 +278,7 @@ abstract class MeshCompiler extends TaskWithBinary {
|
||||
" Ensure Filament has been built/installed before building this app.")
|
||||
}
|
||||
|
||||
project.exec {
|
||||
exec.exec {
|
||||
standardOutput out
|
||||
errorOutput err
|
||||
executable "${binary.get()}"
|
||||
@@ -280,11 +315,6 @@ class FilamentToolsPlugin implements Plugin<Project> {
|
||||
extension.meshInputFile = project.objects.fileProperty()
|
||||
extension.meshOutputDir = project.objects.directoryProperty()
|
||||
|
||||
project.ext.filamentToolsPath = project.file("../../../out/release/filament")
|
||||
if (project.hasProperty("filament_tools_dir")) {
|
||||
project.ext.filamentToolsPath = project.file(project.property("filament_tools_dir"))
|
||||
}
|
||||
|
||||
project.tasks.register("filamentCompileMaterials", MaterialCompiler) {
|
||||
enabled =
|
||||
extension.materialInputDir.isPresent() &&
|
||||
|
||||
@@ -16,8 +16,10 @@
|
||||
|
||||
#include "CallbackUtils.h"
|
||||
|
||||
#include "private/backend/VirtualMachineEnv.h"
|
||||
|
||||
void acquireCallbackJni(JNIEnv* env, CallbackJni& callbackUtils) {
|
||||
#ifdef ANDROID
|
||||
#ifdef __ANDROID__
|
||||
callbackUtils.handlerClass = env->FindClass("android/os/Handler");
|
||||
callbackUtils.handlerClass = (jclass) env->NewGlobalRef(callbackUtils.handlerClass);
|
||||
callbackUtils.post = env->GetMethodID(callbackUtils.handlerClass,
|
||||
@@ -32,7 +34,7 @@ void acquireCallbackJni(JNIEnv* env, CallbackJni& callbackUtils) {
|
||||
|
||||
void releaseCallbackJni(JNIEnv* env, CallbackJni callbackUtils, jobject handler, jobject callback) {
|
||||
if (handler && callback) {
|
||||
#ifdef ANDROID
|
||||
#ifdef __ANDROID__
|
||||
if (env->IsInstanceOf(handler, callbackUtils.handlerClass)) {
|
||||
env->CallBooleanMethod(handler, callbackUtils.post, callback);
|
||||
}
|
||||
@@ -43,59 +45,12 @@ void releaseCallbackJni(JNIEnv* env, CallbackJni callbackUtils, jobject handler,
|
||||
}
|
||||
env->DeleteGlobalRef(handler);
|
||||
env->DeleteGlobalRef(callback);
|
||||
#ifdef ANDROID
|
||||
#ifdef __ANDROID__
|
||||
env->DeleteGlobalRef(callbackUtils.handlerClass);
|
||||
#endif
|
||||
env->DeleteGlobalRef(callbackUtils.executorClass);
|
||||
}
|
||||
|
||||
JniBufferCallback* JniBufferCallback::make(filament::Engine* engine,
|
||||
JNIEnv* env, jobject handler, jobject callback, AutoBuffer&& buffer) {
|
||||
return new JniBufferCallback(env, handler, callback, std::move(buffer));
|
||||
}
|
||||
|
||||
JniBufferCallback::JniBufferCallback(JNIEnv* env, jobject handler, jobject callback,
|
||||
AutoBuffer&& buffer)
|
||||
: mEnv(env)
|
||||
, mHandler(env->NewGlobalRef(handler))
|
||||
, mCallback(env->NewGlobalRef(callback))
|
||||
, mBuffer(std::move(buffer)) {
|
||||
acquireCallbackJni(env, mCallbackUtils);
|
||||
}
|
||||
|
||||
JniBufferCallback::~JniBufferCallback() {
|
||||
releaseCallbackJni(mEnv, mCallbackUtils, mHandler, mCallback);
|
||||
}
|
||||
|
||||
void JniBufferCallback::invoke(void*, size_t, void* user) {
|
||||
JniBufferCallback* data = reinterpret_cast<JniBufferCallback*>(user);
|
||||
delete data;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------
|
||||
|
||||
JniImageCallback* JniImageCallback::make(filament::Engine* engine,
|
||||
JNIEnv* env, jobject handler, jobject callback, long image) {
|
||||
return new JniImageCallback(env, handler, callback, image);
|
||||
}
|
||||
|
||||
JniImageCallback::JniImageCallback(JNIEnv* env, jobject handler, jobject callback, long image)
|
||||
: mEnv(env)
|
||||
, mHandler(env->NewGlobalRef(handler))
|
||||
, mCallback(env->NewGlobalRef(callback))
|
||||
, mImage(image) {
|
||||
acquireCallbackJni(env, mCallbackUtils);
|
||||
}
|
||||
|
||||
JniImageCallback::~JniImageCallback() {
|
||||
releaseCallbackJni(mEnv, mCallbackUtils, mHandler, mCallback);
|
||||
}
|
||||
|
||||
void JniImageCallback::invoke(void*, void* user) {
|
||||
JniImageCallback* data = reinterpret_cast<JniImageCallback*>(user);
|
||||
delete data;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------
|
||||
|
||||
JniCallback* JniCallback::make(JNIEnv* env, jobject handler, jobject callback) {
|
||||
@@ -103,17 +58,63 @@ JniCallback* JniCallback::make(JNIEnv* env, jobject handler, jobject callback) {
|
||||
}
|
||||
|
||||
JniCallback::JniCallback(JNIEnv* env, jobject handler, jobject callback)
|
||||
: mEnv(env)
|
||||
, mHandler(env->NewGlobalRef(handler))
|
||||
, mCallback(env->NewGlobalRef(callback)) {
|
||||
: mHandler(env->NewGlobalRef(handler)),
|
||||
mCallback(env->NewGlobalRef(callback)) {
|
||||
acquireCallbackJni(env, mCallbackUtils);
|
||||
}
|
||||
|
||||
JniCallback::~JniCallback() {
|
||||
releaseCallbackJni(mEnv, mCallbackUtils, mHandler, mCallback);
|
||||
JniCallback::~JniCallback() = default;
|
||||
|
||||
void JniCallback::post(void* user, filament::backend::CallbackHandler::Callback callback) {
|
||||
callback(user);
|
||||
}
|
||||
|
||||
void JniCallback::invoke(void* user) {
|
||||
JniCallback* data = reinterpret_cast<JniCallback*>(user);
|
||||
delete data;
|
||||
void JniCallback::postToJavaAndDestroy(JniCallback* callback) {
|
||||
JNIEnv* env = filament::VirtualMachineEnv::get().getEnvironment();
|
||||
releaseCallbackJni(env, callback->mCallbackUtils, callback->mHandler, callback->mCallback);
|
||||
delete callback;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------
|
||||
|
||||
JniBufferCallback* JniBufferCallback::make(filament::Engine*,
|
||||
JNIEnv* env, jobject handler, jobject callback, AutoBuffer&& buffer) {
|
||||
return new JniBufferCallback(env, handler, callback, std::move(buffer));
|
||||
}
|
||||
|
||||
JniBufferCallback::JniBufferCallback(JNIEnv* env, jobject handler, jobject callback,
|
||||
AutoBuffer&& buffer)
|
||||
: JniCallback(env, handler, callback),
|
||||
mBuffer(std::move(buffer)) {
|
||||
}
|
||||
|
||||
JniBufferCallback::~JniBufferCallback() = default;
|
||||
|
||||
void JniBufferCallback::postToJavaAndDestroy(void*, size_t, void* user) {
|
||||
JniBufferCallback* callback = (JniBufferCallback*)user;
|
||||
JNIEnv* env = filament::VirtualMachineEnv::get().getEnvironment();
|
||||
callback->mBuffer.attachToJniThread(env);
|
||||
releaseCallbackJni(env, callback->mCallbackUtils, callback->mHandler, callback->mCallback);
|
||||
delete callback;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------
|
||||
|
||||
JniImageCallback* JniImageCallback::make(filament::Engine*,
|
||||
JNIEnv* env, jobject handler, jobject callback, long image) {
|
||||
return new JniImageCallback(env, handler, callback, image);
|
||||
}
|
||||
|
||||
JniImageCallback::JniImageCallback(JNIEnv* env, jobject handler, jobject callback, long image)
|
||||
: JniCallback(env, handler, callback),
|
||||
mImage(image) {
|
||||
}
|
||||
|
||||
JniImageCallback::~JniImageCallback() = default;
|
||||
|
||||
void JniImageCallback::postToJavaAndDestroy(void*, void* user) {
|
||||
JniImageCallback* callback = (JniImageCallback*)user;
|
||||
JNIEnv* env = filament::VirtualMachineEnv::get().getEnvironment();
|
||||
releaseCallbackJni(env, callback->mCallbackUtils, callback->mHandler, callback->mCallback);
|
||||
delete callback;
|
||||
}
|
||||
|
||||
@@ -18,13 +18,14 @@
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include "common/CallbackUtils.h"
|
||||
#include "common/NioUtils.h"
|
||||
|
||||
#include <backend/CallbackHandler.h>
|
||||
|
||||
#include <filament/Engine.h>
|
||||
|
||||
struct CallbackJni {
|
||||
#ifdef ANDROID
|
||||
#ifdef __ANDROID__
|
||||
jclass handlerClass = nullptr;
|
||||
jmethodID post = nullptr;
|
||||
#endif
|
||||
@@ -35,57 +36,60 @@ struct CallbackJni {
|
||||
void acquireCallbackJni(JNIEnv* env, CallbackJni& callbackUtils);
|
||||
void releaseCallbackJni(JNIEnv* env, CallbackJni callbackUtils, jobject handler, jobject callback);
|
||||
|
||||
struct JniBufferCallback {
|
||||
struct JniCallback : private filament::backend::CallbackHandler {
|
||||
JniCallback(JniCallback const &) = delete;
|
||||
JniCallback(JniCallback&&) = delete;
|
||||
JniCallback& operator=(JniCallback const &) = delete;
|
||||
JniCallback& operator=(JniCallback&&) = delete;
|
||||
|
||||
// create a JniCallback
|
||||
static JniCallback* make(JNIEnv* env, jobject handler, jobject runnable);
|
||||
|
||||
// execute the callback on the java thread and destroy ourselves
|
||||
static void postToJavaAndDestroy(JniCallback* callback);
|
||||
|
||||
// CallbackHandler interface.
|
||||
void post(void* user, Callback callback) override;
|
||||
|
||||
// Get the CallbackHandler interface
|
||||
filament::backend::CallbackHandler* getHandler() noexcept { return this; }
|
||||
|
||||
jobject getCallbackObject() { return mCallback; }
|
||||
|
||||
protected:
|
||||
JniCallback(JNIEnv* env, jobject handler, jobject runnable);
|
||||
explicit JniCallback() = default; // this version does nothing
|
||||
virtual ~JniCallback();
|
||||
jobject mHandler{};
|
||||
jobject mCallback{};
|
||||
CallbackJni mCallbackUtils{};
|
||||
};
|
||||
|
||||
|
||||
struct JniBufferCallback : public JniCallback {
|
||||
// create a JniBufferCallback
|
||||
static JniBufferCallback* make(filament::Engine* engine,
|
||||
JNIEnv* env, jobject handler, jobject callback, AutoBuffer&& buffer);
|
||||
|
||||
static void invoke(void* buffer, size_t n, void* user);
|
||||
// execute the callback on the java thread and destroy ourselves
|
||||
static void postToJavaAndDestroy(void*, size_t, void* user);
|
||||
|
||||
private:
|
||||
JniBufferCallback(JNIEnv* env, jobject handler, jobject callback, AutoBuffer&& buffer);
|
||||
JniBufferCallback(JniBufferCallback const &) = delete;
|
||||
JniBufferCallback(JniBufferCallback&&) = delete;
|
||||
~JniBufferCallback();
|
||||
|
||||
JNIEnv* mEnv;
|
||||
jobject mHandler;
|
||||
jobject mCallback;
|
||||
virtual ~JniBufferCallback();
|
||||
AutoBuffer mBuffer;
|
||||
CallbackJni mCallbackUtils;
|
||||
};
|
||||
|
||||
struct JniImageCallback {
|
||||
struct JniImageCallback : public JniCallback {
|
||||
// create a JniImageCallback
|
||||
static JniImageCallback* make(filament::Engine* engine, JNIEnv* env, jobject handler,
|
||||
jobject runnable, long image);
|
||||
|
||||
static void invoke(void* image, void* user);
|
||||
// execute the callback on the java thread and destroy ourselves
|
||||
static void postToJavaAndDestroy(void*, void* user);
|
||||
|
||||
private:
|
||||
JniImageCallback(JNIEnv* env, jobject handler, jobject runnable, long image);
|
||||
JniImageCallback(JniImageCallback const &) = delete;
|
||||
JniImageCallback(JniImageCallback&&) = delete;
|
||||
~JniImageCallback();
|
||||
|
||||
JNIEnv* mEnv;
|
||||
jobject mHandler;
|
||||
jobject mCallback;
|
||||
virtual ~JniImageCallback();
|
||||
long mImage;
|
||||
CallbackJni mCallbackUtils;
|
||||
};
|
||||
|
||||
struct JniCallback {
|
||||
static JniCallback* make(JNIEnv* env, jobject handler, jobject runnable);
|
||||
|
||||
static void invoke(void* user);
|
||||
|
||||
private:
|
||||
JniCallback(JNIEnv* env, jobject handler, jobject runnable);
|
||||
JniCallback(JniCallback const &) = delete;
|
||||
JniCallback(JniCallback&&) = delete;
|
||||
~JniCallback();
|
||||
|
||||
JNIEnv* mEnv;
|
||||
jobject mHandler;
|
||||
jobject mCallback;
|
||||
CallbackJni mCallbackUtils;
|
||||
};
|
||||
|
||||
@@ -38,6 +38,10 @@ public:
|
||||
AutoBuffer(AutoBuffer&& rhs) noexcept;
|
||||
~AutoBuffer() noexcept;
|
||||
|
||||
void attachToJniThread(JNIEnv* env) noexcept {
|
||||
mEnv = env;
|
||||
}
|
||||
|
||||
void* getData() const noexcept {
|
||||
return mUserData;
|
||||
}
|
||||
|
||||
@@ -370,3 +370,10 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderVariant
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
builder->variantFilter((uint8_t) variantFilter);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderUseLegacyMorphing(JNIEnv*,
|
||||
jclass, jlong nativeBuilder) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
builder->useLegacyMorphing();
|
||||
}
|
||||
|
||||
@@ -459,6 +459,19 @@ public class MaterialBuilder {
|
||||
@NonNull
|
||||
public MaterialBuilder variantFilter(int variantFilter) {
|
||||
nMaterialBuilderVariantFilter(mNativeObject, variantFilter);
|
||||
useLegacyMorphing();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Legacy morphing uses the data in the {@link VertexBuffer.VertexAttribute} slots
|
||||
* (<code>MORPH_POSITION_0</code>, etc) and is limited to 4 morph targets.
|
||||
*
|
||||
* @see RenderableManager.Builder#morphing()
|
||||
*/
|
||||
@NonNull
|
||||
public MaterialBuilder useLegacyMorphing() {
|
||||
nMaterialBuilderUseLegacyMorphing(mNativeObject);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -599,4 +612,5 @@ public class MaterialBuilder {
|
||||
private static native void nMaterialBuilderOptimization(long nativeBuilder, int optimization);
|
||||
private static native void nMaterialBuilderVariantFilter(long nativeBuilder,
|
||||
int variantFilter);
|
||||
private static native void nMaterialBuilderUseLegacyMorphing(long nativeBuilder);
|
||||
}
|
||||
|
||||
@@ -27,6 +27,10 @@ add_library(filaflat STATIC IMPORTED)
|
||||
set_target_properties(filaflat PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libfilaflat.a)
|
||||
|
||||
add_library(filamat STATIC IMPORTED)
|
||||
set_target_properties(filamat PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libfilamat.a)
|
||||
|
||||
add_library(geometry STATIC IMPORTED)
|
||||
set_target_properties(geometry PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libgeometry.a)
|
||||
@@ -70,6 +74,7 @@ add_library(filament-jni SHARED
|
||||
src/main/cpp/Material.cpp
|
||||
src/main/cpp/MaterialInstance.cpp
|
||||
src/main/cpp/MathUtils.cpp
|
||||
src/main/cpp/MorphTargetBuffer.cpp
|
||||
src/main/cpp/RenderableManager.cpp
|
||||
src/main/cpp/Renderer.cpp
|
||||
src/main/cpp/RenderTarget.cpp
|
||||
@@ -81,6 +86,7 @@ add_library(filament-jni SHARED
|
||||
src/main/cpp/SwapChain.cpp
|
||||
src/main/cpp/Texture.cpp
|
||||
src/main/cpp/TextureSampler.cpp
|
||||
src/main/cpp/ToneMapper.cpp
|
||||
src/main/cpp/TransformManager.cpp
|
||||
src/main/cpp/VertexBuffer.cpp
|
||||
src/main/cpp/View.cpp
|
||||
@@ -111,6 +117,7 @@ target_link_libraries(filament-jni
|
||||
PUBLIC geometry
|
||||
|
||||
$<$<STREQUAL:${FILAMENT_ENABLE_MATDBG},ON>:matdbg>
|
||||
$<$<STREQUAL:${FILAMENT_ENABLE_MATDBG},ON>:filamat>
|
||||
$<$<STREQUAL:${FILAMENT_SUPPORTS_VULKAN},ON>:bluevk>
|
||||
$<$<STREQUAL:${FILAMENT_SUPPORTS_VULKAN},ON>:vkshaders>
|
||||
$<$<STREQUAL:${FILAMENT_SUPPORTS_VULKAN},ON>:smol-v>
|
||||
@@ -119,6 +126,7 @@ target_link_libraries(filament-jni
|
||||
target_include_directories(filament-jni PRIVATE
|
||||
..
|
||||
${FILAMENT_DIR}/include
|
||||
../../filament/backend/include
|
||||
../../third_party/robin-map
|
||||
../../libs/utils/include)
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ LIBFILAMENT {
|
||||
*filament*Renderer*;
|
||||
*filament*RenderTarget*;
|
||||
*filament*Scene*;
|
||||
*filament*ToneMapper*;
|
||||
*filament*Transform*;
|
||||
*filament*Material*;
|
||||
*filament*IndexBuffer*;
|
||||
|
||||
@@ -91,7 +91,8 @@ Java_com_google_android_filament_BufferObject_nSetBuffer(JNIEnv *env, jclass typ
|
||||
|
||||
auto* callback = JniBufferCallback::make(engine, env, handler, runnable, std::move(nioBuffer));
|
||||
|
||||
BufferDescriptor desc(data, sizeInBytes, &JniBufferCallback::invoke, callback);
|
||||
BufferDescriptor desc(data, sizeInBytes,
|
||||
callback->getHandler(), &JniBufferCallback::postToJavaAndDestroy, callback);
|
||||
|
||||
bufferObject->setBuffer(*engine, std::move(desc), (uint32_t) destOffsetInBytes);
|
||||
|
||||
|
||||
@@ -102,10 +102,19 @@ Java_com_google_android_filament_Camera_nSetModelMatrix(JNIEnv *env, jclass,
|
||||
jlong nativeCamera, jfloatArray in_) {
|
||||
Camera* camera = (Camera *) nativeCamera;
|
||||
jfloat *in = env->GetFloatArrayElements(in_, NULL);
|
||||
camera->setModelMatrix(*reinterpret_cast<const filament::math::mat4f*>(in));
|
||||
camera->setModelMatrix((math::mat4)*reinterpret_cast<const filament::math::mat4f*>(in));
|
||||
env->ReleaseFloatArrayElements(in_, in, JNI_ABORT);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Camera_nSetModelMatrixFp64(JNIEnv *env, jclass,
|
||||
jlong nativeCamera, jdoubleArray in_) {
|
||||
Camera* camera = (Camera *) nativeCamera;
|
||||
jdouble *in = env->GetDoubleArrayElements(in_, NULL);
|
||||
camera->setModelMatrix(*reinterpret_cast<const filament::math::mat4*>(in));
|
||||
env->ReleaseDoubleArrayElements(in_, in, JNI_ABORT);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Camera_nGetProjectionMatrix(JNIEnv *env, jclass,
|
||||
jlong nativeCamera, jdoubleArray out_) {
|
||||
@@ -141,21 +150,41 @@ Java_com_google_android_filament_Camera_nGetModelMatrix(JNIEnv *env, jclass,
|
||||
jlong nativeCamera, jfloatArray out_) {
|
||||
Camera *camera = (Camera *) nativeCamera;
|
||||
jfloat *out = env->GetFloatArrayElements(out_, NULL);
|
||||
const filament::math::mat4f& m = camera->getModelMatrix();
|
||||
const filament::math::mat4f& m = (math::mat4f)camera->getModelMatrix();
|
||||
std::copy_n(&m[0][0], 16, out);
|
||||
env->ReleaseFloatArrayElements(out_, out, 0);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Camera_nGetModelMatrixFp64(JNIEnv *env, jclass,
|
||||
jlong nativeCamera, jdoubleArray out_) {
|
||||
Camera *camera = (Camera *) nativeCamera;
|
||||
jdouble *out = env->GetDoubleArrayElements(out_, NULL);
|
||||
const filament::math::mat4& m = camera->getModelMatrix();
|
||||
std::copy_n(&m[0][0], 16, out);
|
||||
env->ReleaseDoubleArrayElements(out_, out, 0);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Camera_nGetViewMatrix(JNIEnv *env, jclass, jlong nativeCamera,
|
||||
jfloatArray out_) {
|
||||
Camera *camera = (Camera *) nativeCamera;
|
||||
jfloat *out = env->GetFloatArrayElements(out_, NULL);
|
||||
const filament::math::mat4f& m = camera->getViewMatrix();
|
||||
const filament::math::mat4f& m = (math::mat4f)camera->getViewMatrix();
|
||||
std::copy_n(&m[0][0], 16, out);
|
||||
env->ReleaseFloatArrayElements(out_, out, 0);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Camera_nGetViewMatrixFp64(JNIEnv *env, jclass, jlong nativeCamera,
|
||||
jdoubleArray out_) {
|
||||
Camera *camera = (Camera *) nativeCamera;
|
||||
jdouble *out = env->GetDoubleArrayElements(out_, NULL);
|
||||
const filament::math::mat4& m = camera->getViewMatrix();
|
||||
std::copy_n(&m[0][0], 16, out);
|
||||
env->ReleaseDoubleArrayElements(out_, out, 0);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Camera_nGetPosition(JNIEnv *env, jclass, jlong nativeCamera,
|
||||
jfloatArray out_) {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <jni.h>
|
||||
|
||||
#include <filament/ColorGrading.h>
|
||||
#include <filament/ToneMapper.h>
|
||||
|
||||
#include <math/vec3.h>
|
||||
#include <math/vec4.h>
|
||||
@@ -30,28 +31,48 @@ Java_com_google_android_filament_ColorGrading_nCreateBuilder(JNIEnv*, jclass) {
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ColorGrading_nDestroyBuilder(JNIEnv*, jclass,
|
||||
jlong nativeBuilder) {
|
||||
Java_com_google_android_filament_ColorGrading_nDestroyBuilder(JNIEnv*, jclass, jlong nativeBuilder) {
|
||||
ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder;
|
||||
delete builder;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_ColorGrading_nBuilderBuild(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jlong nativeEngine) {
|
||||
Java_com_google_android_filament_ColorGrading_nBuilderBuild(JNIEnv*, jclass, jlong nativeBuilder, jlong nativeEngine) {
|
||||
ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
return (jlong) builder->build(*engine);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ColorGrading_nBuilderQuality(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jint quality_) {
|
||||
Java_com_google_android_filament_ColorGrading_nBuilderQuality(JNIEnv*, jclass, jlong nativeBuilder, jint quality_) {
|
||||
ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder;
|
||||
ColorGrading::QualityLevel quality = (ColorGrading::QualityLevel) quality_;
|
||||
builder->quality(quality);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ColorGrading_nBuilderFormat(JNIEnv*, jclass, jlong nativeBuilder, jint format_) {
|
||||
ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder;
|
||||
ColorGrading::LutFormat format = (ColorGrading::LutFormat) format_;
|
||||
builder->format(format);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ColorGrading_nBuilderDimensions(JNIEnv*, jclass, jlong nativeBuilder, jint dim_) {
|
||||
ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder;
|
||||
builder->dimensions((uint8_t)dim_);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ColorGrading_nBuilderToneMapper(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jlong toneMapper_) {
|
||||
ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder;
|
||||
const ToneMapper* toneMapper = (const ToneMapper*) toneMapper_;
|
||||
builder->toneMapper(toneMapper);
|
||||
}
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ColorGrading_nBuilderToneMapping(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jint toneMapping_) {
|
||||
@@ -59,6 +80,7 @@ Java_com_google_android_filament_ColorGrading_nBuilderToneMapping(JNIEnv*, jclas
|
||||
ColorGrading::ToneMapping toneMapping = (ColorGrading::ToneMapping) toneMapping_;
|
||||
builder->toneMapping(toneMapping);
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ColorGrading_nBuilderLuminanceScaling(JNIEnv*, jclass,
|
||||
@@ -67,6 +89,13 @@ Java_com_google_android_filament_ColorGrading_nBuilderLuminanceScaling(JNIEnv*,
|
||||
builder->luminanceScaling(luminanceScaling);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ColorGrading_nBuilderGamutMapping(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jboolean gamutMapping) {
|
||||
ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder;
|
||||
builder->gamutMapping(gamutMapping);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ColorGrading_nBuilderExposure(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jfloat exposure) {
|
||||
@@ -74,6 +103,13 @@ Java_com_google_android_filament_ColorGrading_nBuilderExposure(JNIEnv*, jclass,
|
||||
builder->exposure(exposure);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ColorGrading_nBuilderNightAdaptation(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jfloat adaptation) {
|
||||
ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder;
|
||||
builder->nightAdaptation(adaptation);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ColorGrading_nBuilderWhiteBalance(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jfloat temperature, jfloat tint) {
|
||||
|
||||
@@ -45,12 +45,11 @@ extern "C" {
|
||||
// handle. Whatever object is returned from this method must match what is in
|
||||
// folder filament/src/driver/opengl/Context* in particular pay attention to
|
||||
// the object type in makeCurrent method.
|
||||
extern void *getNativeWindow(JNIEnv *env, jclass, jobject surface);
|
||||
extern void* getNativeWindow(JNIEnv* env, jclass, jobject surface);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_Engine_nGetBackend(JNIEnv* env,
|
||||
jclass klass, jlong nativeEngine) {
|
||||
Java_com_google_android_filament_Engine_nGetBackend(JNIEnv*, jclass, jlong nativeEngine) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
return (jlong) engine->getBackend();
|
||||
}
|
||||
@@ -64,8 +63,8 @@ Java_com_google_android_filament_Engine_nCreateSwapChain(JNIEnv* env,
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_Engine_nCreateSwapChainHeadless(JNIEnv* env,
|
||||
jclass klass, jlong nativeEngine, jint width, jint height, jlong flags) {
|
||||
Java_com_google_android_filament_Engine_nCreateSwapChainHeadless(JNIEnv*,
|
||||
jclass, jlong nativeEngine, jint width, jint height, jlong flags) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
return (jlong) engine->createSwapChain(width, height, (uint64_t) flags);
|
||||
}
|
||||
@@ -81,7 +80,7 @@ extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Engine_nDestroySwapChain(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeSwapChain) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
SwapChain *swapChain = (SwapChain *) nativeSwapChain;
|
||||
SwapChain* swapChain = (SwapChain*) nativeSwapChain;
|
||||
return engine->destroy(swapChain);
|
||||
}
|
||||
|
||||
@@ -98,7 +97,7 @@ extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Engine_nDestroyView(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeView) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
View *view = (View *) nativeView;
|
||||
View* view = (View*) nativeView;
|
||||
return engine->destroy(view);
|
||||
}
|
||||
|
||||
@@ -115,7 +114,7 @@ extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Engine_nDestroyRenderer(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeRenderer) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
Renderer *renderer = (Renderer *) nativeRenderer;
|
||||
Renderer* renderer = (Renderer*) nativeRenderer;
|
||||
return engine->destroy(renderer);
|
||||
}
|
||||
|
||||
@@ -158,7 +157,7 @@ extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Engine_nDestroyScene(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeScene) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
Scene *scene = (Scene *) nativeScene;
|
||||
Scene* scene = (Scene*) nativeScene;
|
||||
return engine->destroy(scene);
|
||||
}
|
||||
|
||||
@@ -175,7 +174,7 @@ extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Engine_nDestroyFence(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeFence) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
Fence *fence = (Fence *) nativeFence;
|
||||
Fence* fence = (Fence*) nativeFence;
|
||||
return engine->destroy(fence);
|
||||
}
|
||||
|
||||
@@ -185,7 +184,7 @@ extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Engine_nDestroyStream(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeStream) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
Stream *stream = (Stream *) nativeStream;
|
||||
Stream* stream = (Stream*) nativeStream;
|
||||
return engine->destroy(stream);
|
||||
}
|
||||
|
||||
@@ -195,7 +194,7 @@ extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Engine_nDestroyIndexBuffer(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeIndexBuffer) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
IndexBuffer *indexBuffer = (IndexBuffer *) nativeIndexBuffer;
|
||||
IndexBuffer* indexBuffer = (IndexBuffer*) nativeIndexBuffer;
|
||||
return engine->destroy(indexBuffer);
|
||||
}
|
||||
|
||||
@@ -203,15 +202,23 @@ extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Engine_nDestroyVertexBuffer(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeVertexBuffer) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
VertexBuffer *vertexBuffer = (VertexBuffer *) nativeVertexBuffer;
|
||||
VertexBuffer* vertexBuffer = (VertexBuffer*) nativeVertexBuffer;
|
||||
return engine->destroy(vertexBuffer);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Engine_nDestroySkinningBuffer(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeSkinningBuffer) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
SkinningBuffer* skinningBuffer = (SkinningBuffer*) nativeSkinningBuffer;
|
||||
return engine->destroy(skinningBuffer);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Engine_nDestroyIndirectLight(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeIndirectLight) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
IndirectLight *indirectLight = (IndirectLight *) nativeIndirectLight;
|
||||
IndirectLight* indirectLight = (IndirectLight*) nativeIndirectLight;
|
||||
return engine->destroy(indirectLight);
|
||||
}
|
||||
|
||||
@@ -219,7 +226,7 @@ extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Engine_nDestroyMaterial(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeMaterial) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
Material *material = (Material *) nativeMaterial;
|
||||
Material* material = (Material*) nativeMaterial;
|
||||
return engine->destroy(material);
|
||||
}
|
||||
|
||||
@@ -235,7 +242,7 @@ extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Engine_nDestroySkybox(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeSkybox) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
Skybox *skybox = (Skybox *) nativeSkybox;
|
||||
Skybox* skybox = (Skybox*) nativeSkybox;
|
||||
return engine->destroy(skybox);
|
||||
}
|
||||
|
||||
@@ -251,7 +258,7 @@ extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Engine_nDestroyTexture(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeTexture) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
Texture *texture = (Texture *) nativeTexture;
|
||||
Texture* texture = (Texture*) nativeTexture;
|
||||
return engine->destroy(texture);
|
||||
}
|
||||
|
||||
@@ -272,7 +279,7 @@ Java_com_google_android_filament_Engine_nDestroyEntity(JNIEnv*, jclass,
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Engine_nFlushAndWait(JNIEnv *env, jclass clazz,
|
||||
Java_com_google_android_filament_Engine_nFlushAndWait(JNIEnv*, jclass,
|
||||
jlong nativeEngine) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
engine->flushAndWait();
|
||||
@@ -281,22 +288,19 @@ Java_com_google_android_filament_Engine_nFlushAndWait(JNIEnv *env, jclass clazz,
|
||||
// Managers...
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_Engine_nGetTransformManager(JNIEnv*, jclass,
|
||||
jlong nativeEngine) {
|
||||
Java_com_google_android_filament_Engine_nGetTransformManager(JNIEnv*, jclass, jlong nativeEngine) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
return (jlong) &engine->getTransformManager();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_Engine_nGetLightManager(JNIEnv*, jclass,
|
||||
jlong nativeEngine) {
|
||||
Java_com_google_android_filament_Engine_nGetLightManager(JNIEnv*, jclass, jlong nativeEngine) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
return (jlong) &engine->getLightManager();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_Engine_nGetRenderableManager(JNIEnv*, jclass,
|
||||
jlong nativeEngine) {
|
||||
Java_com_google_android_filament_Engine_nGetRenderableManager(JNIEnv*, jclass, jlong nativeEngine) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
return (jlong) &engine->getRenderableManager();
|
||||
}
|
||||
|
||||
@@ -16,9 +16,7 @@
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
namespace filament {
|
||||
extern jint JNI_OnLoad(JavaVM* vm, void* reserved);
|
||||
};
|
||||
#include "private/backend/VirtualMachineEnv.h"
|
||||
|
||||
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||
JNIEnv* env;
|
||||
@@ -26,9 +24,9 @@ JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if ANDROID
|
||||
::filament::JNI_OnLoad(vm, reserved);
|
||||
#endif
|
||||
// This must be called when the library is loaded. We need this to get a reference to the
|
||||
// global VM
|
||||
::filament::VirtualMachineEnv::JNI_OnLoad(vm);
|
||||
|
||||
return JNI_VERSION_1_6;
|
||||
}
|
||||
|
||||
@@ -91,7 +91,8 @@ Java_com_google_android_filament_IndexBuffer_nSetBuffer(JNIEnv *env, jclass type
|
||||
|
||||
auto* callback = JniBufferCallback::make(engine, env, handler, runnable, std::move(nioBuffer));
|
||||
|
||||
BufferDescriptor desc(data, sizeInBytes, &JniBufferCallback::invoke, callback);
|
||||
BufferDescriptor desc(data, sizeInBytes,
|
||||
callback->getHandler(), &JniBufferCallback::postToJavaAndDestroy, callback);
|
||||
|
||||
indexBuffer->setBuffer(*engine, std::move(desc), (uint32_t) destOffsetInBytes);
|
||||
|
||||
|
||||
@@ -76,8 +76,10 @@ extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_LightManager_nBuilderShadowOptions(JNIEnv* env, jclass,
|
||||
jlong nativeBuilder, jint mapSize, jint cascades, jfloatArray splitPositions,
|
||||
jfloat constantBias, jfloat normalBias, jfloat shadowFar, jfloat shadowNearHint,
|
||||
jfloat shadowFarHint, jboolean stable, jboolean screenSpaceContactShadows, jint stepCount,
|
||||
jfloat maxShadowDistance, jint vsmMsaaSamples, jfloat blurWidth) {
|
||||
jfloat shadowFarHint, jboolean stable,
|
||||
jfloat polygonOffsetConstant, jfloat polygonOffsetSlope,
|
||||
jboolean screenSpaceContactShadows, jint stepCount,
|
||||
jfloat maxShadowDistance, jint vsmMsaaSamples, jfloat blurWidth, jfloat shadowBulbRadius) {
|
||||
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
|
||||
LightManager::ShadowOptions shadowOptions {
|
||||
.mapSize = (uint32_t)mapSize,
|
||||
@@ -88,13 +90,16 @@ Java_com_google_android_filament_LightManager_nBuilderShadowOptions(JNIEnv* env,
|
||||
.shadowNearHint = shadowNearHint,
|
||||
.shadowFarHint = shadowFarHint,
|
||||
.stable = (bool)stable,
|
||||
.polygonOffsetConstant = polygonOffsetConstant,
|
||||
.polygonOffsetSlope = polygonOffsetConstant,
|
||||
.screenSpaceContactShadows = (bool)screenSpaceContactShadows,
|
||||
.stepCount = uint8_t(stepCount),
|
||||
.maxShadowDistance = maxShadowDistance,
|
||||
.vsm = {
|
||||
.msaaSamples = (uint8_t) vsmMsaaSamples,
|
||||
.blurWidth = blurWidth
|
||||
}
|
||||
},
|
||||
.shadowBulbRadius = shadowBulbRadius
|
||||
};
|
||||
jfloat *nativeSplits = env->GetFloatArrayElements(splitPositions, NULL);
|
||||
const jsize splitCount = std::min((jsize) 3, env->GetArrayLength(splitPositions));
|
||||
@@ -189,6 +194,23 @@ Java_com_google_android_filament_LightManager_nBuilderHaloFalloff(JNIEnv*, jclas
|
||||
builder->sunHaloFalloff(haloFalloff);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_LightManager_nBuilderLightChannel(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jint channel, jboolean enable) {
|
||||
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
|
||||
builder->lightChannel(channel, (bool)enable);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_LightManager_nBuilderBuild(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jlong nativeEngine, jint entity) {
|
||||
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
return jboolean(builder->build(*engine, (Entity &) entity) == LightManager::Builder::Success);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_LightManager_nComputeUniformSplits(JNIEnv* env, jclass,
|
||||
jfloatArray splitPositions, jint cascades) {
|
||||
@@ -213,13 +235,7 @@ Java_com_google_android_filament_LightManager_nComputePracticalSplits(JNIEnv* en
|
||||
env->ReleaseFloatArrayElements(splitPositions, nativeSplits, 0);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_LightManager_nBuilderBuild(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jlong nativeEngine, jint entity) {
|
||||
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
return jboolean(builder->build(*engine, (Entity &) entity) == LightManager::Builder::Success);
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_LightManager_nGetType(JNIEnv* env,
|
||||
@@ -394,3 +410,17 @@ Java_com_google_android_filament_LightManager_nGetInnerConeAngle(JNIEnv*, jclass
|
||||
LightManager *lm = (LightManager *) nativeLightManager;
|
||||
return (jfloat)lm->getSpotLightInnerCone((LightManager::Instance) i);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_LightManager_nSetLightChannel(JNIEnv*, jclass,
|
||||
jlong nativeLightManager, jint i, jint channel, jboolean enable) {
|
||||
LightManager *lm = (LightManager *) nativeLightManager;
|
||||
lm->setLightChannel((LightManager::Instance) i, channel, (bool)enable);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_LightManager_nGetLightChannel(JNIEnv*, jclass,
|
||||
jlong nativeLightManager, jint i, jint channel) {
|
||||
LightManager const *lm = (LightManager const *) nativeLightManager;
|
||||
return lm->getLightChannel((LightManager::Instance) i, channel);
|
||||
}
|
||||
|
||||
114
android/filament-android/src/main/cpp/MorphTargetBuffer.cpp
Normal file
114
android/filament-android/src/main/cpp/MorphTargetBuffer.cpp
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* 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/MorphTargetBuffer.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_MorphTargetBuffer_nCreateBuilder(JNIEnv*, jclass) {
|
||||
return (jlong) new MorphTargetBuffer::Builder();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_MorphTargetBuffer_nDestroyBuilder(JNIEnv*, jclass,
|
||||
jlong nativeBuilder) {
|
||||
MorphTargetBuffer::Builder* builder = (MorphTargetBuffer::Builder *) nativeBuilder;
|
||||
delete builder;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_MorphTargetBuffer_nBuilderVertexCount(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jint vertexCount) {
|
||||
MorphTargetBuffer::Builder* builder = (MorphTargetBuffer::Builder *) nativeBuilder;
|
||||
builder->vertexCount((size_t) vertexCount);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_MorphTargetBuffer_nBuilderCount(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jint count) {
|
||||
MorphTargetBuffer::Builder* builder = (MorphTargetBuffer::Builder *) nativeBuilder;
|
||||
builder->count((size_t) count);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_MorphTargetBuffer_nBuilderBuild(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jlong nativeEngine) {
|
||||
MorphTargetBuffer::Builder* builder = (MorphTargetBuffer::Builder *) nativeBuilder;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
return (jlong) builder->build(*engine);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_MorphTargetBuffer_nSetPositionsAt(JNIEnv* env, jclass,
|
||||
jlong nativeObject, jlong nativeEngine,
|
||||
jint targetIndex, jfloatArray positions, jint count) {
|
||||
MorphTargetBuffer *morphTargetBuffer = (MorphTargetBuffer *) nativeObject;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
jfloat* data = env->GetFloatArrayElements(positions, NULL);
|
||||
morphTargetBuffer->setPositionsAt(*engine, targetIndex,
|
||||
(math::float4*) data, size_t(count));
|
||||
env->ReleaseFloatArrayElements(positions, data, JNI_ABORT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_MorphTargetBuffer_nSetTangentsAt(JNIEnv* env, jclass,
|
||||
jlong nativeObject, jlong nativeEngine,
|
||||
jint targetIndex, jshortArray tangents, jint count) {
|
||||
MorphTargetBuffer *morphTargetBuffer = (MorphTargetBuffer *) nativeObject;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
jshort* data = env->GetShortArrayElements(tangents, NULL);
|
||||
morphTargetBuffer->setTangentsAt(*engine, targetIndex,
|
||||
(math::short4*) data, size_t(count));
|
||||
env->ReleaseShortArrayElements(tangents, data, JNI_ABORT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_MorphTargetBuffer_nGetVertexCount(JNIEnv*, jclass,
|
||||
jlong nativeObject) {
|
||||
MorphTargetBuffer *morphTargetBuffer = (MorphTargetBuffer *) nativeObject;
|
||||
return (jint)morphTargetBuffer->getVertexCount();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_MorphTargetBuffer_nGetCount(JNIEnv*, jclass,
|
||||
jlong nativeObject) {
|
||||
MorphTargetBuffer *morphTargetBuffer = (MorphTargetBuffer *) nativeObject;
|
||||
return (jint)morphTargetBuffer->getCount();
|
||||
}
|
||||
@@ -209,11 +209,36 @@ Java_com_google_android_filament_RenderableManager_nBuilderSkinningBones(JNIEnv*
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nBuilderMorphing(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jboolean enabled) {
|
||||
jlong nativeBuilder, jint targetCount) {
|
||||
RenderableManager::Builder *builder = (RenderableManager::Builder *) nativeBuilder;
|
||||
builder->morphing(enabled);
|
||||
builder->morphing(targetCount);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nBuilderSetMorphTargetBufferAt(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, int level, int primitiveIndex, jlong nativeMorphTargetBuffer,
|
||||
int offset, int count) {
|
||||
RenderableManager::Builder *builder = (RenderableManager::Builder *) nativeBuilder;
|
||||
MorphTargetBuffer *morphTargetBuffer = (MorphTargetBuffer *) nativeMorphTargetBuffer;
|
||||
builder->morphing(level, primitiveIndex, morphTargetBuffer, offset, count);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nBuilderLightChannel(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jint channel, jboolean enable) {
|
||||
RenderableManager::Builder *builder = (RenderableManager::Builder *) nativeBuilder;
|
||||
builder->lightChannel(channel, (bool)enable);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nBuilderInstances(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jint instanceCount) {
|
||||
RenderableManager::Builder *builder = (RenderableManager::Builder *) nativeBuilder;
|
||||
builder->instances(instanceCount);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nSetSkinningBuffer(JNIEnv*, jclass,
|
||||
jlong nativeRenderableManager, jint i, jlong nativeSkinningBuffer, jint count, jint offset) {
|
||||
@@ -258,12 +283,29 @@ Java_com_google_android_filament_RenderableManager_nSetBonesAsQuaternions(JNIEnv
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nSetMorphWeights(JNIEnv* env, jclass,
|
||||
jlong nativeRenderableManager, jint instance, jfloatArray weights) {
|
||||
jlong nativeRenderableManager, jint instance, jfloatArray weights, jint offset) {
|
||||
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
|
||||
jfloat* vec = env->GetFloatArrayElements(weights, NULL);
|
||||
math::float4 floatvec(vec[0], vec[1], vec[2], vec[3]);
|
||||
jsize count = env->GetArrayLength(weights);
|
||||
rm->setMorphWeights((RenderableManager::Instance)instance, vec, count, offset);
|
||||
env->ReleaseFloatArrayElements(weights, vec, JNI_ABORT);
|
||||
rm->setMorphWeights((RenderableManager::Instance)instance, floatvec);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nSetMorphTargetBufferAt(JNIEnv*,
|
||||
jclass, jlong nativeRenderableManager, jint i, int level, jint primitiveIndex,
|
||||
jlong nativeMorphTargetBuffer, jint offset, jint count) {
|
||||
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
|
||||
MorphTargetBuffer *morphTargetBuffer = (MorphTargetBuffer *) nativeMorphTargetBuffer;
|
||||
rm->setMorphTargetBufferAt((RenderableManager::Instance) i, (uint8_t) level,
|
||||
(size_t) primitiveIndex, morphTargetBuffer, (size_t) offset, (size_t) count);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nGetMorphTargetCount(JNIEnv* env, jclass,
|
||||
jlong nativeRenderableManager, jint instance) {
|
||||
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
|
||||
return rm->getMorphTargetCount((RenderableManager::Instance)instance);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
@@ -404,3 +446,17 @@ Java_com_google_android_filament_RenderableManager_nGetEnabledAttributesAt(JNIEn
|
||||
AttributeBitset enabled = rm->getEnabledAttributesAt((RenderableManager::Instance) i, (size_t) primitiveIndex);
|
||||
return enabled.getValue();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nSetLightChannel(JNIEnv*, jclass,
|
||||
jlong nativeRenderableManager, jint i, jint channel, jboolean enable) {
|
||||
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
|
||||
rm->setLightChannel((RenderableManager::Instance) i, channel, (bool)enable);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nGetLightChannel(JNIEnv*, jclass,
|
||||
jlong nativeRenderableManager, jint i, jint channel) {
|
||||
RenderableManager const *rm = (RenderableManager const *) nativeRenderableManager;
|
||||
return rm->getLightChannel((RenderableManager::Instance) i, channel);
|
||||
}
|
||||
|
||||
@@ -97,7 +97,8 @@ Java_com_google_android_filament_Renderer_nReadPixels(JNIEnv *env, jclass,
|
||||
|
||||
PixelBufferDescriptor desc(buffer, sizeInBytes, (backend::PixelDataFormat) format,
|
||||
(backend::PixelDataType) type, (uint8_t) alignment, (uint32_t) left, (uint32_t) top,
|
||||
(uint32_t) stride, &JniBufferCallback::invoke, callback);
|
||||
(uint32_t) stride,
|
||||
callback->getHandler(), &JniBufferCallback::postToJavaAndDestroy, callback);
|
||||
|
||||
renderer->readPixels(uint32_t(xoffset), uint32_t(yoffset), uint32_t(width), uint32_t(height),
|
||||
std::move(desc));
|
||||
@@ -132,7 +133,8 @@ Java_com_google_android_filament_Renderer_nReadPixelsEx(JNIEnv *env, jclass,
|
||||
|
||||
PixelBufferDescriptor desc(buffer, sizeInBytes, (backend::PixelDataFormat) format,
|
||||
(backend::PixelDataType) type, (uint8_t) alignment, (uint32_t) left, (uint32_t) top,
|
||||
(uint32_t) stride, &JniBufferCallback::invoke, callback);
|
||||
(uint32_t) stride,
|
||||
callback->getHandler(), &JniBufferCallback::postToJavaAndDestroy, callback);
|
||||
|
||||
renderer->readPixels(renderTarget,
|
||||
uint32_t(xoffset), uint32_t(yoffset), uint32_t(width), uint32_t(height),
|
||||
|
||||
@@ -100,7 +100,7 @@ Java_com_google_android_filament_Skybox_nSetColor(JNIEnv *, jclass,
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_Skybix_nGetTexture(JNIEnv* env, jclass,
|
||||
Java_com_google_android_filament_Skybox_nGetTexture(JNIEnv* env, jclass,
|
||||
jlong nativeSkybox) {
|
||||
Skybox *skybox = (Skybox *) nativeSkybox;
|
||||
Texture const *tex = skybox->getTexture();
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include "common/NioUtils.h"
|
||||
#include "common/CallbackUtils.h"
|
||||
|
||||
#ifdef ANDROID
|
||||
#ifdef __ANDROID__
|
||||
|
||||
#if __has_include(<android/hardware_buffer_jni.h>)
|
||||
#include <android/hardware_buffer_jni.h>
|
||||
@@ -169,7 +169,8 @@ Java_com_google_android_filament_Stream_nReadPixels(JNIEnv *env, jclass,
|
||||
|
||||
PixelBufferDescriptor desc(buffer, sizeInBytes, (backend::PixelDataFormat) format,
|
||||
(backend::PixelDataType) type, (uint8_t) alignment, (uint32_t) left, (uint32_t) top,
|
||||
(uint32_t) stride, &JniBufferCallback::invoke, callback);
|
||||
(uint32_t) stride,
|
||||
callback->getHandler(), &JniBufferCallback::postToJavaAndDestroy, callback);
|
||||
|
||||
stream->readPixels(uint32_t(xoffset), uint32_t(yoffset), uint32_t(width), uint32_t(height),
|
||||
std::move(desc));
|
||||
@@ -189,7 +190,7 @@ Java_com_google_android_filament_Stream_nSetAcquiredImage(JNIEnv* env, jclass, j
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
Stream* stream = (Stream*) nativeStream;
|
||||
|
||||
#ifdef ANDROID
|
||||
#ifdef __ANDROID__
|
||||
|
||||
// This function is not available before NDK 15 or before Android 8.
|
||||
if (UTILS_UNLIKELY(!AHardwareBuffer_fromHardwareBuffer_fn)) {
|
||||
@@ -200,8 +201,8 @@ Java_com_google_android_filament_Stream_nSetAcquiredImage(JNIEnv* env, jclass, j
|
||||
if (!AHardwareBuffer_fromHardwareBuffer_fn) {
|
||||
__android_log_print(ANDROID_LOG_WARN, "Filament", "AHardwareBuffer_fromHardwareBuffer is not available.");
|
||||
sHardwareBufferSupported = false;
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
AHardwareBuffer* nativeBuffer = AHardwareBuffer_fromHardwareBuffer_fn(env, hwbuffer);
|
||||
@@ -221,5 +222,6 @@ Java_com_google_android_filament_Stream_nSetAcquiredImage(JNIEnv* env, jclass, j
|
||||
|
||||
#endif
|
||||
|
||||
stream->setAcquiredImage((void*) nativeBuffer, &JniImageCallback::invoke, callback);
|
||||
stream->setAcquiredImage((void*) nativeBuffer,
|
||||
callback->getHandler(), &JniImageCallback::postToJavaAndDestroy, callback);
|
||||
}
|
||||
|
||||
@@ -27,5 +27,8 @@ Java_com_google_android_filament_SwapChain_nSetFrameCompletedCallback(JNIEnv* en
|
||||
jlong nativeSwapChain, jobject handler, jobject runnable) {
|
||||
SwapChain* swapChain = (SwapChain*) nativeSwapChain;
|
||||
auto *callback = JniCallback::make(env, handler, runnable);
|
||||
swapChain->setFrameCompletedCallback(&JniCallback::invoke, callback);
|
||||
swapChain->setFrameCompletedCallback([](void* user) {
|
||||
JniCallback* callback = (JniCallback*)user;
|
||||
JniCallback::postToJavaAndDestroy(callback);
|
||||
}, callback);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
|
||||
#ifdef ANDROID
|
||||
#ifdef __ANDROID__
|
||||
#include <android/bitmap.h>
|
||||
#endif
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
#include "common/CallbackUtils.h"
|
||||
#include "common/NioUtils.h"
|
||||
|
||||
#include "private/backend/VirtualMachineEnv.h"
|
||||
|
||||
using namespace filament;
|
||||
using namespace backend;
|
||||
|
||||
@@ -210,7 +212,8 @@ Java_com_google_android_filament_Texture_nSetImage(JNIEnv* env, jclass, jlong na
|
||||
|
||||
Texture::PixelBufferDescriptor desc(buffer, sizeInBytes, (backend::PixelDataFormat) format,
|
||||
(backend::PixelDataType) type, (uint8_t) alignment, (uint32_t) left, (uint32_t) top,
|
||||
(uint32_t) stride, &JniBufferCallback::invoke, callback);
|
||||
(uint32_t) stride,
|
||||
callback->getHandler(), &JniBufferCallback::postToJavaAndDestroy, callback);
|
||||
|
||||
texture->setImage(*engine, (size_t) level, (uint32_t) xoffset, (uint32_t) yoffset,
|
||||
(uint32_t) width, (uint32_t) height, std::move(desc));
|
||||
@@ -240,7 +243,7 @@ Java_com_google_android_filament_Texture_nSetImageCompressed(JNIEnv *env, jclass
|
||||
|
||||
Texture::PixelBufferDescriptor desc(buffer, sizeInBytes,
|
||||
(backend::CompressedPixelDataType) compressedFormat, (uint32_t) compressedSizeInBytes,
|
||||
&JniBufferCallback::invoke, callback);
|
||||
callback->getHandler(), &JniBufferCallback::postToJavaAndDestroy, callback);
|
||||
|
||||
texture->setImage(*engine, (size_t) level, (uint32_t) xoffset, (uint32_t) yoffset,
|
||||
(uint32_t) width, (uint32_t) height, std::move(desc));
|
||||
@@ -274,7 +277,8 @@ Java_com_google_android_filament_Texture_nSetImage3D(JNIEnv* env, jclass, jlong
|
||||
|
||||
Texture::PixelBufferDescriptor desc(buffer, sizeInBytes, (backend::PixelDataFormat) format,
|
||||
(backend::PixelDataType) type, (uint8_t) alignment, (uint32_t) left, (uint32_t) top,
|
||||
(uint32_t) stride, &JniBufferCallback::invoke, callback);
|
||||
(uint32_t) stride,
|
||||
callback->getHandler(), &JniBufferCallback::postToJavaAndDestroy, callback);
|
||||
|
||||
texture->setImage(*engine, (size_t) level,
|
||||
(uint32_t) xoffset, (uint32_t) yoffset, (uint32_t) zoffset,
|
||||
@@ -308,7 +312,7 @@ Java_com_google_android_filament_Texture_nSetImage3DCompressed(JNIEnv *env, jcla
|
||||
|
||||
Texture::PixelBufferDescriptor desc(buffer, sizeInBytes,
|
||||
(backend::CompressedPixelDataType) compressedFormat, (uint32_t) compressedSizeInBytes,
|
||||
&JniBufferCallback::invoke, callback);
|
||||
callback->getHandler(), &JniBufferCallback::postToJavaAndDestroy, callback);
|
||||
|
||||
texture->setImage(*engine, (size_t) level,
|
||||
(uint32_t) xoffset, (uint32_t) yoffset, (uint32_t) zoffset,
|
||||
@@ -346,7 +350,8 @@ Java_com_google_android_filament_Texture_nSetImageCubemap(JNIEnv *env, jclass,
|
||||
|
||||
Texture::PixelBufferDescriptor desc(buffer, sizeInBytes, (backend::PixelDataFormat) format,
|
||||
(backend::PixelDataType) type, (uint8_t) alignment, (uint32_t) left, (uint32_t) top,
|
||||
(uint32_t) stride, &JniBufferCallback::invoke, callback);
|
||||
(uint32_t) stride,
|
||||
callback->getHandler(), &JniBufferCallback::postToJavaAndDestroy, callback);
|
||||
|
||||
texture->setImage(*engine, (size_t) level, std::move(desc), faceOffsets);
|
||||
|
||||
@@ -381,7 +386,7 @@ Java_com_google_android_filament_Texture_nSetImageCubemapCompressed(JNIEnv *env,
|
||||
|
||||
Texture::PixelBufferDescriptor desc(buffer, sizeInBytes,
|
||||
(backend::CompressedPixelDataType) compressedFormat, (uint32_t) compressedSizeInBytes,
|
||||
&JniBufferCallback::invoke, callback);
|
||||
callback->getHandler(), &JniBufferCallback::postToJavaAndDestroy, callback);
|
||||
|
||||
texture->setImage(*engine, (size_t) level, std::move(desc), faceOffsets);
|
||||
|
||||
@@ -454,7 +459,7 @@ Java_com_google_android_filament_Texture_nGeneratePrefilterMipmap(JNIEnv *env, j
|
||||
Texture::PixelBufferDescriptor desc(buffer, sizeInBytes, (backend::PixelDataFormat) format,
|
||||
(backend::PixelDataType) type, (uint8_t) alignment,
|
||||
(uint32_t) left, (uint32_t) top, (uint32_t) stride,
|
||||
&JniBufferCallback::invoke, callback);
|
||||
callback->getHandler(), &JniBufferCallback::postToJavaAndDestroy, callback);
|
||||
|
||||
Texture::PrefilterOptions options;
|
||||
options.sampleCount = sampleCount;
|
||||
@@ -468,7 +473,7 @@ Java_com_google_android_filament_Texture_nGeneratePrefilterMipmap(JNIEnv *env, j
|
||||
// ANDROID SPECIFIC BITS
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef ANDROID
|
||||
#ifdef __ANDROID__
|
||||
|
||||
#define BITMAP_CONFIG_ALPHA_8 0
|
||||
#define BITMAP_CONFIG_RGB_565 1
|
||||
@@ -477,46 +482,37 @@ Java_com_google_android_filament_Texture_nGeneratePrefilterMipmap(JNIEnv *env, j
|
||||
#define BITMAP_CONFIG_RGBA_F16 4
|
||||
#define BITMAP_CONFIG_HARDWARE 5
|
||||
|
||||
class AutoBitmap {
|
||||
public:
|
||||
class AutoBitmap : public JniCallback {
|
||||
private:
|
||||
|
||||
AutoBitmap(JNIEnv* env, jobject bitmap) noexcept
|
||||
: mEnv(env)
|
||||
, mBitmap(env->NewGlobalRef(bitmap))
|
||||
{
|
||||
: JniCallback(),
|
||||
mBitmap(env->NewGlobalRef(bitmap)) {
|
||||
if (mBitmap) {
|
||||
AndroidBitmap_getInfo(mEnv, mBitmap, &mInfo);
|
||||
AndroidBitmap_lockPixels(mEnv, mBitmap, &mData);
|
||||
AndroidBitmap_getInfo(env, mBitmap, &mInfo);
|
||||
AndroidBitmap_lockPixels(env, mBitmap, &mData);
|
||||
}
|
||||
}
|
||||
|
||||
AutoBitmap(JNIEnv* env, jobject bitmap, jobject handler, jobject runnable) noexcept
|
||||
: mEnv(env)
|
||||
, mBitmap(env->NewGlobalRef(bitmap))
|
||||
, mHandler(env->NewGlobalRef(handler))
|
||||
, mCallback(env->NewGlobalRef(runnable))
|
||||
{
|
||||
acquireCallbackJni(env, mCallbackUtils);
|
||||
: JniCallback(env, handler, runnable),
|
||||
mBitmap(env->NewGlobalRef(bitmap)) {
|
||||
if (mBitmap) {
|
||||
AndroidBitmap_getInfo(mEnv, mBitmap, &mInfo);
|
||||
AndroidBitmap_lockPixels(mEnv, mBitmap, &mData);
|
||||
AndroidBitmap_getInfo(env, mBitmap, &mInfo);
|
||||
AndroidBitmap_lockPixels(env, mBitmap, &mData);
|
||||
}
|
||||
}
|
||||
|
||||
~AutoBitmap() noexcept {
|
||||
releaseCallbackJni(mEnv, mCallbackUtils, mHandler, mCallback);
|
||||
void release(JNIEnv* env) {
|
||||
if (mBitmap) {
|
||||
AndroidBitmap_unlockPixels(mEnv, mBitmap);
|
||||
mEnv->DeleteGlobalRef(mBitmap);
|
||||
AndroidBitmap_unlockPixels(env, mBitmap);
|
||||
env->DeleteGlobalRef(mBitmap);
|
||||
}
|
||||
}
|
||||
|
||||
AutoBitmap(AutoBitmap &&rhs) noexcept {
|
||||
mEnv = rhs.mEnv;
|
||||
std::swap(mData, rhs.mData);
|
||||
std::swap(mBitmap, rhs.mBitmap);
|
||||
std::swap(mInfo, rhs.mInfo);
|
||||
}
|
||||
~AutoBitmap() override = default;
|
||||
|
||||
public:
|
||||
void* getData() const noexcept {
|
||||
return mData;
|
||||
}
|
||||
@@ -543,28 +539,39 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
static void invoke(void* buffer, size_t n, void* user) {
|
||||
AutoBitmap* data = reinterpret_cast<AutoBitmap*>(user);
|
||||
delete data;
|
||||
}
|
||||
|
||||
static AutoBitmap* make(Engine* engine, JNIEnv* env, jobject bitmap) {
|
||||
return new AutoBitmap(env, bitmap);
|
||||
}
|
||||
|
||||
static AutoBitmap* make(Engine* engine, JNIEnv* env, jobject bitmap,
|
||||
jobject handler, jobject runnable) {
|
||||
// create a AutoBitmap
|
||||
static AutoBitmap* make(JNIEnv* env, jobject bitmap, jobject handler, jobject runnable) {
|
||||
return new AutoBitmap(env, bitmap, handler, runnable);
|
||||
}
|
||||
|
||||
// execute the callback on the java thread and destroy ourselves
|
||||
static void invoke(void*, size_t, void* user) {
|
||||
auto* autoBitmap = reinterpret_cast<AutoBitmap*>(user);
|
||||
JNIEnv* env = filament::VirtualMachineEnv::get().getEnvironment();
|
||||
releaseCallbackJni(env, autoBitmap->mCallbackUtils, autoBitmap->mHandler, autoBitmap->mCallback);
|
||||
autoBitmap->release(env);
|
||||
delete autoBitmap;
|
||||
}
|
||||
|
||||
// create a AutoBitmap without a handler
|
||||
static AutoBitmap* make(JNIEnv* env, jobject bitmap) {
|
||||
return new AutoBitmap(env, bitmap);
|
||||
}
|
||||
|
||||
// just destroy ourselves
|
||||
static void invokeNoCallback(void*, size_t, void* user) {
|
||||
auto* autoBitmap = reinterpret_cast<AutoBitmap*>(user);
|
||||
JNIEnv* env = filament::VirtualMachineEnv::get().getEnvironment();
|
||||
autoBitmap->release(env);
|
||||
delete autoBitmap;
|
||||
}
|
||||
|
||||
private:
|
||||
JNIEnv* mEnv;
|
||||
void* mData = nullptr;
|
||||
jobject mBitmap = nullptr;
|
||||
jobject mHandler = nullptr;
|
||||
jobject mCallback = nullptr;
|
||||
AndroidBitmapInfo mInfo;
|
||||
CallbackJni mCallbackUtils;
|
||||
AndroidBitmapInfo mInfo{};
|
||||
};
|
||||
|
||||
extern "C"
|
||||
@@ -575,14 +582,14 @@ Java_com_google_android_filament_android_TextureHelper_nSetBitmap(JNIEnv* env, j
|
||||
Texture* texture = (Texture*) nativeTexture;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
|
||||
auto* autoBitmap = AutoBitmap::make(engine, env, bitmap);
|
||||
auto* autoBitmap = AutoBitmap::make(env, bitmap);
|
||||
|
||||
Texture::PixelBufferDescriptor desc(
|
||||
autoBitmap->getData(),
|
||||
autoBitmap->getSizeInBytes(),
|
||||
autoBitmap->getFormat(format),
|
||||
autoBitmap->getType(format),
|
||||
&AutoBitmap::invoke, autoBitmap);
|
||||
&AutoBitmap::invokeNoCallback, autoBitmap);
|
||||
|
||||
texture->setImage(*engine, (size_t) level,
|
||||
(uint32_t) xoffset, (uint32_t) yoffset,
|
||||
@@ -598,14 +605,14 @@ Java_com_google_android_filament_android_TextureHelper_nSetBitmapWithCallback(JN
|
||||
Texture* texture = (Texture*) nativeTexture;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
|
||||
auto* autoBitmap = AutoBitmap::make(engine, env, bitmap, handler, runnable);
|
||||
auto* autoBitmap = AutoBitmap::make(env, bitmap, handler, runnable);
|
||||
|
||||
Texture::PixelBufferDescriptor desc(
|
||||
autoBitmap->getData(),
|
||||
autoBitmap->getSizeInBytes(),
|
||||
autoBitmap->getFormat(format),
|
||||
autoBitmap->getType(format),
|
||||
&AutoBitmap::invoke, autoBitmap);
|
||||
autoBitmap->getHandler(), &AutoBitmap::invoke, autoBitmap);
|
||||
|
||||
texture->setImage(*engine, (size_t) level,
|
||||
(uint32_t) xoffset, (uint32_t) yoffset,
|
||||
|
||||
98
android/filament-android/src/main/cpp/ToneMapper.cpp
Normal file
98
android/filament-android/src/main/cpp/ToneMapper.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* 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/ToneMapper.h>
|
||||
|
||||
using namespace filament;
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nDestroyToneMapper(JNIEnv *env, jclass clazz,
|
||||
jlong toneMapper_) {
|
||||
ToneMapper* toneMapper = (ToneMapper*) toneMapper_;
|
||||
delete toneMapper;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nCreateLinearToneMapper(JNIEnv*, jclass) {
|
||||
return (jlong) new LinearToneMapper();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nCreateACESToneMapper(JNIEnv*, jclass) {
|
||||
return (jlong) new ACESToneMapper();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nCreateACESLegacyToneMapper(JNIEnv*, jclass) {
|
||||
return (jlong) new ACESLegacyToneMapper();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nCreateFilmicToneMapper(JNIEnv*, jclass) {
|
||||
return (jlong) new FilmicToneMapper();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nCreateGenericToneMapper(JNIEnv*, jclass,
|
||||
jfloat contrast, jfloat midGrayIn, jfloat midGrayOut, jfloat hdrMax) {
|
||||
return (jlong) new GenericToneMapper(contrast, midGrayIn, midGrayOut, hdrMax);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jfloat JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nGenericGetContrast(JNIEnv*, jclass, jlong nativeObject) {
|
||||
return ((GenericToneMapper*) nativeObject)->getContrast();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jfloat JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nGenericGetMidGrayIn(JNIEnv*, jclass, jlong nativeObject) {
|
||||
return ((GenericToneMapper*) nativeObject)->getMidGrayIn();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jfloat JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nGenericGetMidGrayOut(JNIEnv*, jclass, jlong nativeObject) {
|
||||
return ((GenericToneMapper*) nativeObject)->getMidGrayOut();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jfloat JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nGenericGetHdrMax(JNIEnv*, jclass, jlong nativeObject) {
|
||||
return ((GenericToneMapper*) nativeObject)->getHdrMax();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nGenericSetContrast(JNIEnv*, jclass,
|
||||
jlong nativeObject, jfloat contrast) {
|
||||
((GenericToneMapper*) nativeObject)->setContrast(contrast);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nGenericSetMidGrayIn(JNIEnv*, jclass,
|
||||
jlong nativeObject, jfloat midGrayIn) {
|
||||
((GenericToneMapper*) nativeObject)->setMidGrayIn(midGrayIn);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nGenericSetMidGrayOut(JNIEnv*, jclass,
|
||||
jlong nativeObject, jfloat midGrayOut) {
|
||||
((GenericToneMapper*) nativeObject)->setMidGrayOut(midGrayOut);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nGenericSetHdrMax(JNIEnv*, jclass,
|
||||
jlong nativeObject, jfloat hdrMax) {
|
||||
((GenericToneMapper*) nativeObject)->setHdrMax(hdrMax);
|
||||
}
|
||||
@@ -70,6 +70,23 @@ Java_com_google_android_filament_TransformManager_nCreateArray(JNIEnv* env,
|
||||
return tm->getInstance(entity);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_TransformManager_nCreateArrayFp64(JNIEnv* env,
|
||||
jclass, jlong nativeTransformManager, jint entity_, jint parent,
|
||||
jdoubleArray localTransform_) {
|
||||
TransformManager* tm = (TransformManager*) nativeTransformManager;
|
||||
Entity& entity = *reinterpret_cast<Entity*>(&entity_);
|
||||
if (localTransform_) {
|
||||
jdouble *localTransform = env->GetDoubleArrayElements(localTransform_, NULL);
|
||||
tm->create(entity, (TransformManager::Instance) parent,
|
||||
*reinterpret_cast<const filament::math::mat4 *>(localTransform));
|
||||
env->ReleaseDoubleArrayElements(localTransform_, localTransform, JNI_ABORT);
|
||||
} else {
|
||||
tm->create(entity, (TransformManager::Instance) parent);
|
||||
}
|
||||
return tm->getInstance(entity);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_TransformManager_nDestroy(JNIEnv*, jclass,
|
||||
jlong nativeTransformManager, jint entity_) {
|
||||
@@ -104,6 +121,17 @@ Java_com_google_android_filament_TransformManager_nSetTransform(JNIEnv* env,
|
||||
env->ReleaseFloatArrayElements(localTransform_, localTransform, JNI_ABORT);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_TransformManager_nSetTransformFp64(JNIEnv* env,
|
||||
jclass, jlong nativeTransformManager, jint i,
|
||||
jdoubleArray localTransform_) {
|
||||
TransformManager* tm = (TransformManager*) nativeTransformManager;
|
||||
jdouble *localTransform = env->GetDoubleArrayElements(localTransform_, NULL);
|
||||
tm->setTransform((TransformManager::Instance) i,
|
||||
*reinterpret_cast<const filament::math::mat4 *>(localTransform));
|
||||
env->ReleaseDoubleArrayElements(localTransform_, localTransform, JNI_ABORT);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_TransformManager_nGetTransform(JNIEnv* env,
|
||||
jclass, jlong nativeTransformManager, jint i,
|
||||
@@ -115,6 +143,17 @@ Java_com_google_android_filament_TransformManager_nGetTransform(JNIEnv* env,
|
||||
env->ReleaseFloatArrayElements(outLocalTransform_, outLocalTransform, 0);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_TransformManager_nGetTransformFp64(JNIEnv* env,
|
||||
jclass, jlong nativeTransformManager, jint i,
|
||||
jdoubleArray outLocalTransform_) {
|
||||
TransformManager* tm = (TransformManager*) nativeTransformManager;
|
||||
jdouble *outLocalTransform = env->GetDoubleArrayElements(outLocalTransform_, NULL);
|
||||
*reinterpret_cast<filament::math::mat4 *>(outLocalTransform) = tm->getTransformAccurate(
|
||||
(TransformManager::Instance) i);
|
||||
env->ReleaseDoubleArrayElements(outLocalTransform_, outLocalTransform, 0);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_TransformManager_nGetWorldTransform(JNIEnv* env,
|
||||
jclass, jlong nativeTransformManager, jint i,
|
||||
@@ -126,6 +165,17 @@ Java_com_google_android_filament_TransformManager_nGetWorldTransform(JNIEnv* env
|
||||
env->ReleaseFloatArrayElements(outWorldTransform_, outWorldTransform, 0);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_TransformManager_nGetWorldTransformFp64(JNIEnv* env,
|
||||
jclass, jlong nativeTransformManager, jint i,
|
||||
jdoubleArray outWorldTransform_) {
|
||||
TransformManager* tm = (TransformManager*) nativeTransformManager;
|
||||
jdouble *outWorldTransform = env->GetDoubleArrayElements(outWorldTransform_, NULL);
|
||||
*reinterpret_cast<filament::math::mat4 *>(outWorldTransform) = tm->getWorldTransformAccurate(
|
||||
(TransformManager::Instance) i);
|
||||
env->ReleaseDoubleArrayElements(outWorldTransform_, outWorldTransform, 0);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_TransformManager_nOpenLocalTransformTransaction(
|
||||
JNIEnv*, jclass, jlong nativeTransformManager) {
|
||||
@@ -139,3 +189,19 @@ Java_com_google_android_filament_TransformManager_nCommitLocalTransformTransacti
|
||||
TransformManager* tm = (TransformManager*) nativeTransformManager;
|
||||
tm->commitLocalTransformTransaction();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_TransformManager_nSetAccurateTranslationsEnabled(JNIEnv*,
|
||||
jclass, jlong nativeTransformManager, jboolean enable) {
|
||||
TransformManager* tm = (TransformManager*) nativeTransformManager;
|
||||
tm->setAccurateTranslationsEnabled((bool)enable);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_TransformManager_nIsAccurateTranslationsEnabled(JNIEnv*,
|
||||
jclass, jlong nativeTransformManager) {
|
||||
TransformManager* tm = (TransformManager*) nativeTransformManager;
|
||||
return (jboolean)tm->isAccurateTranslationsEnabled();
|
||||
}
|
||||
|
||||
@@ -32,40 +32,40 @@ using namespace filament::math;
|
||||
using namespace backend;
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_VertexBuffer_nCreateBuilder(JNIEnv *env, jclass type) {
|
||||
Java_com_google_android_filament_VertexBuffer_nCreateBuilder(JNIEnv*, jclass) {
|
||||
return (jlong) new VertexBuffer::Builder();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_VertexBuffer_nDestroyBuilder(JNIEnv *env, jclass type,
|
||||
Java_com_google_android_filament_VertexBuffer_nDestroyBuilder(JNIEnv*, jclass,
|
||||
jlong nativeBuilder) {
|
||||
VertexBuffer::Builder* builder = (VertexBuffer::Builder *) nativeBuilder;
|
||||
delete builder;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_VertexBuffer_nBuilderVertexCount(JNIEnv *env, jclass type,
|
||||
Java_com_google_android_filament_VertexBuffer_nBuilderVertexCount(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jint vertexCount) {
|
||||
VertexBuffer::Builder* builder = (VertexBuffer::Builder *) nativeBuilder;
|
||||
builder->vertexCount((uint32_t) vertexCount);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_VertexBuffer_nBuilderEnableBufferObjects(JNIEnv *env, jclass type,
|
||||
Java_com_google_android_filament_VertexBuffer_nBuilderEnableBufferObjects(JNIEnv*, jclass,
|
||||
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,
|
||||
Java_com_google_android_filament_VertexBuffer_nBuilderBufferCount(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jint bufferCount) {
|
||||
VertexBuffer::Builder* builder = (VertexBuffer::Builder *) nativeBuilder;
|
||||
builder->bufferCount((uint8_t) bufferCount);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_VertexBuffer_nBuilderAttribute(JNIEnv *env, jclass type,
|
||||
Java_com_google_android_filament_VertexBuffer_nBuilderAttribute(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jint attribute, jint bufferIndex, jint attributeType, jint byteOffset,
|
||||
jint byteStride) {
|
||||
VertexBuffer::Builder* builder = (VertexBuffer::Builder *) nativeBuilder;
|
||||
@@ -75,14 +75,14 @@ Java_com_google_android_filament_VertexBuffer_nBuilderAttribute(JNIEnv *env, jcl
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_VertexBuffer_nBuilderNormalized(JNIEnv *env, jclass type,
|
||||
Java_com_google_android_filament_VertexBuffer_nBuilderNormalized(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jint attribute, jboolean normalized) {
|
||||
VertexBuffer::Builder* builder = (VertexBuffer::Builder *) nativeBuilder;
|
||||
builder->normalized((VertexAttribute) attribute, normalized);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_VertexBuffer_nBuilderBuild(JNIEnv *env, jclass type,
|
||||
Java_com_google_android_filament_VertexBuffer_nBuilderBuild(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jlong nativeEngine) {
|
||||
VertexBuffer::Builder* builder = (VertexBuffer::Builder *) nativeBuilder;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
@@ -90,14 +90,14 @@ Java_com_google_android_filament_VertexBuffer_nBuilderBuild(JNIEnv *env, jclass
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_VertexBuffer_nGetVertexCount(JNIEnv *env, jclass type,
|
||||
Java_com_google_android_filament_VertexBuffer_nGetVertexCount(JNIEnv*, jclass,
|
||||
jlong nativeVertexBuffer) {
|
||||
VertexBuffer *vertexBuffer = (VertexBuffer *) nativeVertexBuffer;
|
||||
return (jint) vertexBuffer->getVertexCount();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_VertexBuffer_nSetBufferAt(JNIEnv *env, jclass type,
|
||||
Java_com_google_android_filament_VertexBuffer_nSetBufferAt(JNIEnv *env, jclass,
|
||||
jlong nativeVertexBuffer, jlong nativeEngine, jint bufferIndex,
|
||||
jobject buffer, jint remaining,
|
||||
jint destOffsetInBytes, jint count, jobject handler, jobject runnable) {
|
||||
@@ -114,7 +114,8 @@ Java_com_google_android_filament_VertexBuffer_nSetBufferAt(JNIEnv *env, jclass t
|
||||
|
||||
auto* callback = JniBufferCallback::make(engine, env, handler, runnable, std::move(nioBuffer));
|
||||
|
||||
BufferDescriptor desc(data, sizeInBytes, &JniBufferCallback::invoke, callback);
|
||||
BufferDescriptor desc(data, sizeInBytes,
|
||||
callback->getHandler(), &JniBufferCallback::postToJavaAndDestroy, callback);
|
||||
|
||||
vertexBuffer->setBufferAt(*engine, (uint8_t) bufferIndex, std::move(desc),
|
||||
(uint32_t) destOffsetInBytes);
|
||||
@@ -123,7 +124,7 @@ Java_com_google_android_filament_VertexBuffer_nSetBufferAt(JNIEnv *env, jclass t
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_VertexBuffer_nSetBufferObjectAt(JNIEnv *env, jclass type,
|
||||
Java_com_google_android_filament_VertexBuffer_nSetBufferObjectAt(JNIEnv*, jclass,
|
||||
jlong nativeVertexBuffer, jlong nativeEngine, jint bufferIndex, jlong nativeBufferObject) {
|
||||
VertexBuffer *vertexBuffer = (VertexBuffer *) nativeVertexBuffer;
|
||||
Engine *engine = (Engine *) nativeEngine;
|
||||
|
||||
@@ -20,6 +20,10 @@
|
||||
#include <filament/View.h>
|
||||
#include <filament/Viewport.h>
|
||||
|
||||
#include "common/CallbackUtils.h"
|
||||
|
||||
#include "private/backend/VirtualMachineEnv.h"
|
||||
|
||||
using namespace filament;
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
@@ -82,13 +86,19 @@ Java_com_google_android_filament_View_nSetRenderTarget(JNIEnv*, jclass,
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetSampleCount(JNIEnv*, jclass, jlong nativeView, jint count) {
|
||||
View* view = (View*) nativeView;
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
view->setSampleCount((uint8_t) count);
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_View_nGetSampleCount(JNIEnv*, jclass, jlong nativeView) {
|
||||
View* view = (View*) nativeView;
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
return view->getSampleCount();
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
@@ -119,13 +129,14 @@ Java_com_google_android_filament_View_nGetDithering(JNIEnv*, jclass,
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetDynamicResolutionOptions(JNIEnv*, jclass, jlong nativeView,
|
||||
jboolean enabled, jboolean homogeneousScaling,
|
||||
jfloat minScale, jfloat maxScale, jint quality) {
|
||||
jfloat minScale, jfloat maxScale, jfloat sharpness, jint quality) {
|
||||
View* view = (View*)nativeView;
|
||||
View::DynamicResolutionOptions options;
|
||||
options.enabled = enabled;
|
||||
options.homogeneousScaling = homogeneousScaling;
|
||||
options.minScale = filament::math::float2{ minScale };
|
||||
options.maxScale = filament::math::float2{ maxScale };
|
||||
options.sharpness = sharpness;
|
||||
options.quality = (View::QualityLevel)quality;
|
||||
view->setDynamicResolutionOptions(options);
|
||||
}
|
||||
@@ -138,18 +149,27 @@ Java_com_google_android_filament_View_nSetShadowType(JNIEnv*, jclass, jlong nati
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetVsmShadowOptions(JNIEnv*, jclass, jlong nativeView,
|
||||
jint anisotropy, jboolean mipmapping, jfloat exponent, jfloat minVarianceScale,
|
||||
jint anisotropy, jboolean mipmapping, jfloat minVarianceScale,
|
||||
jfloat lightBleedReduction) {
|
||||
View* view = (View*) nativeView;
|
||||
View::VsmShadowOptions options;
|
||||
options.anisotropy = (uint8_t)anisotropy;
|
||||
options.mipmapping = (bool)mipmapping;
|
||||
options.exponent = exponent;
|
||||
options.minVarianceScale = minVarianceScale;
|
||||
options.lightBleedReduction = lightBleedReduction;
|
||||
view->setVsmShadowOptions(options);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetSoftShadowOptions(JNIEnv*, jclass, jlong nativeView,
|
||||
jfloat penumbraScale, jfloat penumbraRatioScale) {
|
||||
View* view = (View*) nativeView;
|
||||
View::SoftShadowOptions options;
|
||||
options.penumbraScale = penumbraScale;
|
||||
options.penumbraRatioScale = penumbraRatioScale;
|
||||
view->setSoftShadowOptions(options);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetRenderQuality(JNIEnv*, jclass,
|
||||
@@ -216,7 +236,9 @@ Java_com_google_android_filament_View_nGetAmbientOcclusion(JNIEnv*, jclass, jlon
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetAmbientOcclusionOptions(JNIEnv*, jclass,
|
||||
jlong nativeView, jfloat radius, jfloat bias, jfloat power, jfloat resolution, jfloat intensity,
|
||||
jint quality, jint lowPassFilter, jint upsampling, jboolean enabled, jfloat minHorizonAngleRad) {
|
||||
jfloat bilateralThreshold,
|
||||
jint quality, jint lowPassFilter, jint upsampling, jboolean enabled, jboolean bentNormals,
|
||||
jfloat minHorizonAngleRad) {
|
||||
View* view = (View*) nativeView;
|
||||
View::AmbientOcclusionOptions options = view->getAmbientOcclusionOptions();
|
||||
options.radius = radius;
|
||||
@@ -224,10 +246,12 @@ Java_com_google_android_filament_View_nSetAmbientOcclusionOptions(JNIEnv*, jclas
|
||||
options.bias = bias;
|
||||
options.resolution = resolution;
|
||||
options.intensity = intensity;
|
||||
options.bilateralThreshold = bilateralThreshold;
|
||||
options.quality = (View::QualityLevel)quality;
|
||||
options.lowPassFilter = (View::QualityLevel)lowPassFilter;
|
||||
options.upsampling = (View::QualityLevel)upsampling;
|
||||
options.enabled = (bool)enabled;
|
||||
options.bentNormals = (bool)bentNormals;
|
||||
options.minHorizonAngleRad = minHorizonAngleRad;
|
||||
view->setAmbientOcclusionOptions(options);
|
||||
}
|
||||
@@ -316,8 +340,8 @@ 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, jint filter,
|
||||
Java_com_google_android_filament_View_nSetDepthOfFieldOptions(JNIEnv *, jclass,
|
||||
jlong nativeView, jfloat cocScale, jfloat maxApertureDiameter, jboolean enabled, jint filter,
|
||||
jboolean nativeResolution, jint foregroundRingCount, jint backgroundRingCount, jint fastGatherRingCount,
|
||||
jint maxForegroundCOC, jint maxBackgroundCOC) {
|
||||
View* view = (View*) nativeView;
|
||||
@@ -346,6 +370,17 @@ Java_com_google_android_filament_View_nSetVignetteOptions(JNIEnv*, jclass, jlong
|
||||
.color = LinearColorA{r, g, b, a}, .enabled = (bool)enabled});
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetMultiSampleAntiAliasingOptions(JNIEnv* env, jclass clazz,
|
||||
jlong nativeView, jboolean enabled, jint sampleCount, jboolean customResolve) {
|
||||
View* view = (View*) nativeView;
|
||||
view->setMultiSampleAntiAliasingOptions({
|
||||
.enabled = (bool)enabled,
|
||||
.sampleCount = (uint8_t)sampleCount,
|
||||
.customResolve = (bool)customResolve});
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetTemporalAntiAliasingOptions(JNIEnv *, jclass,
|
||||
@@ -355,6 +390,16 @@ Java_com_google_android_filament_View_nSetTemporalAntiAliasingOptions(JNIEnv *,
|
||||
.filterWidth = filterWidth, .feedback = feedback, .enabled = (bool) enabled});
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetScreenSpaceReflectionsOptions(JNIEnv*, jclass,
|
||||
jlong nativeView, jfloat thickness, jfloat bias, jfloat maxDistance, jfloat stride, jboolean enabled) {
|
||||
View* view = (View*) nativeView;
|
||||
view->setScreenSpaceReflectionsOptions({.thickness = thickness, .bias = bias,
|
||||
.maxDistance = maxDistance, .stride = stride, .enabled = (bool) enabled
|
||||
});
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_View_nIsShadowingEnabled(JNIEnv *, jclass, jlong nativeView) {
|
||||
@@ -377,3 +422,42 @@ Java_com_google_android_filament_View_nIsScreenSpaceRefractionEnabled(JNIEnv *,
|
||||
View* view = (View*) nativeView;
|
||||
return (jboolean)view->isScreenSpaceRefractionEnabled();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nPick(JNIEnv* env, jclass,
|
||||
jlong nativeView,
|
||||
jint x, jint y, jobject handler, jobject internalCallback) {
|
||||
|
||||
// jniState will be initialized the first time this method is called
|
||||
static const struct JniState {
|
||||
jclass internalOnPickCallbackClass;
|
||||
jfieldID renderableFieldId;
|
||||
jfieldID depthFieldId;
|
||||
jfieldID fragCoordXFieldId;
|
||||
jfieldID fragCoordYFieldId;
|
||||
jfieldID fragCoordZFieldId;
|
||||
explicit JniState(JNIEnv* env) noexcept {
|
||||
internalOnPickCallbackClass = env->FindClass("com/google/android/filament/View$InternalOnPickCallback");
|
||||
renderableFieldId = env->GetFieldID(internalOnPickCallbackClass, "mRenderable", "I");
|
||||
depthFieldId = env->GetFieldID(internalOnPickCallbackClass, "mDepth", "F");
|
||||
fragCoordXFieldId = env->GetFieldID(internalOnPickCallbackClass, "mFragCoordsX", "F");
|
||||
fragCoordYFieldId = env->GetFieldID(internalOnPickCallbackClass, "mFragCoordsY", "F");
|
||||
fragCoordZFieldId = env->GetFieldID(internalOnPickCallbackClass, "mFragCoordsZ", "F");
|
||||
}
|
||||
} jniState(env);
|
||||
|
||||
View* view = (View*) nativeView;
|
||||
JniCallback *callback = JniCallback::make(env, handler, internalCallback);
|
||||
view->pick(x, y, [callback](View::PickingQueryResult const& result) {
|
||||
// this is executed on the backend/service thread
|
||||
jobject obj = callback->getCallbackObject();
|
||||
JNIEnv* env = filament::VirtualMachineEnv::get().getEnvironment();
|
||||
env->SetIntField(obj, jniState.renderableFieldId, (jint)result.renderable.getId());
|
||||
env->SetFloatField(obj, jniState.depthFieldId, result.depth);
|
||||
env->SetFloatField(obj, jniState.fragCoordXFieldId, result.fragCoords.x);
|
||||
env->SetFloatField(obj, jniState.fragCoordYFieldId, result.fragCoords.y);
|
||||
env->SetFloatField(obj, jniState.fragCoordZFieldId, result.fragCoords.z);
|
||||
JniCallback::postToJavaAndDestroy(callback);
|
||||
}, callback->getHandler());
|
||||
}
|
||||
|
||||
@@ -63,12 +63,27 @@ final class Asserts {
|
||||
return out;
|
||||
}
|
||||
|
||||
@NonNull @Size(min = 16)
|
||||
static double[] assertMat4(@Nullable double[] out) {
|
||||
if (out == null) out = new double[16];
|
||||
else if (out.length < 16) {
|
||||
throw new ArrayIndexOutOfBoundsException("Array length must be at least 16");
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
static void assertMat4fIn(@NonNull @Size(min = 16) float[] in) {
|
||||
if (in.length < 16) {
|
||||
throw new ArrayIndexOutOfBoundsException("Array length must be at least 16");
|
||||
}
|
||||
}
|
||||
|
||||
static void assertMat4In(@NonNull @Size(min = 16) double[] in) {
|
||||
if (in.length < 16) {
|
||||
throw new ArrayIndexOutOfBoundsException("Array length must be at least 16");
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull @Size(min = 3)
|
||||
static float[] assertFloat3(@Nullable float[] out) {
|
||||
if (out == null) out = new float[3];
|
||||
|
||||
@@ -254,6 +254,9 @@ public class Camera {
|
||||
/**
|
||||
* Sets a custom projection matrix.
|
||||
*
|
||||
* <p>The projection matrix must define an NDC system that must match the OpenGL convention,
|
||||
* that is all 3 axis are mapped to [-1, 1].</p>
|
||||
*
|
||||
* @param inProjection custom projection matrix for rendering and culling
|
||||
*
|
||||
* @param near distance in world units from the camera to the near plane.
|
||||
@@ -279,6 +282,9 @@ public class Camera {
|
||||
/**
|
||||
* Sets a custom projection matrix.
|
||||
*
|
||||
* <p>The projection matrices must define an NDC system that must match the OpenGL convention,
|
||||
* that is all 3 axis are mapped to [-1, 1].</p>
|
||||
*
|
||||
* @param inProjection custom projection matrix for rendering.
|
||||
*
|
||||
* @param inProjectionForCulling custom projection matrix for culling.
|
||||
@@ -413,6 +419,20 @@ public class Camera {
|
||||
nSetModelMatrix(getNativeObject(), viewMatrix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the camera's view matrix.
|
||||
* <p>
|
||||
* Helper method to set the camera's entity transform component.
|
||||
* Remember that the Camera "looks" towards its -z axis.
|
||||
* <p>
|
||||
*
|
||||
* @param viewMatrix The camera position and orientation provided as a <b>rigid transform</b> matrix.
|
||||
*/
|
||||
public void setModelMatrix(@NonNull @Size(min = 16) double[] viewMatrix) {
|
||||
Asserts.assertMat4In(viewMatrix);
|
||||
nSetModelMatrixFp64(getNativeObject(), viewMatrix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the camera's view matrix.
|
||||
*
|
||||
@@ -510,6 +530,22 @@ public class Camera {
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the camera's model matrix. The model matrix encodes the camera position and
|
||||
* orientation, or pose.
|
||||
*
|
||||
* @param out A 16-double array where the model matrix will be stored, or null in which
|
||||
* case a new array is allocated.
|
||||
*
|
||||
* @return A 16-double array containing the camera's pose as a column-major matrix.
|
||||
*/
|
||||
@NonNull @Size(min = 16)
|
||||
public double[] getModelMatrix(@Nullable @Size(min = 16) double[] out) {
|
||||
out = Asserts.assertMat4(out);
|
||||
nGetModelMatrixFp64(getNativeObject(), out);
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the camera's view matrix. The view matrix is the inverse of the model matrix.
|
||||
*
|
||||
@@ -525,6 +561,21 @@ public class Camera {
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the camera's view matrix. The view matrix is the inverse of the model matrix.
|
||||
*
|
||||
* @param out A 16-double array where the model view will be stored, or null in which
|
||||
* case a new array is allocated.
|
||||
*
|
||||
* @return A 16-double array containing the camera's view as a column-major matrix.
|
||||
*/
|
||||
@NonNull @Size(min = 16)
|
||||
public double[] getViewMatrix(@Nullable @Size(min = 16) double[] out) {
|
||||
out = Asserts.assertMat4(out);
|
||||
nGetViewMatrixFp64(getNativeObject(), out);
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the camera position in world space.
|
||||
*
|
||||
@@ -734,6 +785,7 @@ public class Camera {
|
||||
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 nSetModelMatrixFp64(long nativeCamera, double[] 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);
|
||||
private static native float nGetCullingFar(long nativeCamera);
|
||||
@@ -741,7 +793,9 @@ public class Camera {
|
||||
private static native void nGetCullingProjectionMatrix(long nativeCamera, double[] out);
|
||||
private static native void nGetScaling(long nativeCamera, double[] out);
|
||||
private static native void nGetModelMatrix(long nativeCamera, float[] out);
|
||||
private static native void nGetModelMatrixFp64(long nativeCamera, double[] out);
|
||||
private static native void nGetViewMatrix(long nativeCamera, float[] out);
|
||||
private static native void nGetViewMatrixFp64(long nativeCamera, double[] out);
|
||||
private static native void nGetPosition(long nativeCamera, float[] out);
|
||||
private static native void nGetLeftVector(long nativeCamera, float[] out);
|
||||
private static native void nGetUpVector(long nativeCamera, float[] out);
|
||||
|
||||
@@ -55,6 +55,7 @@ import static com.google.android.filament.Asserts.assertFloat4In;
|
||||
* The various transforms held by ColorGrading are applied in the following order:
|
||||
* <ul>
|
||||
* <li>Exposure</li>
|
||||
* <li>Night adaptation</li>
|
||||
* <li>White balance</li>
|
||||
* <li>Channel mixer</li>
|
||||
* <li>Shadows/mid-tones/highlights</li>
|
||||
@@ -65,6 +66,7 @@ import static com.google.android.filament.Asserts.assertFloat4In;
|
||||
* <li>Curves</li>
|
||||
* <li>Tone mapping</li>
|
||||
* <li>Luminance scaling</li>
|
||||
* <li>Gamut mapping</li>
|
||||
* </ul>
|
||||
*
|
||||
* <h1>Defaults</h1>
|
||||
@@ -72,6 +74,7 @@ import static com.google.android.filament.Asserts.assertFloat4In;
|
||||
* Here are the default color grading options:
|
||||
* <ul>
|
||||
* <li>Exposure: 0.0</li>
|
||||
* <li>Night adaptation: 0.0</li>
|
||||
* <li>White balance: temperature <code>0.0</code>, and tint <code>0.0</code></li>
|
||||
* <li>Channel mixer: red <code>{1,0,0}</code>, green <code>{0,1,0}</code>, blue <code>{0,0,1}</code></li>
|
||||
* <li>Shadows/mid-tones/highlights: shadows <code>{1,1,1,0}</code>, mid-tones <code>{1,1,1,0}</code>,
|
||||
@@ -81,12 +84,13 @@ import static com.google.android.filament.Asserts.assertFloat4In;
|
||||
* <li>Vibrance: <code>1.0</code></li>
|
||||
* <li>Saturation: <code>1.0</code></li>
|
||||
* <li>Curves: gamma <code>{1,1,1}</code>, midPoint <code>{1,1,1}</code>, and scale <code>{1,1,1}</code></li>
|
||||
* <li>Tone mapping: {@link ToneMapping#ACES_LEGACY}</li>
|
||||
* <li>Tone mapping: {@link ToneMapper.ACESLegacy}</li>
|
||||
* <li>Luminance scaling: false</li>
|
||||
* <li>Gamut mapping: false</li>
|
||||
* </ul>
|
||||
*
|
||||
* @see View
|
||||
* @see ToneMapping
|
||||
* @see ToneMapper
|
||||
*/
|
||||
public class ColorGrading {
|
||||
long mNativeObject;
|
||||
@@ -101,8 +105,18 @@ public class ColorGrading {
|
||||
ULTRA
|
||||
}
|
||||
|
||||
/**
|
||||
* Color grading LUT format.
|
||||
*/
|
||||
public enum LutFormat {
|
||||
INTEGER,
|
||||
FLOAT
|
||||
}
|
||||
|
||||
/**
|
||||
* List of available tone-mapping operators.
|
||||
*
|
||||
* @deprecated Use {@link ColorGrading.Builder#toneMapper(ToneMapper)}
|
||||
*/
|
||||
public enum ToneMapping {
|
||||
/** Linear tone mapping (i.e. no tone mapping). */
|
||||
@@ -113,10 +127,6 @@ public class ColorGrading {
|
||||
ACES,
|
||||
/** Filmic tone mapping, modelled after ACES but applied in sRGB space. */
|
||||
FILMIC,
|
||||
/** Reserved for future use. */
|
||||
RESERVED,
|
||||
/** Reinhard luma-based tone mapping. */
|
||||
REINHARD,
|
||||
/** Tone mapping used to validate/debug scene exposure. */
|
||||
DISPLAY_RANGE,
|
||||
}
|
||||
@@ -160,6 +170,55 @@ public class ColorGrading {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* When color grading is implemented using a 3D LUT, this sets the texture format of
|
||||
* of the LUT. This overrides the value set by quality().
|
||||
*
|
||||
* The default is INTEGER
|
||||
*
|
||||
* @param format The desired format of the 3D LUT.
|
||||
*
|
||||
* @return This Builder, for chaining calls
|
||||
*/
|
||||
public Builder format(LutFormat format) {
|
||||
nBuilderFormat(mNativeBuilder, format.ordinal());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* When color grading is implemented using a 3D LUT, this sets the dimension of the LUT.
|
||||
* This overrides the value set by quality().
|
||||
*
|
||||
* The default is 32
|
||||
*
|
||||
* @param dim The desired dimension of the LUT. Between 16 and 64.
|
||||
*
|
||||
* @return This Builder, for chaining calls
|
||||
*/
|
||||
public Builder dimensions(int dim) {
|
||||
nBuilderDimensions(mNativeBuilder, dim);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects the tone mapping operator to apply to the HDR color buffer as the last
|
||||
* operation of the color grading post-processing step.
|
||||
*
|
||||
* The default tone mapping operator is {@link ToneMapper.ACESLegacy}.
|
||||
*
|
||||
* The specified tone mapper must have a lifecycle that exceeds the lifetime of
|
||||
* this builder. Since the build(Engine&) method is synchronous, it is safe to
|
||||
* delete the tone mapper object after that finishes executing.
|
||||
*
|
||||
* @param toneMapper The tone mapping operator to apply to the HDR color buffer
|
||||
*
|
||||
* @return This Builder, for chaining calls
|
||||
*/
|
||||
public Builder toneMapper(ToneMapper toneMapper) {
|
||||
nBuilderToneMapper(mNativeBuilder, toneMapper.getNativeObject());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects the tone mapping operator to apply to the HDR color buffer as the last
|
||||
* operation of the color grading post-processing step.
|
||||
@@ -169,6 +228,8 @@ public class ColorGrading {
|
||||
* @param toneMapping The tone mapping operator to apply to the HDR color buffer
|
||||
*
|
||||
* @return This Builder, for chaining calls
|
||||
*
|
||||
* @deprecated Use {@link #toneMapper(ToneMapper)}
|
||||
*/
|
||||
public Builder toneMapping(ToneMapping toneMapping) {
|
||||
nBuilderToneMapping(mNativeBuilder, toneMapping.ordinal());
|
||||
@@ -194,6 +255,22 @@ public class ColorGrading {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables gamut mapping to the destination color space's gamut. When gamut
|
||||
* mapping is turned off, out-of-gamut colors are clipped to the destination's gamut,
|
||||
* which may produce hue skews (blue skewing to purple, green to yellow, etc.). When
|
||||
* gamut mapping is enabled, out-of-gamut colors are brought back in gamut by trying to
|
||||
* preserve the perceived chroma and lightness of the original values.
|
||||
*
|
||||
* @param gamutMapping Enables or disables gamut mapping
|
||||
*
|
||||
* @return This Builder, for chaining calls
|
||||
*/
|
||||
public Builder gamutMapping(boolean gamutMapping) {
|
||||
nBuilderGamutMapping(mNativeBuilder, gamutMapping);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts the exposure of this image. The exposure is specified in stops:
|
||||
* each stop brightens (positive values) or darkens (negative values) the image by
|
||||
@@ -210,6 +287,22 @@ public class ColorGrading {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls the amount of night adaptation to replicate a more natural representation of
|
||||
* low-light conditions as perceived by the human vision system. In low-light conditions,
|
||||
* peak luminance sensitivity of the eye shifts toward the blue end of the color spectrum:
|
||||
* darker tones appear brighter, reducing contrast, and colors are blue shifted (the darker
|
||||
* the more intense the effect).
|
||||
*
|
||||
* @param adaptation Amount of adaptation, between 0 (no adaptation) and 1 (full adaptation).
|
||||
*
|
||||
* @return This Builder, for chaining calls
|
||||
*/
|
||||
public Builder nightAdaptation(float adaptation) {
|
||||
nBuilderNightAdaptation(mNativeBuilder, adaptation);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts the while balance of the image. This can be used to remove color casts
|
||||
* and correct the appearance of the white point in the scene, or to alter the
|
||||
@@ -502,9 +595,14 @@ public class ColorGrading {
|
||||
private static native void nDestroyBuilder(long nativeBuilder);
|
||||
|
||||
private static native void nBuilderQuality(long nativeBuilder, int quality);
|
||||
private static native void nBuilderToneMapping(long nativeBuilder, int toneMapper);
|
||||
private static native void nBuilderFormat(long nativeBuilder, int format);
|
||||
private static native void nBuilderDimensions(long nativeBuilder, int dim);
|
||||
private static native void nBuilderToneMapper(long nativeBuilder, long toneMapper);
|
||||
private static native void nBuilderToneMapping(long nativeBuilder, int toneMapping);
|
||||
private static native void nBuilderLuminanceScaling(long nativeBuilder, boolean luminanceScaling);
|
||||
private static native void nBuilderGamutMapping(long nativeBuilder, boolean gamutMapping);
|
||||
private static native void nBuilderExposure(long nativeBuilder, float exposure);
|
||||
private static native void nBuilderNightAdaptation(long nativeBuilder, float adaptation);
|
||||
private static native void nBuilderWhiteBalance(long nativeBuilder, float temperature, float tint);
|
||||
private static native void nBuilderChannelMixer(long nativeBuilder, float[] outRed, float[] outGreen, float[] outBlue);
|
||||
private static native void nBuilderShadowsMidtonesHighlights(long nativeBuilder, float[] shadows, float[] midtones, float[] highlights, float[] ranges);
|
||||
|
||||
@@ -106,7 +106,10 @@ import com.google.android.filament.proguard.UsedByReflection;
|
||||
* @see Renderer
|
||||
*/
|
||||
public class Engine {
|
||||
private static final Backend[] sBackendValues = Backend.values();
|
||||
|
||||
private long mNativeObject;
|
||||
|
||||
@NonNull private final TransformManager mTransformManager;
|
||||
@NonNull private final LightManager mLightManager;
|
||||
@NonNull private final RenderableManager mRenderableManager;
|
||||
@@ -252,7 +255,7 @@ public class Engine {
|
||||
*/
|
||||
@NonNull
|
||||
public Backend getBackend() {
|
||||
return Backend.values()[(int) nGetBackend(getNativeObject())];
|
||||
return sBackendValues[(int) nGetBackend(getNativeObject())];
|
||||
}
|
||||
|
||||
// SwapChain
|
||||
@@ -513,6 +516,15 @@ public class Engine {
|
||||
vertexBuffer.clearNativeObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys a {@link SkinningBuffer} and frees all its associated resources.
|
||||
* @param skinningBuffer the {@link SkinningBuffer} to destroy
|
||||
*/
|
||||
public void destroySkinningBuffer(@NonNull SkinningBuffer skinningBuffer) {
|
||||
assertDestroy(nDestroySkinningBuffer(getNativeObject(), skinningBuffer.getNativeObject()));
|
||||
skinningBuffer.clearNativeObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys a {@link IndirectLight} and frees all its associated resources.
|
||||
* @param ibl the {@link IndirectLight} to destroy
|
||||
@@ -631,7 +643,7 @@ public class Engine {
|
||||
|
||||
/**
|
||||
* 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
|
||||
* all commands to this point are executed. Note that this does guarantee that the
|
||||
* hardware is actually finished.
|
||||
*
|
||||
* <p>This is typically used right after destroying the <code>SwapChain</code>,
|
||||
@@ -690,6 +702,7 @@ public class Engine {
|
||||
private static native boolean nDestroyStream(long nativeEngine, long nativeStream);
|
||||
private static native boolean nDestroyIndexBuffer(long nativeEngine, long nativeIndexBuffer);
|
||||
private static native boolean nDestroyVertexBuffer(long nativeEngine, long nativeVertexBuffer);
|
||||
private static native boolean nDestroySkinningBuffer(long nativeEngine, long nativeSkinningBuffer);
|
||||
private static native boolean nDestroyIndirectLight(long nativeEngine, long nativeIndirectLight);
|
||||
private static native boolean nDestroyMaterial(long nativeEngine, long nativeMaterial);
|
||||
private static native boolean nDestroyMaterialInstance(long nativeEngine, long nativeMaterialInstance);
|
||||
|
||||
@@ -117,6 +117,8 @@ import androidx.annotation.Size;
|
||||
* </ul>
|
||||
*/
|
||||
public class LightManager {
|
||||
private static final Type[] sTypeValues = Type.values();
|
||||
|
||||
private long mNativeObject;
|
||||
|
||||
LightManager(long nativeLightManager) {
|
||||
@@ -244,13 +246,13 @@ public class LightManager {
|
||||
* light. 1mm by default.
|
||||
* This is ignored when the View's ShadowType is set to VSM.
|
||||
*/
|
||||
public float constantBias = 0.05f;
|
||||
public float constantBias = 0.001f;
|
||||
|
||||
/** Amount by which the maximum sampling error is scaled. The resulting value is used
|
||||
* to move the shadow away from the fragment normal. Should be 1.0.
|
||||
* This is ignored when the View's ShadowType is set to VSM.
|
||||
*/
|
||||
public float normalBias = 0.4f;
|
||||
public float normalBias = 1.0f;
|
||||
|
||||
/** Distance from the camera after which shadows are clipped. This is used to clip
|
||||
* shadows that are too far and wouldn't contribute to the scene much, improving
|
||||
@@ -279,7 +281,24 @@ public class LightManager {
|
||||
* When set to true, all resolution enhancing features that can affect stability are
|
||||
* disabling, resulting in significantly lower resolution shadows, albeit stable ones.
|
||||
*/
|
||||
public boolean stable = true;
|
||||
public boolean stable = false;
|
||||
|
||||
/**
|
||||
* Constant bias in depth-resolution units by which shadows are moved away from the
|
||||
* light. The default value of 0.5 is used to round depth values up.
|
||||
* Generally this value shouldn't be changed or at least be small and positive.
|
||||
* This is ignored when the View's ShadowType is set to VSM.
|
||||
*/
|
||||
float polygonOffsetConstant = 0.5f;
|
||||
|
||||
/**
|
||||
* Bias based on the change in depth in depth-resolution units by which shadows are moved
|
||||
* away from the light. The default value of 2.0 works well with SHADOW_SAMPLING_PCF_LOW.
|
||||
* Generally this value is between 0.5 and the size in texel of the PCF filter.
|
||||
* Setting this value correctly is essential for LISPSM shadow-maps.
|
||||
* This is ignored when the View's ShadowType is set to VSM.
|
||||
*/
|
||||
float polygonOffsetSlope = 2.0f;
|
||||
|
||||
/**
|
||||
* Whether screen-space contact shadows are used. This applies regardless of whether a
|
||||
@@ -332,6 +351,12 @@ public class LightManager {
|
||||
* The maximum value is 125.
|
||||
*/
|
||||
public float blurWidth = 0.0f;
|
||||
|
||||
/**
|
||||
* Light bulb radius used for soft shadows. Currently this is only used when DPCF is
|
||||
* enabled. (2cm by default).
|
||||
*/
|
||||
public float shadowBulbRadius = 0.02f;
|
||||
}
|
||||
|
||||
public static class ShadowCascades {
|
||||
@@ -430,6 +455,18 @@ public class LightManager {
|
||||
mFinalizer = new BuilderFinalizer(mNativeBuilder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables a light channel. Light channel 0 is enabled by default.
|
||||
*
|
||||
* @param channel Light channel to enable or disable, between 0 and 7.
|
||||
* @param enable Whether to enable or disable the light channel.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder lightChannel(@IntRange(from = 0, to = 7) int channel, boolean enable) {
|
||||
nBuilderLightChannel(mNativeBuilder, channel, enable);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this Light casts shadows (disabled by default)
|
||||
*
|
||||
@@ -459,9 +496,11 @@ public class LightManager {
|
||||
nBuilderShadowOptions(mNativeBuilder,
|
||||
options.mapSize, options.shadowCascades, options.cascadeSplitPositions,
|
||||
options.constantBias, options.normalBias, options.shadowFar, options.shadowNearHint,
|
||||
options.shadowFarHint, options.stable, options.screenSpaceContactShadows,
|
||||
options.shadowFarHint, options.stable,
|
||||
options.polygonOffsetConstant, options.polygonOffsetSlope,
|
||||
options.screenSpaceContactShadows,
|
||||
options.stepCount, options.maxShadowDistance, options.vsmMsaaSamples,
|
||||
options.blurWidth);
|
||||
options.blurWidth, options.shadowBulbRadius);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -750,7 +789,7 @@ public class LightManager {
|
||||
|
||||
@NonNull
|
||||
public Type getType(@EntityInstance int i) {
|
||||
return Type.values()[nGetType(mNativeObject, i)];
|
||||
return sTypeValues[nGetType(mNativeObject, i)];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -785,6 +824,30 @@ public class LightManager {
|
||||
return type == Type.SPOT || type == Type.FOCUSED_SPOT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables a light channel.
|
||||
* Light channel 0 is enabled by default.
|
||||
*
|
||||
* @param i Instance of the component obtained from getInstance().
|
||||
* @param channel Light channel to set
|
||||
* @param enable true to enable, false to disable
|
||||
*
|
||||
* @see Builder#lightChannel
|
||||
*/
|
||||
public void setLightChannel(@EntityInstance int i, @IntRange(from = 0, to = 7) int channel, boolean enable) {
|
||||
nSetLightChannel(mNativeObject, i, channel, enable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a light channel is enabled on a specified renderable.
|
||||
* @param i Instance of the component obtained from getInstance().
|
||||
* @param channel Light channel to query
|
||||
* @return true if the light channel is enabled, false otherwise
|
||||
*/
|
||||
public boolean getLightChannel(@EntityInstance int i, @IntRange(from = 0, to = 7) int channel) {
|
||||
return nGetLightChannel(mNativeObject, i, channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamically updates the light's position.
|
||||
*
|
||||
@@ -1095,7 +1158,7 @@ public class LightManager {
|
||||
private static native void nDestroyBuilder(long nativeBuilder);
|
||||
private static native boolean nBuilderBuild(long nativeBuilder, long nativeEngine, int entity);
|
||||
private static native void nBuilderCastShadows(long nativeBuilder, boolean enable);
|
||||
private static native void nBuilderShadowOptions(long nativeBuilder, int mapSize, int cascades, float[] splitPositions, float constantBias, float normalBias, float shadowFar, float shadowNearHint, float shadowFarhint, boolean stable, boolean screenSpaceContactShadows, int stepCount, float maxShadowDistance, int vsmMsaaSamples, float blurWidth);
|
||||
private static native void nBuilderShadowOptions(long nativeBuilder, int mapSize, int cascades, float[] splitPositions, float constantBias, float normalBias, float shadowFar, float shadowNearHint, float shadowFarhint, boolean stable, float polygonOffsetConstant, float polygonOffsetSlope, boolean screenSpaceContactShadows, int stepCount, float maxShadowDistance, int vsmMsaaSamples, float blurWidth, float shadowBulbRadius);
|
||||
private static native void nBuilderCastLight(long nativeBuilder, boolean enabled);
|
||||
private static native void nBuilderPosition(long nativeBuilder, float x, float y, float z);
|
||||
private static native void nBuilderDirection(long nativeBuilder, float x, float y, float z);
|
||||
@@ -1108,6 +1171,7 @@ public class LightManager {
|
||||
private static native void nBuilderAngularRadius(long nativeBuilder, float angularRadius);
|
||||
private static native void nBuilderHaloSize(long nativeBuilder, float haloSize);
|
||||
private static native void nBuilderHaloFalloff(long nativeBuilder, float haloFalloff);
|
||||
private static native void nBuilderLightChannel(long nativeBuilder, int channel, boolean enable);
|
||||
|
||||
private static native void nComputeUniformSplits(float[] splitPositions, int cascades);
|
||||
private static native void nComputeLogSplits(float[] splitPositions, int cascades, float near, float far);
|
||||
@@ -1137,4 +1201,6 @@ public class LightManager {
|
||||
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);
|
||||
private static native void nSetLightChannel(long nativeLightManager, int i, int channel, boolean enable);
|
||||
private static native boolean nGetLightChannel(long nativeLightManager, int i, int channel);
|
||||
}
|
||||
|
||||
@@ -37,6 +37,20 @@ import java.util.Set;
|
||||
* @see <a href="https://google.github.io/filament/Materials.html">Filament Materials Guide</a>
|
||||
*/
|
||||
public class Material {
|
||||
static final class EnumCache {
|
||||
private EnumCache() { }
|
||||
|
||||
static final Shading[] sShadingValues = Shading.values();
|
||||
static final Interpolation[] sInterpolationValues = Interpolation.values();
|
||||
static final BlendingMode[] sBlendingModeValues = BlendingMode.values();
|
||||
static final RefractionMode[] sRefractionModeValues = RefractionMode.values();
|
||||
static final RefractionType[] sRefractionTypeValues = RefractionType.values();
|
||||
static final VertexDomain[] sVertexDomainValues = VertexDomain.values();
|
||||
static final CullingMode[] sCullingModeValues = CullingMode.values();
|
||||
static final VertexBuffer.VertexAttribute[] sVertexAttributeValues =
|
||||
VertexBuffer.VertexAttribute.values();
|
||||
}
|
||||
|
||||
private long mNativeObject;
|
||||
private final MaterialInstance mDefaultInstance;
|
||||
|
||||
@@ -210,6 +224,8 @@ public class Material {
|
||||
|
||||
@UsedByNative("Material.cpp")
|
||||
public static class Parameter {
|
||||
private static final Type[] sTypeValues = Type.values();
|
||||
|
||||
public enum Type {
|
||||
BOOL,
|
||||
BOOL2,
|
||||
@@ -275,7 +291,7 @@ public class Material {
|
||||
@IntRange(from = 0) int type, @IntRange(from = 0) int precision,
|
||||
@IntRange(from = 1) int count) {
|
||||
parameters.add(
|
||||
new Parameter(name, Type.values()[type], Precision.values()[precision], count));
|
||||
new Parameter(name, sTypeValues[type], Precision.values()[precision], count));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -373,7 +389,7 @@ public class Material {
|
||||
* Material Models</a>
|
||||
*/
|
||||
public Shading getShading() {
|
||||
return Shading.values()[nGetShading(getNativeObject())];
|
||||
return EnumCache.sShadingValues[nGetShading(getNativeObject())];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -384,7 +400,7 @@ public class Material {
|
||||
* Vertex and attributes: interpolation</a>
|
||||
*/
|
||||
public Interpolation getInterpolation() {
|
||||
return Interpolation.values()[nGetInterpolation(getNativeObject())];
|
||||
return EnumCache.sInterpolationValues[nGetInterpolation(getNativeObject())];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -395,7 +411,7 @@ public class Material {
|
||||
* Blending and transparency: blending</a>
|
||||
*/
|
||||
public BlendingMode getBlendingMode() {
|
||||
return BlendingMode.values()[nGetBlendingMode(getNativeObject())];
|
||||
return EnumCache.sBlendingModeValues[nGetBlendingMode(getNativeObject())];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -406,7 +422,7 @@ public class Material {
|
||||
* Blending and transparency: refraction</a>
|
||||
*/
|
||||
public RefractionMode getRefractionMode() {
|
||||
return RefractionMode.values()[nGetRefractionMode(getNativeObject())];
|
||||
return EnumCache.sRefractionModeValues[nGetRefractionMode(getNativeObject())];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -417,10 +433,9 @@ public class Material {
|
||||
* Blending and transparency: refractionType</a>
|
||||
*/
|
||||
public RefractionType getRefractionType() {
|
||||
return RefractionType.values()[nGetRefractionType(getNativeObject())];
|
||||
return EnumCache.sRefractionTypeValues[nGetRefractionType(getNativeObject())];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the vertex domain of this material.
|
||||
*
|
||||
@@ -429,7 +444,7 @@ public class Material {
|
||||
* Vertex and attributes: vertexDomain</a>
|
||||
*/
|
||||
public VertexDomain getVertexDomain() {
|
||||
return VertexDomain.values()[nGetVertexDomain(getNativeObject())];
|
||||
return EnumCache.sVertexDomainValues[nGetVertexDomain(getNativeObject())];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -440,7 +455,7 @@ public class Material {
|
||||
* Rasterization: culling</a>
|
||||
*/
|
||||
public CullingMode getCullingMode() {
|
||||
return CullingMode.values()[nGetCullingMode(getNativeObject())];
|
||||
return EnumCache.sCullingModeValues[nGetCullingMode(getNativeObject())];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -531,7 +546,7 @@ public class Material {
|
||||
if (mRequiredAttributes == null) {
|
||||
int bitSet = nGetRequiredAttributes(getNativeObject());
|
||||
mRequiredAttributes = EnumSet.noneOf(VertexBuffer.VertexAttribute.class);
|
||||
VertexBuffer.VertexAttribute[] values = VertexBuffer.VertexAttribute.values();
|
||||
VertexBuffer.VertexAttribute[] values = EnumCache.sVertexAttributeValues;
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
if ((bitSet & (1 << i)) != 0) {
|
||||
mRequiredAttributes.add(values[i]);
|
||||
|
||||
@@ -56,6 +56,7 @@ public class MaterialInstance {
|
||||
|
||||
MaterialInstance(@NonNull Material material, long nativeMaterialInstance) {
|
||||
mMaterial = material;
|
||||
mNativeMaterial = material.getNativeObject();
|
||||
mNativeObject = nativeMaterialInstance;
|
||||
}
|
||||
|
||||
@@ -77,7 +78,7 @@ public class MaterialInstance {
|
||||
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 new MaterialInstance(other.getMaterial(), nativeInstance);
|
||||
}
|
||||
|
||||
/** @return the {@link Material} associated with this instance */
|
||||
@@ -238,6 +239,10 @@ public class MaterialInstance {
|
||||
|
||||
/**
|
||||
* Sets a texture and sampler parameter on this material's default instance.
|
||||
* <p>
|
||||
* Note: Depth textures can't be sampled with a linear filter unless the comparison mode is set
|
||||
* to COMPARE_TO_TEXTURE.
|
||||
* </p>
|
||||
*
|
||||
* @param name The name of the material texture parameter
|
||||
* @param texture The texture to set as parameter
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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 java.nio.Buffer;
|
||||
import java.nio.BufferOverflowException;
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
public class MorphTargetBuffer {
|
||||
private long mNativeObject;
|
||||
private MorphTargetBuffer(long nativeMorphTargetBuffer) {
|
||||
mNativeObject = nativeMorphTargetBuffer;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
|
||||
// Keep to finalize native resources
|
||||
private final MorphTargetBuffer.Builder.BuilderFinalizer mFinalizer;
|
||||
private final long mNativeBuilder;
|
||||
|
||||
public Builder() {
|
||||
mNativeBuilder = nCreateBuilder();
|
||||
mFinalizer = new MorphTargetBuffer.Builder.BuilderFinalizer(mNativeBuilder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Size of the morph targets in vertex counts.
|
||||
*
|
||||
* @param vertexCount Number of vertex counts the morph targets can hold.
|
||||
* @return this <code>Builder</code> object for chaining calls
|
||||
*/
|
||||
@NonNull
|
||||
public Builder vertexCount(@IntRange(from = 1) int vertexCount) {
|
||||
nBuilderVertexCount(mNativeBuilder, vertexCount);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Size of the morph targets in targets.
|
||||
*
|
||||
* @param count Number of targets the morph targets can hold.
|
||||
* @return this <code>Builder</code> object for chaining calls
|
||||
*/
|
||||
@NonNull
|
||||
public Builder count(@IntRange(from = 1) int count) {
|
||||
nBuilderCount(mNativeBuilder, count);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns the <code>MorphTargetBuffer</code> object.
|
||||
*
|
||||
* @param engine reference to the {@link Engine} to associate this <code>MorphTargetBuffer</code>
|
||||
* with.
|
||||
*
|
||||
* @return the newly created <code>MorphTargetBuffer</code> object
|
||||
*
|
||||
* @exception IllegalStateException if the MorphTargetBuffer could not be created
|
||||
*
|
||||
* @see #setMorphTargetBufferAt
|
||||
*/
|
||||
@NonNull
|
||||
public MorphTargetBuffer build(@NonNull Engine engine) {
|
||||
long nativeMorphTargetBuffer = nBuilderBuild(mNativeBuilder, engine.getNativeObject());
|
||||
if (nativeMorphTargetBuffer == 0)
|
||||
throw new IllegalStateException("Couldn't create MorphTargetBuffer");
|
||||
return new MorphTargetBuffer(nativeMorphTargetBuffer);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates positions of morph target at the index.
|
||||
*
|
||||
* @param engine {@link Engine} instance
|
||||
* @param targetIndex The index of morph target to be updated
|
||||
* @param positions Pointer to at least count positions
|
||||
* @param count Number of position elements in positions
|
||||
*/
|
||||
public void setPositionsAt(@NonNull Engine engine,
|
||||
@IntRange(from = 0) int targetIndex,
|
||||
@NonNull float[] positions, @IntRange(from = 0, to = 125) int count) {
|
||||
int result = nSetPositionsAt(mNativeObject, engine.getNativeObject(), targetIndex,
|
||||
positions, count);
|
||||
if (result < 0) {
|
||||
throw new BufferOverflowException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates tangents of morph target at the index.
|
||||
*
|
||||
* @param engine {@link Engine} instance
|
||||
* @param targetIndex The index of morph target to be updated
|
||||
* @param tangents Pointer to at least count tangents
|
||||
* @param count Number of tangent elements in tangents
|
||||
*/
|
||||
public void setTangentsAt(@NonNull Engine engine,
|
||||
@IntRange(from = 0) int targetIndex,
|
||||
@NonNull short[] tangents, @IntRange(from = 0, to = 125) int count) {
|
||||
int result = nSetTangentsAt(mNativeObject, engine.getNativeObject(), targetIndex,
|
||||
tangents, count);
|
||||
if (result < 0) {
|
||||
throw new BufferOverflowException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return number of vertex count in this {@link MorphTargetBuffer}
|
||||
*/
|
||||
public int getVertexCount() {
|
||||
return nGetVertexCount(mNativeObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return number of target count in this {@link MorphTargetBuffer}
|
||||
*/
|
||||
public int getCount() {
|
||||
return nGetCount(mNativeObject);
|
||||
}
|
||||
|
||||
public long getNativeObject() {
|
||||
if (mNativeObject == 0) {
|
||||
throw new IllegalStateException("Calling method on destroyed MorphTargetBuffer");
|
||||
}
|
||||
return mNativeObject;
|
||||
}
|
||||
|
||||
void clearNativeObject() {
|
||||
mNativeObject = 0;
|
||||
}
|
||||
|
||||
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 nBuilderCount(long nativeBuilder, int count);
|
||||
private static native long nBuilderBuild(long nativeBuilder, long nativeEngine);
|
||||
|
||||
private static native int nSetPositionsAt(long nativeObject, long nativeEngine, int targetIndex, float[] positions, int count);
|
||||
private static native int nSetTangentsAt(long nativeObject, long nativeEngine, int targetIndex, short[] tangents, int count);
|
||||
private static native int nGetVertexCount(long nativeObject);
|
||||
private static native int nGetCount(long nativeObject);
|
||||
}
|
||||
@@ -31,8 +31,10 @@ import androidx.annotation.Nullable;
|
||||
* @see View
|
||||
*/
|
||||
public class RenderTarget {
|
||||
private long mNativeObject;
|
||||
private static final int ATTACHMENT_COUNT = AttachmentPoint.values().length;
|
||||
private static final Texture.CubemapFace[] sCubemapFaceValues = Texture.CubemapFace.values();
|
||||
|
||||
private long mNativeObject;
|
||||
private final Texture[] mTextures = new Texture[ATTACHMENT_COUNT];
|
||||
|
||||
private RenderTarget(long nativeRenderTarget, Builder builder) {
|
||||
@@ -194,7 +196,7 @@ public class RenderTarget {
|
||||
* a cubemap.
|
||||
*/
|
||||
public Texture.CubemapFace getFace(AttachmentPoint attachment) {
|
||||
return Texture.CubemapFace.values()[nGetFace(getNativeObject(), attachment.ordinal())];
|
||||
return sCubemapFaceValues[nGetFace(getNativeObject(), attachment.ordinal())];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -58,6 +58,10 @@ import java.util.Set;
|
||||
*/
|
||||
public class RenderableManager {
|
||||
private static final String LOG_TAG = "Filament";
|
||||
|
||||
private static final VertexBuffer.VertexAttribute[] sVertexAttributeValues =
|
||||
VertexBuffer.VertexAttribute.values();
|
||||
|
||||
private long mNativeObject;
|
||||
|
||||
RenderableManager(long nativeRenderableManager) {
|
||||
@@ -92,7 +96,9 @@ public class RenderableManager {
|
||||
public enum PrimitiveType {
|
||||
POINTS(0),
|
||||
LINES(1),
|
||||
TRIANGLES(4);
|
||||
LINE_STRIP(3),
|
||||
TRIANGLES(4),
|
||||
TRIANGLE_STRIP(5);
|
||||
|
||||
private final int mType;
|
||||
PrimitiveType(int value) { mType = value; }
|
||||
@@ -266,6 +272,34 @@ public class RenderableManager {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables a light channel. Light channel 0 is enabled by default.
|
||||
*
|
||||
* @param channel Light channel to enable or disable, between 0 and 7.
|
||||
* @param enable Whether to enable or disable the light channel.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder lightChannel(@IntRange(from = 0, to = 7) int channel, boolean enable) {
|
||||
nBuilderLightChannel(mNativeBuilder, channel, enable);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the number of draw instance of this renderable. The default is 1 instance and
|
||||
* the maximum number of instances allowed is 65535. 0 is invalid.
|
||||
* All instances are culled using the same bounding box, so care must be taken to make
|
||||
* sure all instances render inside the specified bounding box.
|
||||
* The material can use getInstanceIndex() in the vertex shader to get the instance index and
|
||||
* possibly adjust the position or transform.
|
||||
*
|
||||
* @param instanceCount the number of instances silently clamped between 1 and 65535.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder instances(@IntRange(from = 1, to = 65535) int instanceCount) {
|
||||
nBuilderInstances(mNativeBuilder, instanceCount);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls if this renderable casts shadows, false by default.
|
||||
*
|
||||
@@ -382,17 +416,67 @@ public class RenderableManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls if the renderable has vertex morphing targets, false by default.
|
||||
* Controls if the renderable has vertex morphing targets, zero by default. This is
|
||||
* required to enable GPU morphing.
|
||||
*
|
||||
* <p>This is required to enable GPU morphing for up to 4 attributes. The attached VertexBuffer
|
||||
* must provide data in the appropriate VertexAttribute slots (<code>MORPH_POSITION_0</code> etc).</p>
|
||||
* <p>Filament supports two morphing modes: standard (default) and legacy.</p>
|
||||
*
|
||||
* <p>For standard morphing, A {@link MorphTargetBuffer} must be created and provided via
|
||||
* {@link RenderableManager#setMorphTargetBufferAt}. Standard morphing supports up to
|
||||
* <code>CONFIG_MAX_MORPH_TARGET_COUNT</code> morph targets.</p>
|
||||
*
|
||||
* For legacy morphing, the attached {@link VertexBuffer} must provide data in the
|
||||
* appropriate {@link VertexBuffer.VertexAttribute} slots (<code>MORPH_POSITION_0</code> etc).
|
||||
* Legacy morphing only supports up to 4 morph targets and will be deprecated in the future.
|
||||
* Legacy morphing must be enabled on the material definition: either via the
|
||||
* <code>legacyMorphing</code> material attribute or by calling
|
||||
* {@link MaterialBuilder::useLegacyMorphing}.
|
||||
*
|
||||
* <p>See also {@link RenderableManager#setMorphWeights}, which can be called on a per-frame basis
|
||||
* to advance the animation.</p>
|
||||
*/
|
||||
@NonNull
|
||||
public Builder morphing(boolean enabled) {
|
||||
nBuilderMorphing(mNativeBuilder, enabled);
|
||||
public Builder morphing(@IntRange(from = 0, to = 255) int targetCount) {
|
||||
nBuilderMorphing(mNativeBuilder, targetCount);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the morph target buffer for a primitive.
|
||||
*
|
||||
* The morph target buffer must have an associated renderable and geometry. Two conditions
|
||||
* must be met:
|
||||
* 1. The number of morph targets in the buffer must equal the renderable's morph target
|
||||
* count.
|
||||
* 2. The vertex count of each morph target must equal the geometry's vertex count.
|
||||
*
|
||||
* @param level the level of detail (lod), only 0 can be specified
|
||||
* @param primitiveIndex zero-based index of the primitive, must be less than the count passed to Builder constructor
|
||||
* @param morphTargetBuffer specifies the morph target buffer
|
||||
* @param offset specifies where in the morph target buffer to start reading (expressed as a number of vertices)
|
||||
* @param count number of vertices in the morph target buffer to read, must equal the geometry's count (for triangles, this should be a multiple of 3)
|
||||
*/
|
||||
@NonNull
|
||||
public Builder morphing(@IntRange(from = 0) int level,
|
||||
@IntRange(from = 0) int primitiveIndex,
|
||||
@NonNull MorphTargetBuffer morphTargetBuffer,
|
||||
@IntRange(from = 0) int offset,
|
||||
@IntRange(from = 0) int count) {
|
||||
nBuilderSetMorphTargetBufferAt(mNativeBuilder, level, primitiveIndex,
|
||||
morphTargetBuffer.getNativeObject(), offset, count);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to specify morph target buffer for a primitive.
|
||||
* For details, see the {@link RenderableManager.Builder#morphing}.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder morphing(@IntRange(from = 0) int level,
|
||||
@IntRange(from = 0) int primitiveIndex,
|
||||
@NonNull MorphTargetBuffer morphTargetBuffer) {
|
||||
nBuilderSetMorphTargetBufferAt(mNativeBuilder, level, primitiveIndex,
|
||||
morphTargetBuffer.getNativeObject(), 0, morphTargetBuffer.getVertexCount());
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -479,15 +563,50 @@ public class RenderableManager {
|
||||
/**
|
||||
* Updates the vertex morphing weights on a renderable, all zeroes by default.
|
||||
*
|
||||
* <p>This is specified using a 4-tuple, one float per morph target. If the renderable has fewer
|
||||
* than 4 morph targets, then clients should fill the unused components with zeroes.</p>
|
||||
* <p>The renderable must be built with morphing enabled. In legacy morphing mode, only the
|
||||
* first 4 weights are considered.</p>
|
||||
*
|
||||
* @see Builder#morphing
|
||||
*/
|
||||
public void setMorphWeights(@EntityInstance int i, @NonNull float[] weights, @IntRange(from = 0) int offset) {
|
||||
nSetMorphWeights(mNativeObject, i, weights, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the morph target buffer for the given primitive.
|
||||
*
|
||||
* <p>The renderable must be built with morphing enabled.</p>
|
||||
*
|
||||
* @see Builder#morphing
|
||||
*/
|
||||
public void setMorphWeights(@EntityInstance int i, @NonNull @Size(min = 4) float[] weights) {
|
||||
nSetMorphWeights(mNativeObject, i, weights);
|
||||
public void setMorphTargetBufferAt(@EntityInstance int i,
|
||||
@IntRange(from = 0) int level,
|
||||
@IntRange(from = 0) int primitiveIndex,
|
||||
@NonNull MorphTargetBuffer morphTargetBuffer,
|
||||
@IntRange(from = 0) int offset,
|
||||
@IntRange(from = 0) int count) {
|
||||
nSetMorphTargetBufferAt(mNativeObject, i, level, primitiveIndex,
|
||||
morphTargetBuffer.getNativeObject(), offset, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to change morph target buffer for the given primitive.
|
||||
* For details, see the {@link RenderableManager#setMorphTargetBufferAt}.
|
||||
*/
|
||||
public void setMorphTargetBufferAt(@EntityInstance int i,
|
||||
@IntRange(from = 0) int level,
|
||||
@IntRange(from = 0) int primitiveIndex,
|
||||
@NonNull MorphTargetBuffer morphTargetBuffer) {
|
||||
nSetMorphTargetBufferAt(mNativeObject, i, level, primitiveIndex,
|
||||
morphTargetBuffer.getNativeObject(), 0, morphTargetBuffer.getVertexCount());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the morph target count on a renderable.
|
||||
*/
|
||||
@IntRange(from = 0)
|
||||
public int getMorphTargetCount(@EntityInstance int i) {
|
||||
return nGetMorphTargetCount(mNativeObject, i);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -531,6 +650,30 @@ public class RenderableManager {
|
||||
nSetCulling(mNativeObject, i, enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables a light channel.
|
||||
* Light channel 0 is enabled by default.
|
||||
*
|
||||
* @param i Instance of the component obtained from getInstance().
|
||||
* @param channel Light channel to set
|
||||
* @param enable true to enable, false to disable
|
||||
*
|
||||
* @see Builder#lightChannel
|
||||
*/
|
||||
public void setLightChannel(@EntityInstance int i, @IntRange(from = 0, to = 7) int channel, boolean enable) {
|
||||
nSetLightChannel(mNativeObject, i, channel, enable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a light channel is enabled on a specified renderable.
|
||||
* @param i Instance of the component obtained from getInstance().
|
||||
* @param channel Light channel to query
|
||||
* @return true if the light channel is enabled, false otherwise
|
||||
*/
|
||||
public boolean getLightChannel(@EntityInstance int i, @IntRange(from = 0, to = 7) int channel) {
|
||||
return nGetLightChannel(mNativeObject, i, channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes whether or not the renderable casts shadows.
|
||||
*
|
||||
@@ -676,15 +819,19 @@ public class RenderableManager {
|
||||
/**
|
||||
* Retrieves the set of enabled attribute slots in the given primitive's VertexBuffer.
|
||||
*/
|
||||
public Set<VertexBuffer.VertexAttribute> getEnabledAttributesAt(@EntityInstance int i, @IntRange(from = 0) int primitiveIndex) {
|
||||
public Set<VertexBuffer.VertexAttribute> getEnabledAttributesAt(
|
||||
@EntityInstance int i, @IntRange(from = 0) int primitiveIndex) {
|
||||
int bitSet = nGetEnabledAttributesAt(mNativeObject, i, primitiveIndex);
|
||||
Set<VertexBuffer.VertexAttribute> requiredAttributes = EnumSet.noneOf(VertexBuffer.VertexAttribute.class);
|
||||
VertexBuffer.VertexAttribute[] values = VertexBuffer.VertexAttribute.values();
|
||||
Set<VertexBuffer.VertexAttribute> requiredAttributes =
|
||||
EnumSet.noneOf(VertexBuffer.VertexAttribute.class);
|
||||
VertexBuffer.VertexAttribute[] values = sVertexAttributeValues;
|
||||
|
||||
for (int j = 0; j < values.length; j++) {
|
||||
if ((bitSet & (1 << j)) != 0) {
|
||||
requiredAttributes.add(values[j]);
|
||||
}
|
||||
}
|
||||
|
||||
requiredAttributes = Collections.unmodifiableSet(requiredAttributes);
|
||||
return requiredAttributes;
|
||||
}
|
||||
@@ -716,17 +863,24 @@ public class RenderableManager {
|
||||
private static native void nBuilderSkinning(long nativeBuilder, int boneCount);
|
||||
private static native int nBuilderSkinningBones(long nativeBuilder, int boneCount, Buffer bones, int remaining);
|
||||
private static native void nBuilderSkinningBuffer(long nativeBuilder, long nativeSkinningBuffer, int boneCount, int offset);
|
||||
private static native void nBuilderMorphing(long nativeBuilder, boolean enabled);
|
||||
private static native void nBuilderMorphing(long nativeBuilder, int targetCount);
|
||||
private static native void nBuilderSetMorphTargetBufferAt(long nativeBuilder, int level, int primitiveIndex, long nativeMorphTargetBuffer, int offset, int count);
|
||||
private static native void nEnableSkinningBuffers(long nativeBuilder, boolean enabled);
|
||||
private static native void nBuilderLightChannel(long nativeRenderableManager, int channel, boolean enable);
|
||||
private static native void nBuilderInstances(long nativeRenderableManager, int instances);
|
||||
|
||||
private static native void nSetSkinningBuffer(long nativeObject, int i, long nativeSkinningBuffer, int count, int offset);
|
||||
private static native int nSetBonesAsMatrices(long nativeObject, int i, Buffer matrices, int remaining, int boneCount, int offset);
|
||||
private static native int nSetBonesAsQuaternions(long nativeObject, int i, Buffer quaternions, int remaining, int boneCount, int offset);
|
||||
private static native void nSetMorphWeights(long nativeObject, int instance, float[] weights);
|
||||
private static native void nSetMorphWeights(long nativeObject, int instance, float[] weights, int offset);
|
||||
private static native void nSetMorphTargetBufferAt(long nativeObject, int i, int level, int primitiveIndex, long nativeMorphTargetBuffer, int offset, int count);
|
||||
private static native int nGetMorphTargetCount(long nativeObject, int i);
|
||||
private static native void nSetAxisAlignedBoundingBox(long nativeRenderableManager, int i, float cx, float cy, float cz, float ex, float ey, float ez);
|
||||
private static native void nSetLayerMask(long nativeRenderableManager, int i, int select, int value);
|
||||
private static native void nSetPriority(long nativeRenderableManager, int i, int priority);
|
||||
private static native void nSetCulling(long nativeRenderableManager, int i, boolean enabled);
|
||||
private static native void nSetLightChannel(long nativeRenderableManager, int i, int channel, boolean enable);
|
||||
private static native boolean nGetLightChannel(long nativeRenderableManager, int i, int channel);
|
||||
private static native void nSetCastShadows(long nativeRenderableManager, int i, boolean enabled);
|
||||
private static native void nSetReceiveShadows(long nativeRenderableManager, int i, boolean enabled);
|
||||
private static native void nSetScreenSpaceContactShadows(long nativeRenderableManager, int i, boolean enabled);
|
||||
|
||||
@@ -107,12 +107,12 @@ public class Renderer {
|
||||
/**
|
||||
* Rate at which the scale will change to reach the target frame rate.
|
||||
*/
|
||||
public float scaleRate = 0.125f;
|
||||
public float scaleRate = 1.0f / 15.0f;
|
||||
|
||||
/**
|
||||
* History size. higher values, tend to filter more (clamped to 30).
|
||||
* History size. higher values, tend to filter more (clamped to 31).
|
||||
*/
|
||||
public int history = 9;
|
||||
public int history = 15;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -309,7 +309,7 @@ public class Renderer {
|
||||
*
|
||||
* <p><code>render()</code> generates commands for each of the following stages:</p>
|
||||
* <ul>
|
||||
* <li>Shadow map pass, if needed (currently only a single shadow map is supported)</li>
|
||||
* <li>Shadow map passes, if needed</li>
|
||||
* <li>Depth pre-pass</li>
|
||||
* <li>SSAO pass, if enabled</li>
|
||||
* <li>Color pass</li>
|
||||
@@ -437,8 +437,9 @@ public class Renderer {
|
||||
*</pre>
|
||||
*
|
||||
*
|
||||
* <p>Typically <code>readPixels</code> will be called after {@link #render} and before
|
||||
* {@link #endFrame}.</p>
|
||||
* <p><code>readPixels</code> must be called within a frame, meaning after {@link #beginFrame}
|
||||
* and before {@link #endFrame}. Typically, <code>readPixels</code> will be called after
|
||||
* {@link #render}.</p>
|
||||
* <br>
|
||||
* <p>After calling this method, the callback associated with <code>buffer</code>
|
||||
* will be invoked on the main thread, indicating that the read-back has completed.
|
||||
|
||||
@@ -118,8 +118,8 @@ public class SkinningBuffer {
|
||||
* @param offset Index of the first bone to set
|
||||
*/
|
||||
public void setBonesAsMatrices(@NonNull Engine engine,
|
||||
@NonNull Buffer matrices, @IntRange(from = 0, to = 255) int boneCount,
|
||||
@IntRange(from = 0) int offset) {
|
||||
@NonNull Buffer matrices, @IntRange(from = 0, to = 255) int boneCount,
|
||||
@IntRange(from = 0) int offset) {
|
||||
int result = nSetBonesAsMatrices(mNativeObject, engine.getNativeObject(),
|
||||
matrices, matrices.remaining(), boneCount, offset);
|
||||
if (result < 0) {
|
||||
@@ -138,8 +138,8 @@ public class SkinningBuffer {
|
||||
* @param offset Index of the first bone to set
|
||||
*/
|
||||
public void setBonesAsQuaternions(@NonNull Engine engine,
|
||||
@NonNull Buffer quaternions, @IntRange(from = 0, to = 255) int boneCount,
|
||||
@IntRange(from = 0) int offset) {
|
||||
@NonNull Buffer quaternions, @IntRange(from = 0, to = 255) int boneCount,
|
||||
@IntRange(from = 0) int offset) {
|
||||
int result = nSetBonesAsQuaternions(mNativeObject, engine.getNativeObject(),
|
||||
quaternions, quaternions.remaining(), boneCount, offset);
|
||||
if (result < 0) {
|
||||
|
||||
@@ -91,6 +91,8 @@ import java.nio.ReadOnlyBufferException;
|
||||
* @see Engine#destroyStream
|
||||
*/
|
||||
public class Stream {
|
||||
private static final StreamType[] sStreamTypeValues = StreamType.values();
|
||||
|
||||
private long mNativeObject;
|
||||
private long mNativeEngine;
|
||||
|
||||
@@ -236,7 +238,7 @@ public class Stream {
|
||||
* Indicates whether this <code>Stream</code> is NATIVE, TEXTURE_ID, or ACQUIRED.
|
||||
*/
|
||||
public StreamType getStreamType() {
|
||||
return StreamType.values()[nGetStreamType(getNativeObject())];
|
||||
return sStreamTypeValues[nGetStreamType(getNativeObject())];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -71,6 +71,9 @@ import static com.google.android.filament.Texture.Type.COMPRESSED;
|
||||
* @see MaterialInstance#setParameter(String, Texture, TextureSampler)
|
||||
*/
|
||||
public class Texture {
|
||||
private static final Sampler[] sSamplerValues = Sampler.values();
|
||||
private static final InternalFormat[] sInternalFormatValues = InternalFormat.values();
|
||||
|
||||
private long mNativeObject;
|
||||
|
||||
public Texture(long nativeTexture) {
|
||||
@@ -216,7 +219,38 @@ public class Texture {
|
||||
ETC2_EAC_RGBA8, ETC2_EAC_SRGBA8,
|
||||
|
||||
// Available everywhere except Android/iOS
|
||||
DXT1_RGB, DXT1_RGBA, DXT3_RGBA, DXT5_RGBA
|
||||
DXT1_RGB, DXT1_RGBA, DXT3_RGBA, DXT5_RGBA,
|
||||
DXT1_SRGB, DXT1_SRGBA, DXT3_SRGBA, DXT5_SRGBA,
|
||||
|
||||
// ASTC formats are available with a GLES extension
|
||||
RGBA_ASTC_4x4,
|
||||
RGBA_ASTC_5x4,
|
||||
RGBA_ASTC_5x5,
|
||||
RGBA_ASTC_6x5,
|
||||
RGBA_ASTC_6x6,
|
||||
RGBA_ASTC_8x5,
|
||||
RGBA_ASTC_8x6,
|
||||
RGBA_ASTC_8x8,
|
||||
RGBA_ASTC_10x5,
|
||||
RGBA_ASTC_10x6,
|
||||
RGBA_ASTC_10x8,
|
||||
RGBA_ASTC_10x10,
|
||||
RGBA_ASTC_12x10,
|
||||
RGBA_ASTC_12x12,
|
||||
SRGB8_ALPHA8_ASTC_4x4,
|
||||
SRGB8_ALPHA8_ASTC_5x4,
|
||||
SRGB8_ALPHA8_ASTC_5x5,
|
||||
SRGB8_ALPHA8_ASTC_6x5,
|
||||
SRGB8_ALPHA8_ASTC_6x6,
|
||||
SRGB8_ALPHA8_ASTC_8x5,
|
||||
SRGB8_ALPHA8_ASTC_8x6,
|
||||
SRGB8_ALPHA8_ASTC_8x8,
|
||||
SRGB8_ALPHA8_ASTC_10x5,
|
||||
SRGB8_ALPHA8_ASTC_10x6,
|
||||
SRGB8_ALPHA8_ASTC_10x8,
|
||||
SRGB8_ALPHA8_ASTC_10x10,
|
||||
SRGB8_ALPHA8_ASTC_12x10,
|
||||
SRGB8_ALPHA8_ASTC_12x12
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -231,7 +265,38 @@ public class Texture {
|
||||
ETC2_EAC_RGBA8, ETC2_EAC_SRGBA8,
|
||||
|
||||
// Available everywhere except Android/iOS
|
||||
DXT1_RGB, DXT1_RGBA, DXT3_RGBA, DXT5_RGBA
|
||||
DXT1_RGB, DXT1_RGBA, DXT3_RGBA, DXT5_RGBA,
|
||||
DXT1_SRGB, DXT1_SRGBA, DXT3_SRGBA, DXT5_SRGBA,
|
||||
|
||||
// ASTC formats are available with a GLES extension
|
||||
RGBA_ASTC_4x4,
|
||||
RGBA_ASTC_5x4,
|
||||
RGBA_ASTC_5x5,
|
||||
RGBA_ASTC_6x5,
|
||||
RGBA_ASTC_6x6,
|
||||
RGBA_ASTC_8x5,
|
||||
RGBA_ASTC_8x6,
|
||||
RGBA_ASTC_8x8,
|
||||
RGBA_ASTC_10x5,
|
||||
RGBA_ASTC_10x6,
|
||||
RGBA_ASTC_10x8,
|
||||
RGBA_ASTC_10x10,
|
||||
RGBA_ASTC_12x10,
|
||||
RGBA_ASTC_12x12,
|
||||
SRGB8_ALPHA8_ASTC_4x4,
|
||||
SRGB8_ALPHA8_ASTC_5x4,
|
||||
SRGB8_ALPHA8_ASTC_5x5,
|
||||
SRGB8_ALPHA8_ASTC_6x5,
|
||||
SRGB8_ALPHA8_ASTC_6x6,
|
||||
SRGB8_ALPHA8_ASTC_8x5,
|
||||
SRGB8_ALPHA8_ASTC_8x6,
|
||||
SRGB8_ALPHA8_ASTC_8x8,
|
||||
SRGB8_ALPHA8_ASTC_10x5,
|
||||
SRGB8_ALPHA8_ASTC_10x6,
|
||||
SRGB8_ALPHA8_ASTC_10x8,
|
||||
SRGB8_ALPHA8_ASTC_10x10,
|
||||
SRGB8_ALPHA8_ASTC_12x10,
|
||||
SRGB8_ALPHA8_ASTC_12x12
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -477,7 +542,7 @@ public class Texture {
|
||||
* @param alignment Alignment in bytes.
|
||||
* @return Size of the buffer in bytes.
|
||||
*/
|
||||
static int computeDataSize(@NonNull Format format, @NonNull Type type,
|
||||
public static int computeDataSize(@NonNull Format format, @NonNull Type type,
|
||||
int stride, int height, @IntRange(from = 1, to = 8) int alignment) {
|
||||
if (type == Type.COMPRESSED) {
|
||||
return 0;
|
||||
@@ -805,7 +870,7 @@ public class Texture {
|
||||
*/
|
||||
@NonNull
|
||||
public Sampler getTarget() {
|
||||
return Sampler.values()[nGetTarget(getNativeObject())];
|
||||
return sSamplerValues[nGetTarget(getNativeObject())];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -813,7 +878,7 @@ public class Texture {
|
||||
*/
|
||||
@NonNull
|
||||
public InternalFormat getFormat() {
|
||||
return InternalFormat.values()[nGetInternalFormat(getNativeObject())];
|
||||
return sInternalFormatValues[nGetInternalFormat(getNativeObject())];
|
||||
}
|
||||
|
||||
// TODO: add a setImage() version that takes an android Bitmap
|
||||
|
||||
@@ -22,6 +22,14 @@ import androidx.annotation.NonNull;
|
||||
* <code>TextureSampler</code> defines how a texture is accessed.
|
||||
*/
|
||||
public class TextureSampler {
|
||||
static final class EnumCache {
|
||||
static final MinFilter[] sMinFilterValues = MinFilter.values();
|
||||
static final MagFilter[] sMagFilterValues = MagFilter.values();
|
||||
static final WrapMode[] sWrapModeValues = WrapMode.values();
|
||||
static final CompareMode[] sCompareModeValues = CompareMode.values();
|
||||
static final CompareFunction[] sCompareFunctionValues = CompareFunction.values();
|
||||
}
|
||||
|
||||
public enum WrapMode {
|
||||
/**
|
||||
* The edge of the texture extends to infinity.
|
||||
@@ -202,7 +210,7 @@ public class TextureSampler {
|
||||
* @return the minification filter
|
||||
*/
|
||||
public MinFilter getMinFilter() {
|
||||
return MinFilter.values()[nGetMinFilter(mSampler)];
|
||||
return EnumCache.sMinFilterValues[nGetMinFilter(mSampler)];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -218,7 +226,7 @@ public class TextureSampler {
|
||||
* @return the magnification filter
|
||||
*/
|
||||
public MagFilter getMagFilter() {
|
||||
return MagFilter.values()[nGetMagFilter(mSampler)];
|
||||
return EnumCache.sMagFilterValues[nGetMagFilter(mSampler)];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -234,7 +242,7 @@ public class TextureSampler {
|
||||
* @return the wrapping mode in the s (horizontal) direction
|
||||
*/
|
||||
public WrapMode getWrapModeS() {
|
||||
return WrapMode.values()[nGetWrapModeS(mSampler)];
|
||||
return EnumCache.sWrapModeValues[nGetWrapModeS(mSampler)];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -249,7 +257,7 @@ public class TextureSampler {
|
||||
* @return the wrapping mode in the t (vertical) direction
|
||||
*/
|
||||
public WrapMode getWrapModeT() {
|
||||
return WrapMode.values()[nGetWrapModeT(mSampler)];
|
||||
return EnumCache.sWrapModeValues[nGetWrapModeT(mSampler)];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -264,7 +272,7 @@ public class TextureSampler {
|
||||
* @return the wrapping mode in the r (depth) direction
|
||||
*/
|
||||
public WrapMode getWrapModeR() {
|
||||
return WrapMode.values()[nGetWrapModeR(mSampler)];
|
||||
return EnumCache.sWrapModeValues[nGetWrapModeR(mSampler)];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -297,7 +305,7 @@ public class TextureSampler {
|
||||
* @return the comparison mode
|
||||
*/
|
||||
public CompareMode getCompareMode() {
|
||||
return CompareMode.values()[nGetCompareMode(mSampler)];
|
||||
return EnumCache.sCompareModeValues[nGetCompareMode(mSampler)];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -313,7 +321,7 @@ public class TextureSampler {
|
||||
* @return the comparison function
|
||||
*/
|
||||
public CompareFunction getCompareFunction() {
|
||||
return CompareFunction.values()[nGetCompareFunction(mSampler)];
|
||||
return EnumCache.sCompareFunctionValues[nGetCompareFunction(mSampler)];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
package com.google.android.filament;
|
||||
|
||||
/**
|
||||
* Interface for tone mapping operators. A tone mapping operator, or tone mapper,
|
||||
* is responsible for compressing the dynamic range of the rendered scene to a
|
||||
* dynamic range suitable for display.
|
||||
*
|
||||
* In Filament, tone mapping is a color grading step. ToneMapper instances are
|
||||
* created and passed to the ColorGrading::Builder to produce a 3D LUT that will
|
||||
* be used during post-processing to prepare the final color buffer for display.
|
||||
*
|
||||
* Filament provides several default tone mapping operators that fall into three
|
||||
* categories:
|
||||
*
|
||||
* <ul>
|
||||
* <li>Configurable tone mapping operators</li>
|
||||
* <ul>
|
||||
* <li>GenericToneMapper</li>
|
||||
* </ul>
|
||||
* <li>Fixed-aesthetic tone mapping operators</li>
|
||||
* <ul>
|
||||
* <li>ACESToneMapper</li>
|
||||
* <li>ACESLegacyToneMapper</li>
|
||||
* <li>FilmicToneMapper</li>
|
||||
* </ul>
|
||||
* <li>Debug/validation tone mapping operators</li>
|
||||
* <ul>
|
||||
* <li>LinearToneMapper</li>
|
||||
* <li>DisplayRangeToneMapper</li>
|
||||
* </ul>
|
||||
* </ul>
|
||||
*
|
||||
* You can create custom tone mapping operators by subclassing ToneMapper.
|
||||
*/
|
||||
public class ToneMapper {
|
||||
private final long mNativeObject;
|
||||
|
||||
private ToneMapper(long nativeObject) {
|
||||
mNativeObject = nativeObject;
|
||||
}
|
||||
|
||||
public long getNativeObject() {
|
||||
if (mNativeObject == 0) {
|
||||
throw new IllegalStateException("Calling method on destroyed ToneMapper");
|
||||
}
|
||||
return mNativeObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
super.finalize();
|
||||
} finally {
|
||||
nDestroyToneMapper(mNativeObject);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Linear tone mapping operator that returns the input color but clamped to
|
||||
* the 0..1 range. This operator is mostly useful for debugging.
|
||||
*/
|
||||
public static class Linear extends ToneMapper {
|
||||
public Linear() {
|
||||
super(nCreateLinearToneMapper());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ACES tone mapping operator. This operator is an implementation of the
|
||||
* ACES Reference Rendering Transform (RRT) combined with the Output Device
|
||||
* Transform (ODT) for sRGB monitors (dim surround, 100 nits).
|
||||
*/
|
||||
public static class ACES extends ToneMapper {
|
||||
public ACES() {
|
||||
super(nCreateACESToneMapper());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ACES tone mapping operator, modified to match the perceived brightness
|
||||
* of FilmicToneMapper. This operator is the same as ACESToneMapper but
|
||||
* applies a brightness multiplier of ~1.6 to the input color value to
|
||||
* target brighter viewing environments.
|
||||
*/
|
||||
public static class ACESLegacy extends ToneMapper {
|
||||
public ACESLegacy() {
|
||||
super(nCreateACESLegacyToneMapper());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* "Filmic" tone mapping operator. This tone mapper was designed to
|
||||
* approximate the aesthetics of the ACES RRT + ODT for Rec.709
|
||||
* and historically Filament's default tone mapping operator. It exists
|
||||
* only for backward compatibility purposes and is not otherwise recommended.
|
||||
*/
|
||||
public static class Filmic extends ToneMapper {
|
||||
public Filmic() {
|
||||
super(nCreateFilmicToneMapper());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic tone mapping operator that gives control over the tone mapping
|
||||
* curve. This operator can be used to control the aesthetics of the final
|
||||
* image. This operator also allows to control the dynamic range of the
|
||||
* scene referred values.
|
||||
*
|
||||
* The tone mapping curve is defined by 5 parameters:
|
||||
* <ul>
|
||||
* <li>contrast: controls the contrast of the curve</li>
|
||||
* referred values map to output white</li>
|
||||
* <li>midGrayIn: sets the input middle gray</li>
|
||||
* <li>midGrayOut: sets the output middle gray</li>
|
||||
* <li>hdrMax: defines the maximum input value that will be mapped to
|
||||
* output white</li>
|
||||
* </ul>
|
||||
*/
|
||||
public static class Generic extends ToneMapper {
|
||||
/**
|
||||
* Builds a new generic tone mapper parameterized to closely approximate
|
||||
* the {@link ACESLegacy} tone mapper. The default values are:
|
||||
*
|
||||
* <ul>
|
||||
* <li>contrast = 1.55f</li>
|
||||
* <li>midGrayIn = 0.18f</li>
|
||||
* <li>midGrayOut = 0.215f</li>
|
||||
* <li>hdrMax = 10.0f</li>
|
||||
* </ul>
|
||||
*/
|
||||
public Generic() {
|
||||
this(1.55f, 0.18f, 0.215f, 10.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a new generic tone mapper.
|
||||
*
|
||||
* @param contrast: controls the contrast of the curve, must be > 0.0, values
|
||||
* in the range 0.5..2.0 are recommended.
|
||||
* @param midGrayIn: sets the input middle gray, between 0.0 and 1.0.
|
||||
* @param midGrayOut: sets the output middle gray, between 0.0 and 1.0.
|
||||
* @param hdrMax: defines the maximum input value that will be mapped to
|
||||
* output white. Must be >= 1.0.
|
||||
*/
|
||||
public Generic(
|
||||
float contrast, float midGrayIn, float midGrayOut, float hdrMax) {
|
||||
super(nCreateGenericToneMapper(contrast, midGrayIn, midGrayOut, hdrMax));
|
||||
}
|
||||
|
||||
/** Returns the contrast of the curve as a strictly positive value. */
|
||||
public float getContrast() {
|
||||
return nGenericGetContrast(getNativeObject());
|
||||
}
|
||||
|
||||
/** Sets the contrast of the curve, must be > 0.0, values in the range 0.5..2.0 are recommended. */
|
||||
public void setContrast(float contrast) {
|
||||
nGenericSetContrast(getNativeObject(), contrast);
|
||||
}
|
||||
|
||||
/** Returns the middle gray point for input values as a value between 0.0 and 1.0. */
|
||||
public float getMidGrayIn() {
|
||||
return nGenericGetMidGrayIn(getNativeObject());
|
||||
}
|
||||
|
||||
/** Sets the input middle gray, between 0.0 and 1.0. */
|
||||
public void setMidGrayIn(float midGrayIn) {
|
||||
nGenericSetMidGrayIn(getNativeObject(), midGrayIn);
|
||||
}
|
||||
|
||||
/** Returns the middle gray point for output values as a value between 0.0 and 1.0. */
|
||||
public float getMidGrayOut() {
|
||||
return nGenericGetMidGrayOut(getNativeObject());
|
||||
}
|
||||
|
||||
/** Sets the output middle gray, between 0.0 and 1.0. */
|
||||
public void setMidGrayOut(float midGrayOut) {
|
||||
nGenericSetMidGrayOut(getNativeObject(), midGrayOut);
|
||||
}
|
||||
|
||||
/** Returns the maximum input value that will map to output white, as a value >= 1.0. */
|
||||
public float getHdrMax() {
|
||||
return nGenericGetHdrMax(getNativeObject());
|
||||
}
|
||||
|
||||
/** Defines the maximum input value that will be mapped to output white. Must be >= 1.0. */
|
||||
public void setHdrMax(float hdrMax) {
|
||||
nGenericSetHdrMax(getNativeObject(), hdrMax);
|
||||
}
|
||||
}
|
||||
|
||||
private static native void nDestroyToneMapper(long nativeObject);
|
||||
|
||||
private static native long nCreateLinearToneMapper();
|
||||
private static native long nCreateACESToneMapper();
|
||||
private static native long nCreateACESLegacyToneMapper();
|
||||
private static native long nCreateFilmicToneMapper();
|
||||
private static native long nCreateGenericToneMapper(
|
||||
float contrast, float midGrayIn, float midGrayOut, float hdrMax);
|
||||
|
||||
// Generic tone mappper
|
||||
private static native float nGenericGetContrast(long nativeObject);
|
||||
private static native float nGenericGetMidGrayIn(long nativeObject);
|
||||
private static native float nGenericGetMidGrayOut(long nativeObject);
|
||||
private static native float nGenericGetHdrMax(long nativeObject);
|
||||
|
||||
private static native void nGenericSetContrast(long nativeObject, float contrast);
|
||||
private static native void nGenericSetMidGrayIn(long nativeObject, float midGrayIn);
|
||||
private static native void nGenericSetMidGrayOut(long nativeObject, float midGrayOut);
|
||||
private static native void nGenericSetHdrMax(long nativeObject, float hdrMax);
|
||||
}
|
||||
@@ -83,6 +83,35 @@ import androidx.annotation.Size;
|
||||
return nGetInstance(mNativeObject, entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disable the accurate translation mode. Disabled by default.
|
||||
*
|
||||
* When accurate translation mode is active, the translation component of all transforms is
|
||||
* maintained at double precision. This is only useful if the mat4 version of setTransform()
|
||||
* is used, as well as getTransformAccurate().
|
||||
*
|
||||
* @param enable true to enable the accurate translation mode, false to disable.
|
||||
*
|
||||
* @see #isAccurateTranslationsEnabled
|
||||
* @see #create(int, int, double[])
|
||||
* @see #setTransform(int, double[])
|
||||
* @see #getTransform(int, double[])
|
||||
* @see #getWorldTransform(int, double[])
|
||||
*/
|
||||
public void setAccurateTranslationsEnabled(boolean enable) {
|
||||
nSetAccurateTranslationsEnabled(mNativeObject, enable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the high precision translation mode is active.
|
||||
*
|
||||
* @return true if accurate translations mode is active, false otherwise
|
||||
* @see #setAccurateTranslationsEnabled
|
||||
*/
|
||||
public boolean isAccurateTranslationsEnabled() {
|
||||
return nIsAccurateTranslationsEnabled(mNativeObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a transform component and associates it with the given entity. The component is
|
||||
* initialized with the identity transform.
|
||||
@@ -114,6 +143,23 @@ import androidx.annotation.Size;
|
||||
return nCreateArray(mNativeObject, entity, parent, localTransform);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a transform component with a parent and associates it with the given entity.
|
||||
* If this component already exists on the given entity, it is first
|
||||
* destroyed as if {@link #destroy} was called.
|
||||
*
|
||||
* @param entity an {@link Entity} to associate a transform component to.
|
||||
* @param parent the {@link EntityInstance} of the parent transform
|
||||
* @param localTransform the transform, relative to the parent, to initialize the transform
|
||||
* component with.
|
||||
* @see #destroy
|
||||
*/
|
||||
@EntityInstance
|
||||
public int create(@Entity int entity, @EntityInstance int parent,
|
||||
@Nullable @Size(min = 16) double[] localTransform) {
|
||||
return nCreateArrayFp64(mNativeObject, entity, parent, localTransform);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys this component from the given entity, children are orphaned.
|
||||
*
|
||||
@@ -170,6 +216,24 @@ import androidx.annotation.Size;
|
||||
nSetTransform(mNativeObject, i, localTransform);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a local transform of a transform component.
|
||||
* <p>This operation can be slow if the hierarchy of transform is too deep, and this
|
||||
* will be particularly bad when updating a lot of transforms. In that case,
|
||||
* consider using {@link #openLocalTransformTransaction} / {@link #commitLocalTransformTransaction}.</p>
|
||||
*
|
||||
* @param i the {@link EntityInstance} of the transform component to set the local
|
||||
* transform to.
|
||||
* @param localTransform the local transform (i.e. relative to the parent).
|
||||
* @see #getTransform(int, double[])
|
||||
* @see #getWorldTransform(int, double[])
|
||||
*/
|
||||
public void setTransform(@EntityInstance int i,
|
||||
@NonNull @Size(min = 16) double[] localTransform) {
|
||||
Asserts.assertMat4In(localTransform);
|
||||
nSetTransformFp64(mNativeObject, i, localTransform);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the local transform of a transform component.
|
||||
*
|
||||
@@ -190,6 +254,26 @@ import androidx.annotation.Size;
|
||||
return outLocalTransform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the local transform of a transform component.
|
||||
*
|
||||
* @param i the {@link EntityInstance} of the transform component to query the
|
||||
* local transform from.
|
||||
* @param outLocalTransform a 16 <code>float</code> array to receive the result.
|
||||
* If <code>null</code> is given, a new suitable array is allocated.
|
||||
* @return the local transform of the component (i.e. relative to the parent). This always
|
||||
* returns the value set by setTransform().
|
||||
* @see #setTransform
|
||||
*/
|
||||
@NonNull
|
||||
@Size(min = 16)
|
||||
public double[] getTransform(@EntityInstance int i,
|
||||
@Nullable @Size(min = 16) double[] outLocalTransform) {
|
||||
outLocalTransform = Asserts.assertMat4(outLocalTransform);
|
||||
nGetTransformFp64(mNativeObject, i, outLocalTransform);
|
||||
return outLocalTransform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the world transform of a transform component.
|
||||
*
|
||||
@@ -210,6 +294,26 @@ import androidx.annotation.Size;
|
||||
return outWorldTransform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the world transform of a transform component.
|
||||
*
|
||||
* @param i the {@link EntityInstance} of the transform component to query the
|
||||
* world transform from.
|
||||
* @param outWorldTransform a 16 <code>float</code> array to receive the result.
|
||||
* If <code>null</code> is given, a new suitable array is allocated
|
||||
* @return The world transform of the component (i.e. relative to the root). This is the
|
||||
* composition of this component's local transform with its parent's world transform.
|
||||
* @see #setTransform
|
||||
*/
|
||||
@NonNull
|
||||
@Size(min = 16)
|
||||
public double[] getWorldTransform(@EntityInstance int i,
|
||||
@Nullable @Size(min = 16) double[] outWorldTransform) {
|
||||
outWorldTransform = Asserts.assertMat4(outWorldTransform);
|
||||
nGetWorldTransformFp64(mNativeObject, i, outWorldTransform);
|
||||
return outWorldTransform;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a local transform transaction. During a transaction, {@link #getWorldTransform} can
|
||||
* return an invalid transform until {@link #commitLocalTransformTransaction} is called.
|
||||
@@ -252,12 +356,18 @@ import androidx.annotation.Size;
|
||||
private static native int nGetInstance(long nativeTransformManager, int entity);
|
||||
private static native int nCreate(long nativeTransformManager, int entity);
|
||||
private static native int nCreateArray(long mNativeObject, int entity, int parent, float[] localTransform);
|
||||
private static native int nCreateArrayFp64(long mNativeObject, int entity, int parent, double[] 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 nSetTransformFp64(long nativeTransformManager, int i, double[] localTransform);
|
||||
private static native void nGetTransform(long nativeTransformManager, int i, float[] outLocalTransform);
|
||||
private static native void nGetTransformFp64(long nativeTransformManager, int i, double[] outLocalTransform);
|
||||
private static native void nGetWorldTransform(long nativeTransformManager, int i, float[] outWorldTransform);
|
||||
private static native void nGetWorldTransformFp64(long nativeTransformManager, int i, double[] outWorldTransform);
|
||||
private static native void nOpenLocalTransformTransaction(long nativeTransformManager);
|
||||
private static native void nCommitLocalTransformTransaction(long nativeTransformManager);
|
||||
private static native void nSetAccurateTranslationsEnabled(long nativeTransformManager, boolean enable);
|
||||
private static native boolean nIsAccurateTranslationsEnabled(long nativeTransformManager);
|
||||
}
|
||||
|
||||
@@ -59,6 +59,10 @@ import static com.google.android.filament.Colors.LinearColor;
|
||||
* @see RenderTarget
|
||||
*/
|
||||
public class View {
|
||||
private static final AntiAliasing[] sAntiAliasingValues = AntiAliasing.values();
|
||||
private static final Dithering[] sDitheringValues = Dithering.values();
|
||||
private static final AmbientOcclusion[] sAmbientOcclusionValues = AmbientOcclusion.values();
|
||||
|
||||
private long mNativeObject;
|
||||
private String mName;
|
||||
private Scene mScene;
|
||||
@@ -75,7 +79,10 @@ public class View {
|
||||
private VignetteOptions mVignetteOptions;
|
||||
private ColorGrading mColorGrading;
|
||||
private TemporalAntiAliasingOptions mTemporalAntiAliasingOptions;
|
||||
private ScreenSpaceReflectionsOptions mScreenSpaceReflectionsOptions;
|
||||
private MultiSampleAntiAliasingOptions mMultiSampleAntiAliasingOptions;
|
||||
private VsmShadowOptions mVsmShadowOptions;
|
||||
private SoftShadowOptions mSoftShadowOptions;
|
||||
|
||||
/**
|
||||
* Generic quality level.
|
||||
@@ -131,8 +138,20 @@ public class View {
|
||||
public float maxScale = 1.0f;
|
||||
|
||||
/**
|
||||
* Upscaling quality. LOW: 1 bilinear tap, MEDIUM: 4 bilinear taps, HIGH: 9 bilinear taps.
|
||||
* If minScale needs to be very low, it might help to use MEDIUM or HIGH here.
|
||||
* Sharpness when QualityLevel.MEDIUM or higher is used [0, 1].
|
||||
* 0 is disabled, 1 is the sharpest setting.
|
||||
* The default is set to 0.9
|
||||
*/
|
||||
public float sharpness = 0.9f;
|
||||
|
||||
/**
|
||||
* Upscaling quality
|
||||
* LOW: bilinear filtered blit. Fastest, poor quality
|
||||
* MEDIUM: AMD FidelityFX FSR1 w/ mobile optimizations no RCAS sharpening pass
|
||||
* HIGH: AMD FidelityFX FSR1 w/ mobile optimizations + RCAS
|
||||
* ULTRA: AMD FidelityFX FSR1
|
||||
* FSR1 require a well anti-aliased (MSAA or TAA), noise free scene.
|
||||
*
|
||||
* The default upscaling quality is set to LOW.
|
||||
*/
|
||||
@NonNull
|
||||
@@ -169,6 +188,16 @@ public class View {
|
||||
*/
|
||||
public float intensity = 1.0f;
|
||||
|
||||
/**
|
||||
* Depth distance that constitute an edge for filtering. Must be positive.
|
||||
* Default is 5cm.
|
||||
* This must be adjusted with the scene's scale and/or units.
|
||||
* A value too low will result in high frequency noise, while a value too high will
|
||||
* result in the loss of geometry edges. For AO, it is generally better to be too
|
||||
* blurry than not enough.
|
||||
*/
|
||||
public float bilateralThreshold = 0.05f;
|
||||
|
||||
/**
|
||||
* The quality setting controls the number of samples used for evaluating Ambient
|
||||
* occlusion. The default is QualityLevel.LOW which is sufficient for most mobile
|
||||
@@ -198,6 +227,11 @@ public class View {
|
||||
*/
|
||||
public boolean enabled = false;
|
||||
|
||||
/**
|
||||
* enables bent normals computation from AO, and specular AO
|
||||
*/
|
||||
public boolean bentNormals = false;
|
||||
|
||||
/**
|
||||
* Minimal angle to consider in radian. This is used to reduce the creases that can
|
||||
* appear due to insufficiently tessellated geometry.
|
||||
@@ -264,6 +298,29 @@ public class View {
|
||||
public boolean ssctEnabled = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Options for Multi-sample Anti-aliasing (MSAA)
|
||||
* @see View#setMultiSampleAntiAliasingOptions
|
||||
*/
|
||||
public static class MultiSampleAntiAliasingOptions {
|
||||
/** enables or disables temporal anti-aliasing */
|
||||
public boolean enabled = false;
|
||||
|
||||
/**
|
||||
* number of samples to use for multi-sampled anti-aliasing.\n
|
||||
* 0: treated as 1
|
||||
* 1: no anti-aliasing
|
||||
* n: sample count. Effective sample could be different depending on the
|
||||
* GPU capabilities.
|
||||
*/
|
||||
public int sampleCount = 4;
|
||||
|
||||
/**
|
||||
* custom resolve improves quality for HDR scenes, but may impact performance.
|
||||
*/
|
||||
public boolean customResolve = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Options for Temporal Anti-aliasing (TAA)
|
||||
* @see View#setTemporalAntiAliasingOptions
|
||||
@@ -279,6 +336,28 @@ public class View {
|
||||
public boolean enabled = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Options for Screen-space Reflections.
|
||||
* @see View#setScreenSpaceReflectionOptions
|
||||
*/
|
||||
public static class ScreenSpaceReflectionsOptions {
|
||||
/** ray thickness, in world units */
|
||||
public float thickness = 0.1f;
|
||||
|
||||
/** bias, in world units, to prevent self-intersections */
|
||||
public float bias = 0.01f;
|
||||
|
||||
/** maximum distance, in world units, to raycast */
|
||||
public float maxDistance = 3.0f;
|
||||
|
||||
/** stride, in texels, for samples along the ray. */
|
||||
public float stride = 2.0f;
|
||||
|
||||
/** enables or disables screen-space reflections */
|
||||
public boolean enabled = false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Options for controlling the Bloom effect
|
||||
*
|
||||
@@ -681,7 +760,17 @@ public class View {
|
||||
/**
|
||||
* Variance shadows.
|
||||
*/
|
||||
VSM
|
||||
VSM,
|
||||
|
||||
/**
|
||||
* Percentage-closer filtered shadows, with contact hardening simulation.
|
||||
*/
|
||||
DPCF,
|
||||
|
||||
/**
|
||||
* Percentage-closer soft shadows
|
||||
*/
|
||||
PCSS
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -709,13 +798,6 @@ public class View {
|
||||
*/
|
||||
public boolean mipmapping = false;
|
||||
|
||||
/**
|
||||
* EVSM exponent
|
||||
* The maximum value permissible is 5.54 for a shadow map in fp16, or 42.0 for a
|
||||
* shadow map in fp32. Currently the shadow map bit depth is always fp16.
|
||||
*/
|
||||
public float exponent = 5.54f;
|
||||
|
||||
/**
|
||||
* VSM minimum variance scale, must be positive.
|
||||
*/
|
||||
@@ -727,6 +809,29 @@ public class View {
|
||||
public float lightBleedReduction = 0.2f;
|
||||
}
|
||||
|
||||
/**
|
||||
* View-level options for DPCF and PCSS Shadowing.
|
||||
*
|
||||
* <strong>Warning: This API is still experimental and subject to change.</strong>
|
||||
*
|
||||
* @see View#setSoftShadowOptions
|
||||
*/
|
||||
public static class SoftShadowOptions {
|
||||
/**
|
||||
* Globally scales the penumbra of all DPCF and PCSS shadows
|
||||
* Acceptable values are greater than 0
|
||||
*/
|
||||
public float penumbraScale = 1.0f;
|
||||
|
||||
/**
|
||||
* Globally scales the computed penumbra ratio of all DPCF and PCSS shadows.
|
||||
* This effectively controls the strength of contact hardening effect and is useful for
|
||||
* artistic purposes. Higher values make the shadows become softer faster.
|
||||
* Acceptable values are equal to or greater than 1.
|
||||
*/
|
||||
public float penumbraRatioScale = 1.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to select buffers.
|
||||
*/
|
||||
@@ -1020,7 +1125,10 @@ public class View {
|
||||
* </p>
|
||||
*
|
||||
* @param count number of samples to use for multi-sampled anti-aliasing.
|
||||
*
|
||||
* @deprecated use setMultiSampleAntiAliasingOptions instead
|
||||
*/
|
||||
@Deprecated
|
||||
public void setSampleCount(int count) {
|
||||
nSetSampleCount(getNativeObject(), count);
|
||||
}
|
||||
@@ -1033,7 +1141,10 @@ public class View {
|
||||
* </p>
|
||||
*
|
||||
* @return value set by {@link #setSampleCount}
|
||||
*
|
||||
* @deprecated use getMultiSampleAntiAliasingOptions instead
|
||||
*/
|
||||
@Deprecated
|
||||
public int getSampleCount() {
|
||||
return nGetSampleCount(getNativeObject());
|
||||
}
|
||||
@@ -1059,7 +1170,31 @@ public class View {
|
||||
*/
|
||||
@NonNull
|
||||
public AntiAliasing getAntiAliasing() {
|
||||
return AntiAliasing.values()[nGetAntiAliasing(getNativeObject())];
|
||||
return sAntiAliasingValues[nGetAntiAliasing(getNativeObject())];
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disable multi-sample anti-aliasing (MSAA). Disabled by default.
|
||||
*
|
||||
* @param options multi-sample anti-aliasing options
|
||||
*/
|
||||
public void setMultiSampleAntiAliasingOptions(@NonNull MultiSampleAntiAliasingOptions options) {
|
||||
mMultiSampleAntiAliasingOptions = options;
|
||||
nSetMultiSampleAntiAliasingOptions(getNativeObject(),
|
||||
options.enabled, options.sampleCount, options.customResolve);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns multi-sample anti-aliasing options.
|
||||
*
|
||||
* @return multi-sample anti-aliasing options
|
||||
*/
|
||||
@NonNull
|
||||
public MultiSampleAntiAliasingOptions getMultiSampleAntiAliasingOptions() {
|
||||
if (mMultiSampleAntiAliasingOptions == null) {
|
||||
mMultiSampleAntiAliasingOptions = new MultiSampleAntiAliasingOptions();
|
||||
}
|
||||
return mMultiSampleAntiAliasingOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1073,6 +1208,17 @@ public class View {
|
||||
options.feedback, options.filterWidth, options.enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disable screen-space reflections. Disabled by default.
|
||||
*
|
||||
* @param options screen-space reflections options
|
||||
*/
|
||||
public void setScreenSpaceReflectionsOptions(@NonNull ScreenSpaceReflectionsOptions options) {
|
||||
mScreenSpaceReflectionsOptions = options;
|
||||
nSetScreenSpaceReflectionsOptions(getNativeObject(), options.thickness, options.bias,
|
||||
options.maxDistance, options.stride, options.enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns temporal anti-aliasing options.
|
||||
*
|
||||
@@ -1086,6 +1232,19 @@ public class View {
|
||||
return mTemporalAntiAliasingOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns screen-space reflections options.
|
||||
*
|
||||
* @return screen-space reflections options
|
||||
*/
|
||||
@NonNull
|
||||
public ScreenSpaceReflectionsOptions getScreenSpaceReflectionsOptions() {
|
||||
if (mScreenSpaceReflectionsOptions == null) {
|
||||
mScreenSpaceReflectionsOptions = new ScreenSpaceReflectionsOptions();
|
||||
}
|
||||
return mScreenSpaceReflectionsOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables tone-mapping in the post-processing stage. Enabled by default.
|
||||
*
|
||||
@@ -1148,7 +1307,7 @@ public class View {
|
||||
*/
|
||||
@NonNull
|
||||
public Dithering getDithering() {
|
||||
return Dithering.values()[nGetDithering(getNativeObject())];
|
||||
return sDitheringValues[nGetDithering(getNativeObject())];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1173,6 +1332,7 @@ public class View {
|
||||
options.homogeneousScaling,
|
||||
options.minScale,
|
||||
options.maxScale,
|
||||
options.sharpness,
|
||||
options.quality.ordinal());
|
||||
}
|
||||
|
||||
@@ -1224,21 +1384,26 @@ public class View {
|
||||
*
|
||||
* <p>Post-processing includes:</p>
|
||||
* <ul>
|
||||
* <li>Tone-mapping & gamma encoding</li>
|
||||
* <li>Depth-of-field</li>
|
||||
* <li>Bloom</li>
|
||||
* <li>Vignetting</li>
|
||||
* <li>Temporal Anti-aliasing (TAA)</li>
|
||||
* <li>Color grading & gamma encoding</li>
|
||||
* <li>Dithering</li>
|
||||
* <li>MSAA</li>
|
||||
* <li>FXAA</li>
|
||||
* <li>Dynamic scaling</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>
|
||||
* Disabling post-processing forgoes color correctness as well as anti-aliasing and
|
||||
* should only be used experimentally (e.g., for UI overlays).
|
||||
* Disabling post-processing forgoes color correctness as well as some anti-aliasing techniques
|
||||
* and should only be used for debugging, UI overlays or when using custom render targets
|
||||
* (see RenderTarget).
|
||||
* </p>
|
||||
*
|
||||
* @param enabled true enables post processing, false disables it
|
||||
*
|
||||
* @see #setToneMapping
|
||||
* @see #setBloomOptions
|
||||
* @see #setColorGrading
|
||||
* @see #setAntiAliasing
|
||||
* @see #setDithering
|
||||
* @see #setSampleCount
|
||||
@@ -1333,7 +1498,7 @@ public class View {
|
||||
public void setVsmShadowOptions(@NonNull VsmShadowOptions options) {
|
||||
mVsmShadowOptions = options;
|
||||
nSetVsmShadowOptions(getNativeObject(), options.anisotropy, options.mipmapping,
|
||||
options.exponent, options.minVarianceScale, options.lightBleedReduction);
|
||||
options.minVarianceScale, options.lightBleedReduction);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1349,6 +1514,37 @@ public class View {
|
||||
return mVsmShadowOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets soft shadowing options that apply across the entire View.
|
||||
*
|
||||
* Additional light-specific VSM options can be set with
|
||||
* {@link LightManager.Builder#shadowOptions}.
|
||||
*
|
||||
* Only applicable when shadow type is set to ShadowType.DPCF.
|
||||
*
|
||||
* <strong>Warning: This API is still experimental and subject to change.</strong>
|
||||
*
|
||||
* @param options Options for shadowing.
|
||||
* @see #setShadowType
|
||||
*/
|
||||
public void setSoftShadowOptions(@NonNull SoftShadowOptions options) {
|
||||
mSoftShadowOptions = options;
|
||||
nSetSoftShadowOptions(getNativeObject(), options.penumbraScale, options.penumbraRatioScale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets soft shadowing options associated with this View.
|
||||
* @see #setSoftShadowOptions
|
||||
* @return soft shadow options currently set.
|
||||
*/
|
||||
@NonNull
|
||||
public SoftShadowOptions getSoftShadowOptions() {
|
||||
if (mSoftShadowOptions == null) {
|
||||
mSoftShadowOptions = new SoftShadowOptions();
|
||||
}
|
||||
return mSoftShadowOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Activates or deactivates ambient occlusion.
|
||||
* @see #setAmbientOcclusionOptions
|
||||
@@ -1367,7 +1563,7 @@ public class View {
|
||||
@Deprecated
|
||||
@NonNull
|
||||
public AmbientOcclusion getAmbientOcclusion() {
|
||||
return AmbientOcclusion.values()[nGetAmbientOcclusion(getNativeObject())];
|
||||
return sAmbientOcclusionValues[nGetAmbientOcclusion(getNativeObject())];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1378,9 +1574,11 @@ public class View {
|
||||
public void setAmbientOcclusionOptions(@NonNull AmbientOcclusionOptions options) {
|
||||
mAmbientOcclusionOptions = options;
|
||||
nSetAmbientOcclusionOptions(getNativeObject(), options.radius, options.bias, options.power,
|
||||
options.resolution, options.intensity, options.quality.ordinal(), options.lowPassFilter.ordinal(), options.upsampling.ordinal(),
|
||||
options.enabled, options.minHorizonAngleRad);
|
||||
nSetSSCTOptions(getNativeObject(), options.ssctLightConeRad, options.ssctStartTraceDistance, options.ssctContactDistanceMax, options.ssctIntensity,
|
||||
options.resolution, options.intensity, options.bilateralThreshold,
|
||||
options.quality.ordinal(), options.lowPassFilter.ordinal(), options.upsampling.ordinal(),
|
||||
options.enabled, options.bentNormals, options.minHorizonAngleRad);
|
||||
nSetSSCTOptions(getNativeObject(), options.ssctLightConeRad, options.ssctStartTraceDistance,
|
||||
options.ssctContactDistanceMax, options.ssctIntensity,
|
||||
options.ssctLightDirection[0], options.ssctLightDirection[1], options.ssctLightDirection[2],
|
||||
options.ssctDepthBias, options.ssctDepthSlopeBias, options.ssctSampleCount,
|
||||
options.ssctRayCount, options.ssctEnabled);
|
||||
@@ -1518,6 +1716,71 @@ public class View {
|
||||
return mDepthOfFieldOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* A class containing the result of a picking query
|
||||
*/
|
||||
public static class PickingQueryResult {
|
||||
/** The entity of the renderable at the picking query location */
|
||||
@Entity public int renderable;
|
||||
/** The value of the depth buffer at the picking query location */
|
||||
public float depth;
|
||||
/** The fragment coordinate in GL convention at the picking query location */
|
||||
@NonNull public float[] fragCoords = new float[3];
|
||||
};
|
||||
|
||||
/**
|
||||
* An interface to implement a custom class to receive results of picking queries.
|
||||
*/
|
||||
public interface OnPickCallback {
|
||||
/**
|
||||
* onPick() is called by the specified Handler in {@link View#pick} when the picking query
|
||||
* result is available.
|
||||
* @param result An instance of {@link PickingQueryResult}.
|
||||
*/
|
||||
void onPick(@NonNull PickingQueryResult result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a picking query. Multiple queries can be created (e.g.: multi-touch).
|
||||
* Picking queries are all executed when {@link Renderer#render} is called on this View.
|
||||
* The provided callback is guaranteed to be called at some point in the future.
|
||||
*
|
||||
* Typically it takes a couple frames to receive the result of a picking query.
|
||||
*
|
||||
* @param x Horizontal coordinate to query in the viewport with origin on the left.
|
||||
* @param y Vertical coordinate to query on the viewport with origin at the bottom.
|
||||
* @param handler An {@link java.util.concurrent.Executor Executor}.
|
||||
* On Android this can also be a {@link android.os.Handler Handler}.
|
||||
* @param callback User callback executed by <code>handler</code> when the picking query
|
||||
* result is available.
|
||||
*/
|
||||
public void pick(int x, int y,
|
||||
@Nullable Object handler, @Nullable OnPickCallback callback) {
|
||||
InternalOnPickCallback internalCallback = new InternalOnPickCallback(callback);
|
||||
nPick(getNativeObject(), x, y, handler, internalCallback);
|
||||
}
|
||||
|
||||
private static class InternalOnPickCallback implements Runnable {
|
||||
public InternalOnPickCallback(OnPickCallback mUserCallback) {
|
||||
this.mUserCallback = mUserCallback;
|
||||
}
|
||||
@Override
|
||||
public void run() {
|
||||
mPickingQueryResult.renderable = mRenderable;
|
||||
mPickingQueryResult.depth = mDepth;
|
||||
mPickingQueryResult.fragCoords[0] = mFragCoordsX;
|
||||
mPickingQueryResult.fragCoords[1] = mFragCoordsY;
|
||||
mPickingQueryResult.fragCoords[2] = mFragCoordsZ;
|
||||
mUserCallback.onPick(mPickingQueryResult);
|
||||
}
|
||||
private final OnPickCallback mUserCallback;
|
||||
private final PickingQueryResult mPickingQueryResult = new PickingQueryResult();
|
||||
@Entity int mRenderable;
|
||||
float mDepth;
|
||||
float mFragCoordsX;
|
||||
float mFragCoordsY;
|
||||
float mFragCoordsZ;
|
||||
}
|
||||
|
||||
public long getNativeObject() {
|
||||
if (mNativeObject == 0) {
|
||||
@@ -1543,11 +1806,12 @@ public class View {
|
||||
private static native int nGetAntiAliasing(long nativeView);
|
||||
private static native void nSetDithering(long nativeView, int dithering);
|
||||
private static native int nGetDithering(long nativeView);
|
||||
private static native void nSetDynamicResolutionOptions(long nativeView, boolean enabled, boolean homogeneousScaling, float minScale, float maxScale, int quality);
|
||||
private static native void nSetDynamicResolutionOptions(long nativeView, boolean enabled, boolean homogeneousScaling, float minScale, float maxScale, float sharpness, int quality);
|
||||
private static native void nSetRenderQuality(long nativeView, int hdrColorBufferQuality);
|
||||
private static native void nSetDynamicLightingOptions(long nativeView, float zLightNear, float zLightFar);
|
||||
private static native void nSetShadowType(long nativeView, int type);
|
||||
private static native void nSetVsmShadowOptions(long nativeView, int anisotropy, boolean mipmapping, float exponent, float minVarianceScale, float lightBleedReduction);
|
||||
private static native void nSetVsmShadowOptions(long nativeView, int anisotropy, boolean mipmapping, float minVarianceScale, float lightBleedReduction);
|
||||
private static native void nSetSoftShadowOptions(long nativeView, float penumbraScale, float penumbraRatioScale);
|
||||
private static native void nSetColorGrading(long nativeView, long nativeColorGrading);
|
||||
private static native void nSetPostProcessingEnabled(long nativeView, boolean enabled);
|
||||
private static native boolean nIsPostProcessingEnabled(long nativeView);
|
||||
@@ -1555,7 +1819,7 @@ public class View {
|
||||
private static native boolean nIsFrontFaceWindingInverted(long nativeView);
|
||||
private static native void nSetAmbientOcclusion(long nativeView, int ordinal);
|
||||
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 nSetAmbientOcclusionOptions(long nativeView, float radius, float bias, float power, float resolution, float intensity, float bilateralThreshold, int quality, int lowPassFilter, int upsampling, boolean enabled, boolean bentNormals, 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,
|
||||
boolean lensFlare, boolean starburst, float chromaticAberration, int ghostCount, float ghostSpacing, float ghostThreshold, float haloThickness, float haloRadius, float haloThreshold);
|
||||
@@ -1565,7 +1829,10 @@ public class View {
|
||||
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 void nSetScreenSpaceReflectionsOptions(long nativeView, float thickness, float bias, float maxDistance, float stride, boolean enabled);
|
||||
private static native void nSetMultiSampleAntiAliasingOptions(long nativeView, boolean enabled, int sampleCount, boolean customResolve);
|
||||
private static native boolean nIsShadowingEnabled(long nativeView);
|
||||
private static native void nSetScreenSpaceRefractionEnabled(long nativeView, boolean enabled);
|
||||
private static native boolean nIsScreenSpaceRefractionEnabled(long nativeView);
|
||||
private static native void nPick(long nativeView, int x, int y, Object handler, InternalOnPickCallback internalCallback);
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ target_compile_definitions(filament-utils-jni PUBLIC IMAGEIO_LITE=1)
|
||||
target_include_directories(filament-utils-jni PRIVATE
|
||||
${FILAMENT_DIR}/include
|
||||
..
|
||||
../../filament/backend/include
|
||||
${IMAGEIO_DIR}/include
|
||||
../../libs/utils/include)
|
||||
|
||||
|
||||
@@ -9,6 +9,13 @@ android {
|
||||
|
||||
lite {
|
||||
dimension "functionality"
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
// hack: this is needed because filament-utils-android/CMakeLists.txt builds
|
||||
// gltfio from source, which needs this defined
|
||||
arguments.add("-DGLTFIO_LITE=ON")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,13 +50,14 @@ configurations.all { config ->
|
||||
dependencies {
|
||||
implementation deps.kotlin
|
||||
implementation deps.androidx.annotations
|
||||
implementation project(':filament-android')
|
||||
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.8'
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.3'
|
||||
implementation deps.coroutines.core
|
||||
implementation deps.coroutines.android
|
||||
|
||||
fullImplementation module("com.google.android.filament:gltfio-android:${VERSION_NAME}")
|
||||
liteImplementation module("com.google.android.filament:gltfio-android-lite:${VERSION_NAME}")
|
||||
api project(':filament-android')
|
||||
|
||||
fullApi module("com.google.android.filament:gltfio-android:${VERSION_NAME}")
|
||||
liteApi module("com.google.android.filament:gltfio-android-lite:${VERSION_NAME}")
|
||||
}
|
||||
|
||||
apply from: rootProject.file('gradle/gradle-mvn-push.gradle')
|
||||
|
||||
@@ -32,9 +32,13 @@ import com.google.android.filament.Texture;
|
||||
* Texture equirect = HDRLoader.createTexture("foo.hdr");
|
||||
* Texture skyboxTexture = equirectangularToCubemap.run(equirect);
|
||||
* engine.destroy(equirect);
|
||||
* equirectangularToCubemap.destroy();
|
||||
*
|
||||
* specularFilter = new IBLPrefilterContext.SpecularFilter(context);
|
||||
* Texture reflections = specularFilter.run(skyboxTexture);
|
||||
* specularFilter.destroy();
|
||||
*
|
||||
* context.destroy();
|
||||
*
|
||||
* IndirectLight ibl = IndirectLight.Builder()
|
||||
* .reflections(reflections)
|
||||
@@ -43,81 +47,74 @@ import com.google.android.filament.Texture;
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*/
|
||||
public class IBLPrefilterContext {
|
||||
private final long mNativeObject;
|
||||
private 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 void destroy() {
|
||||
nDestroy(getNativeObject());
|
||||
mNativeObject = 0;
|
||||
}
|
||||
|
||||
public static class EquirectangularToCubemap {
|
||||
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) // Keep to finalize native resources
|
||||
private final HelperFinalizer mFinalizer;
|
||||
private final long mNativeHelper;
|
||||
private long mNativeObject;
|
||||
|
||||
public EquirectangularToCubemap(IBLPrefilterContext context) {
|
||||
mNativeHelper = nCreateEquirectHelper(context.mNativeObject);
|
||||
mFinalizer = new HelperFinalizer(mNativeHelper);
|
||||
mNativeObject = nCreateEquirectHelper(context.getNativeObject());
|
||||
}
|
||||
|
||||
public Texture run(Texture equirect) {
|
||||
long nativeTexture = nEquirectHelperRun(mNativeHelper, equirect.getNativeObject());
|
||||
long nativeTexture = nEquirectHelperRun(getNativeObject(), equirect.getNativeObject());
|
||||
return new Texture(nativeTexture);
|
||||
}
|
||||
|
||||
private static class HelperFinalizer {
|
||||
private final long mNativeObject;
|
||||
public void destroy() {
|
||||
nDestroyEquirectHelper(getNativeObject());
|
||||
mNativeObject = 0;
|
||||
}
|
||||
|
||||
HelperFinalizer(long nativeObject) { mNativeObject = nativeObject; }
|
||||
|
||||
@Override
|
||||
public void finalize() {
|
||||
try {
|
||||
super.finalize();
|
||||
} catch (Throwable t) { // Ignore
|
||||
} finally {
|
||||
nDestroyEquirectHelper(mNativeObject);
|
||||
}
|
||||
protected long getNativeObject() {
|
||||
if (mNativeObject == 0) {
|
||||
throw new IllegalStateException("Calling method on destroyed EquirectangularToCubemap");
|
||||
}
|
||||
return mNativeObject;
|
||||
}
|
||||
}
|
||||
|
||||
public static class SpecularFilter {
|
||||
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) // Keep to finalize native resources
|
||||
private final HelperFinalizer mFinalizer;
|
||||
private final long mNativeHelper;
|
||||
private long mNativeObject;
|
||||
|
||||
public SpecularFilter(IBLPrefilterContext context) {
|
||||
mNativeHelper = nCreateSpecularFilter(context.mNativeObject);
|
||||
mFinalizer = new HelperFinalizer(mNativeHelper);
|
||||
mNativeObject = nCreateSpecularFilter(context.getNativeObject());
|
||||
}
|
||||
|
||||
public Texture run(Texture skybox) {
|
||||
long nativeTexture = nSpecularFilterRun(mNativeHelper, skybox.getNativeObject());
|
||||
long nativeTexture = nSpecularFilterRun(getNativeObject(), 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);
|
||||
}
|
||||
}
|
||||
public void destroy() {
|
||||
nDestroySpecularFilter(getNativeObject());
|
||||
mNativeObject = 0;
|
||||
}
|
||||
|
||||
protected long getNativeObject() {
|
||||
if (mNativeObject == 0) {
|
||||
throw new IllegalStateException("Calling method on destroyed SpecularFilter");
|
||||
}
|
||||
return mNativeObject;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected long getNativeObject() {
|
||||
if (mNativeObject == 0) {
|
||||
throw new IllegalStateException("Calling method on destroyed IBLPrefilterContext");
|
||||
}
|
||||
return mNativeObject;
|
||||
}
|
||||
|
||||
private static native long nCreate(long nativeEngine);
|
||||
|
||||
@@ -32,7 +32,9 @@ import androidx.annotation.Size;
|
||||
* @see Bookmark
|
||||
*/
|
||||
public class Manipulator {
|
||||
private long mNativeObject;
|
||||
private static final Mode[] sModeValues = Mode.values();
|
||||
|
||||
private final long mNativeObject;
|
||||
|
||||
private Manipulator(long nativeIndexBuffer) {
|
||||
mNativeObject = nativeIndexBuffer;
|
||||
@@ -320,7 +322,7 @@ public class Manipulator {
|
||||
/**
|
||||
* Gets the immutable mode of the manipulator.
|
||||
*/
|
||||
public Mode getMode() { return Mode.values()[nGetMode(mNativeObject)]; }
|
||||
public Mode getMode() { return sModeValues[nGetMode(mNativeObject)]; }
|
||||
|
||||
/**
|
||||
* Sets the viewport dimensions in terms of pixels.
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
@file:Suppress("unused")
|
||||
|
||||
package com.google.android.filament.utils
|
||||
|
||||
import kotlin.math.*
|
||||
@@ -22,6 +24,10 @@ enum class MatrixColumn {
|
||||
X, Y, Z, W
|
||||
}
|
||||
|
||||
enum class RotationsOrder {
|
||||
XYZ, XZY, YXZ, YZX, ZXY, ZYX
|
||||
}
|
||||
|
||||
data class Mat2(
|
||||
var x: Float2 = Float2(x = 1.0f),
|
||||
var y: Float2 = Float2(y = 1.0f)) {
|
||||
@@ -39,14 +45,14 @@ data class Mat2(
|
||||
fun identity() = Mat2()
|
||||
}
|
||||
|
||||
operator fun get(column: Int) = when(column) {
|
||||
operator fun get(column: Int) = when (column) {
|
||||
0 -> x
|
||||
1 -> y
|
||||
else -> throw IllegalArgumentException("column must be in 0..1")
|
||||
}
|
||||
operator fun get(column: Int, row: Int) = get(column)[row]
|
||||
|
||||
operator fun get(column: MatrixColumn) = when(column) {
|
||||
operator fun get(column: MatrixColumn) = when (column) {
|
||||
MatrixColumn.X -> x
|
||||
MatrixColumn.Y -> y
|
||||
else -> throw IllegalArgumentException("column must be X or Y")
|
||||
@@ -64,34 +70,30 @@ data class Mat2(
|
||||
}
|
||||
|
||||
operator fun unaryMinus() = Mat2(-x, -y)
|
||||
operator fun inc(): Mat2 {
|
||||
x++
|
||||
y++
|
||||
return this
|
||||
}
|
||||
operator fun dec(): Mat2 {
|
||||
x--
|
||||
y--
|
||||
return this
|
||||
}
|
||||
operator fun inc() = Mat2(x++, y++)
|
||||
operator fun dec() = Mat2(x--, y--)
|
||||
|
||||
operator fun plus(v: Float) = Mat2(x + v, y + v)
|
||||
operator fun minus(v: Float) = Mat2(x - v, y - v)
|
||||
operator fun times(v: Float) = Mat2(x * v, y * v)
|
||||
operator fun div(v: Float) = Mat2(x / v, y / v)
|
||||
|
||||
operator fun times(m: Mat2): Mat2 {
|
||||
val t = transpose(this)
|
||||
return Mat2(
|
||||
Float2(dot(t.x, m.x), dot(t.y, m.x)),
|
||||
Float2(dot(t.x, m.y), dot(t.y, m.y))
|
||||
)
|
||||
}
|
||||
operator fun times(m: Mat2) = Mat2(
|
||||
Float2(
|
||||
x.x * m.x.x + y.x * m.x.y,
|
||||
x.y * m.x.x + y.y * m.x.y,
|
||||
),
|
||||
Float2(
|
||||
x.x * m.y.x + y.x * m.y.y,
|
||||
x.y * m.y.x + y.y * m.y.y,
|
||||
)
|
||||
)
|
||||
|
||||
operator fun times(v: Float2) = Float2(
|
||||
x.x * v.x + y.x * v.y,
|
||||
x.y * v.x + y.y * v.y,
|
||||
)
|
||||
|
||||
operator fun times(v: Float2): Float2 {
|
||||
val t = transpose(this)
|
||||
return Float2(dot(t.x, v), dot(t.y, v))
|
||||
}
|
||||
|
||||
fun toFloatArray() = floatArrayOf(
|
||||
x.x, y.x,
|
||||
@@ -126,7 +128,7 @@ data class Mat3(
|
||||
fun identity() = Mat3()
|
||||
}
|
||||
|
||||
operator fun get(column: Int) = when(column) {
|
||||
operator fun get(column: Int) = when (column) {
|
||||
0 -> x
|
||||
1 -> y
|
||||
2 -> z
|
||||
@@ -134,7 +136,7 @@ data class Mat3(
|
||||
}
|
||||
operator fun get(column: Int, row: Int) = get(column)[row]
|
||||
|
||||
operator fun get(column: MatrixColumn) = when(column) {
|
||||
operator fun get(column: MatrixColumn) = when (column) {
|
||||
MatrixColumn.X -> x
|
||||
MatrixColumn.Y -> y
|
||||
MatrixColumn.Z -> z
|
||||
@@ -153,37 +155,37 @@ data class Mat3(
|
||||
}
|
||||
|
||||
operator fun unaryMinus() = Mat3(-x, -y, -z)
|
||||
operator fun inc(): Mat3 {
|
||||
x++
|
||||
y++
|
||||
z++
|
||||
return this
|
||||
}
|
||||
operator fun dec(): Mat3 {
|
||||
x--
|
||||
y--
|
||||
z--
|
||||
return this
|
||||
}
|
||||
operator fun inc() = Mat3(x++, y++, z++)
|
||||
operator fun dec() = Mat3(x--, y--, z--)
|
||||
|
||||
operator fun plus(v: Float) = Mat3(x + v, y + v, z + v)
|
||||
operator fun minus(v: Float) = Mat3(x - v, y - v, z - v)
|
||||
operator fun times(v: Float) = Mat3(x * v, y * v, z * v)
|
||||
operator fun div(v: Float) = Mat3(x / v, y / v, z / v)
|
||||
|
||||
operator fun times(m: Mat3): Mat3 {
|
||||
val t = transpose(this)
|
||||
return Mat3(
|
||||
Float3(dot(t.x, m.x), dot(t.y, m.x), dot(t.z, m.x)),
|
||||
Float3(dot(t.x, m.y), dot(t.y, m.y), dot(t.z, m.y)),
|
||||
Float3(dot(t.x, m.z), dot(t.y, m.z), dot(t.z, m.z))
|
||||
)
|
||||
}
|
||||
operator fun times(m: Mat3) = Mat3(
|
||||
Float3(
|
||||
x.x * m.x.x + y.x * m.x.y + z.x * m.x.z,
|
||||
x.y * m.x.x + y.y * m.x.y + z.y * m.x.z,
|
||||
x.z * m.x.x + y.z * m.x.y + z.z * m.x.z,
|
||||
),
|
||||
Float3(
|
||||
x.x * m.y.x + y.x * m.y.y + z.x * m.y.z,
|
||||
x.y * m.y.x + y.y * m.y.y + z.y * m.y.z,
|
||||
x.z * m.y.x + y.z * m.y.y + z.z * m.y.z,
|
||||
),
|
||||
Float3(
|
||||
x.x * m.z.x + y.x * m.z.y + z.x * m.z.z,
|
||||
x.y * m.z.x + y.y * m.z.y + z.y * m.z.z,
|
||||
x.z * m.z.x + y.z * m.z.y + z.z * m.z.z,
|
||||
)
|
||||
)
|
||||
|
||||
operator fun times(v: Float3): Float3 {
|
||||
val t = transpose(this)
|
||||
return Float3(dot(t.x, v), dot(t.y, v), dot(t.z, v))
|
||||
}
|
||||
operator fun times(v: Float3) = Float3(
|
||||
x.x * v.x + y.x * v.y + z.x * v.z,
|
||||
x.y * v.x + y.y * v.y + z.y * v.z,
|
||||
x.z * v.x + y.z * v.y + z.z * v.z,
|
||||
)
|
||||
|
||||
fun toFloatArray() = floatArrayOf(
|
||||
x.x, y.x, z.x,
|
||||
@@ -265,7 +267,7 @@ data class Mat4(
|
||||
inline val upperLeft: Mat3
|
||||
get() = Mat3(x.xyz, y.xyz, z.xyz)
|
||||
|
||||
operator fun get(column: Int) = when(column) {
|
||||
operator fun get(column: Int) = when (column) {
|
||||
0 -> x
|
||||
1 -> y
|
||||
2 -> z
|
||||
@@ -274,7 +276,7 @@ data class Mat4(
|
||||
}
|
||||
operator fun get(column: Int, row: Int) = get(column)[row]
|
||||
|
||||
operator fun get(column: MatrixColumn) = when(column) {
|
||||
operator fun get(column: MatrixColumn) = when (column) {
|
||||
MatrixColumn.X -> x
|
||||
MatrixColumn.Y -> y
|
||||
MatrixColumn.Z -> z
|
||||
@@ -293,40 +295,49 @@ data class Mat4(
|
||||
}
|
||||
|
||||
operator fun unaryMinus() = Mat4(-x, -y, -z, -w)
|
||||
operator fun inc(): Mat4 {
|
||||
x++
|
||||
y++
|
||||
z++
|
||||
w++
|
||||
return this
|
||||
}
|
||||
operator fun dec(): Mat4 {
|
||||
x--
|
||||
y--
|
||||
z--
|
||||
w--
|
||||
return this
|
||||
}
|
||||
operator fun inc() = Mat4(x++, y++, z++, w++)
|
||||
operator fun dec() = Mat4(x--, y--, z--, w--)
|
||||
|
||||
operator fun plus(v: Float) = Mat4(x + v, y + v, z + v, w + v)
|
||||
operator fun minus(v: Float) = Mat4(x - v, y - v, z - v, w - v)
|
||||
operator fun times(v: Float) = Mat4(x * v, y * v, z * v, w * v)
|
||||
operator fun div(v: Float) = Mat4(x / v, y / v, z / v, w / v)
|
||||
|
||||
operator fun times(m: Mat4): Mat4 {
|
||||
val t = transpose(this)
|
||||
return Mat4(
|
||||
Float4(dot(t.x, m.x), dot(t.y, m.x), dot(t.z, m.x), dot(t.w, m.x)),
|
||||
Float4(dot(t.x, m.y), dot(t.y, m.y), dot(t.z, m.y), dot(t.w, m.y)),
|
||||
Float4(dot(t.x, m.z), dot(t.y, m.z), dot(t.z, m.z), dot(t.w, m.z)),
|
||||
Float4(dot(t.x, m.w), dot(t.y, m.w), dot(t.z, m.w), dot(t.w, m.w))
|
||||
)
|
||||
}
|
||||
operator fun times(m: Mat4) = Mat4(
|
||||
Float4(
|
||||
x.x * m.x.x + y.x * m.x.y + z.x * m.x.z + w.x * m.x.w,
|
||||
x.y * m.x.x + y.y * m.x.y + z.y * m.x.z + w.y * m.x.w,
|
||||
x.z * m.x.x + y.z * m.x.y + z.z * m.x.z + w.z * m.x.w,
|
||||
x.w * m.x.x + y.w * m.x.y + z.w * m.x.z + w.w * m.x.w,
|
||||
),
|
||||
Float4(
|
||||
x.x * m.y.x + y.x * m.y.y + z.x * m.y.z + w.x * m.y.w,
|
||||
x.y * m.y.x + y.y * m.y.y + z.y * m.y.z + w.y * m.y.w,
|
||||
x.z * m.y.x + y.z * m.y.y + z.z * m.y.z + w.z * m.y.w,
|
||||
x.w * m.y.x + y.w * m.y.y + z.w * m.y.z + w.w * m.y.w,
|
||||
),
|
||||
Float4(
|
||||
x.x * m.z.x + y.x * m.z.y + z.x * m.z.z + w.x * m.z.w,
|
||||
x.y * m.z.x + y.y * m.z.y + z.y * m.z.z + w.y * m.z.w,
|
||||
x.z * m.z.x + y.z * m.z.y + z.z * m.z.z + w.z * m.z.w,
|
||||
x.w * m.z.x + y.w * m.z.y + z.w * m.z.z + w.w * m.z.w,
|
||||
),
|
||||
Float4(
|
||||
x.x * m.w.x + y.x * m.w.y + z.x * m.w.z + w.x * m.w.w,
|
||||
x.y * m.w.x + y.y * m.w.y + z.y * m.w.z + w.y * m.w.w,
|
||||
x.z * m.w.x + y.z * m.w.y + z.z * m.w.z + w.z * m.w.w,
|
||||
x.w * m.w.x + y.w * m.w.y + z.w * m.w.z + w.w * m.w.w,
|
||||
)
|
||||
)
|
||||
|
||||
operator fun times(v: Float4): Float4 {
|
||||
val t = transpose(this)
|
||||
return Float4(dot(t.x, v), dot(t.y, v), dot(t.z, v), dot(t.w, v))
|
||||
}
|
||||
operator fun times(v: Float4) = Float4(
|
||||
x.x * v.x + y.x * v.y + z.x * v.z+ w.x * v.w,
|
||||
x.y * v.x + y.y * v.y + z.y * v.z+ w.y * v.w,
|
||||
x.z * v.x + y.z * v.y + z.z * v.z+ w.z * v.w,
|
||||
x.w * v.x + y.w * v.y + z.w * v.z+ w.w * v.w
|
||||
)
|
||||
|
||||
fun toQuaternion() = quaternion(this)
|
||||
|
||||
fun toFloatArray() = floatArrayOf(
|
||||
x.x, y.x, z.x, w.x,
|
||||
@@ -355,6 +366,8 @@ fun transpose(m: Mat3) = Mat3(
|
||||
Float3(m.x.y, m.y.y, m.z.y),
|
||||
Float3(m.x.z, m.y.z, m.z.z)
|
||||
)
|
||||
|
||||
@Suppress("LocalVariableName")
|
||||
fun inverse(m: Mat3): Mat3 {
|
||||
val a = m.x.x
|
||||
val b = m.x.y
|
||||
@@ -373,7 +386,7 @@ fun inverse(m: Mat3): Mat3 {
|
||||
val det = a * A + b * B + c * C
|
||||
|
||||
return Mat3.of(
|
||||
A / det, B / det, C / det,
|
||||
A / det, B / det, C / det,
|
||||
(c * h - b * i) / det, (a * i - c * g) / det, (b * g - a * h) / det,
|
||||
(b * f - c * e) / det, (c * d - a * f) / det, (a * e - b * d) / det
|
||||
)
|
||||
@@ -385,6 +398,7 @@ fun transpose(m: Mat4) = Mat4(
|
||||
Float4(m.x.z, m.y.z, m.z.z, m.w.z),
|
||||
Float4(m.x.w, m.y.w, m.z.w, m.w.w)
|
||||
)
|
||||
|
||||
fun inverse(m: Mat4): Mat4 {
|
||||
val result = Mat4()
|
||||
|
||||
@@ -460,18 +474,90 @@ fun translation(t: Float3) = Mat4(w = Float4(t, 1.0f))
|
||||
fun translation(m: Mat4) = translation(m.translation)
|
||||
|
||||
fun rotation(m: Mat4) = Mat4(normalize(m.right), normalize(m.up), normalize(m.forward))
|
||||
fun rotation(d: Float3): Mat4 {
|
||||
val r = transform(d, ::radians)
|
||||
val c = transform(r, { x -> cos(x) })
|
||||
val s = transform(r, { x -> sin(x) })
|
||||
|
||||
return Mat4.of(
|
||||
c.y * c.z, -c.x * s.z + s.x * s.y * c.z, s.x * s.z + c.x * s.y * c.z, 0.0f,
|
||||
c.y * s.z, c.x * c.z + s.x * s.y * s.z, -s.x * c.z + c.x * s.y * s.z, 0.0f,
|
||||
-s.y , s.x * c.y , c.x * c.y , 0.0f,
|
||||
0.0f , 0.0f , 0.0f , 1.0f
|
||||
)
|
||||
/**
|
||||
* Construct a rotation matrix from Euler angles using YPR around a specified order
|
||||
*
|
||||
* Uses intrinsic Tait-Bryan angles. This means that rotations are performed with respect to the
|
||||
* local coordinate system.
|
||||
* That is, for order 'XYZ', the rotation is first around the X axis (which is the same as the
|
||||
* world-X axis), then around local-Y (which may now be different from the world Y-axis),
|
||||
* then local-Z (which may be different from the world Z-axis)
|
||||
*
|
||||
* @param d Per axis Euler angles in degrees
|
||||
* Yaw, pitch, roll (YPR) are taken accordingly to the rotations order input.
|
||||
* @param order The order in which to apply rotations.
|
||||
* Default is [RotationsOrder.ZYX] which means that the object will first be rotated around its Z
|
||||
* axis, then its Y axis and finally its X axis.
|
||||
*
|
||||
* @return The rotation matrix
|
||||
*/
|
||||
fun rotation(d: Float3, order: RotationsOrder = RotationsOrder.ZYX): Mat4 {
|
||||
val r = transform(d, ::radians)
|
||||
return when(order) {
|
||||
RotationsOrder.XZY -> rotation(r.x, r.z, r.y)
|
||||
RotationsOrder.XYZ -> rotation(r.x, r.y, r.z)
|
||||
RotationsOrder.YXZ -> rotation(r.y, r.x, r.z)
|
||||
RotationsOrder.YZX -> rotation(r.y, r.z, r.x)
|
||||
RotationsOrder.ZYX -> rotation(r.z, r.y, r.x)
|
||||
RotationsOrder.ZXY -> rotation(r.z, r.x, r.y)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a rotation matrix from Euler yaw, pitch, roll around a specified order.
|
||||
*
|
||||
* @param roll about 1st rotation axis in radians. Z in case of ZYX order
|
||||
* @param pitch about 2nd rotation axis in radians. Y in case of ZYX order
|
||||
* @param yaw about 3rd rotation axis in radians. X in case of ZYX order
|
||||
* @param order The order in which to apply rotations.
|
||||
* Default is [RotationsOrder.ZYX] which means that the object will first be rotated around its Z
|
||||
* axis, then its Y axis and finally its X axis.
|
||||
*
|
||||
* @return The rotation matrix
|
||||
*/
|
||||
fun rotation(yaw: Float = 0.0f, pitch: Float = 0.0f, roll: Float = 0.0f, order: RotationsOrder = RotationsOrder.ZYX): Mat4 {
|
||||
val c1 = cos(yaw)
|
||||
val s1 = sin(yaw)
|
||||
val c2 = cos(pitch)
|
||||
val s2 = sin(pitch)
|
||||
val c3 = cos(roll)
|
||||
val s3 = sin(roll)
|
||||
|
||||
return when (order) {
|
||||
RotationsOrder.XZY -> Mat4.of(
|
||||
c2 * c3, -s2, c2 * s3, 0.0f,
|
||||
s1 * s3 + c1 * c3 * s2, c1 * c2, c1 * s2 * s3 - c3 * s1, 0.0f,
|
||||
c3 * s1 * s2 - c1 * s3, c2 * s1, c1 * c3 + s1 * s2 * s3, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f)
|
||||
RotationsOrder.XYZ -> Mat4.of(
|
||||
c2 * c3, -c2 * s3, s2, 0.0f,
|
||||
c1 * s3 + c3 * s1 * s2, c1 * c3 - s1 * s2 * s3, -c2 * s1, 0.0f,
|
||||
s1 * s3 - c1 * c3 * s2, c3 * s1 + c1 * s2 * s3, c1 * c2, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f)
|
||||
RotationsOrder.YXZ -> Mat4.of(
|
||||
c1 * c3 + s1 * s2 * s3, c3 * s1 * s2 - c1 * s3, c2 * s1, 0.0f,
|
||||
c2 * s3, c2 * c3, -s2, 0.0f,
|
||||
c1 * s2 * s3 - c3 * s1, c1 * c3 * s2 + s1 * s3, c1 * c2, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f)
|
||||
RotationsOrder.YZX -> Mat4.of(
|
||||
c1 * c2, s1 * s3 - c1 * c3 * s2, c3 * s1 + c1 * s2 * s3, 0.0f,
|
||||
s2, c2 * c3, -c2 * s3, 0.0f,
|
||||
-c2 * s1, c1 * s3 + c3 * s1 * s2, c1 * c3 - s1 * s2 * s3, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f)
|
||||
RotationsOrder.ZYX -> Mat4.of(
|
||||
c1 * c2, c1 * s2 * s3 - c3 * s1, s1 * s3 + c1 * c3 * s2, 0.0f,
|
||||
c2 * s1, c1 * c3 + s1 * s2 * s3, c3 * s1 * s2 - c1 * s3, 0.0f,
|
||||
-s2, c2 * s3, c2 * c3, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f)
|
||||
RotationsOrder.ZXY -> Mat4.of(
|
||||
c1 * c3 - s1 * s2 * s3, -c2 * s1, c1 * s3 + c3 * s1 * s2, 0.0f,
|
||||
c3 * s1 + c1 * s2 * s3, c1 * c2, s1 * s3 - c1 * c3 * s2, 0.0f,
|
||||
-c2 * s3, s2, c2 * c3, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f)
|
||||
}
|
||||
}
|
||||
|
||||
fun rotation(axis: Float3, angle: Float): Mat4 {
|
||||
val x = axis.x
|
||||
val y = axis.y
|
||||
@@ -483,10 +569,85 @@ fun rotation(axis: Float3, angle: Float): Mat4 {
|
||||
val d = 1.0f - c
|
||||
|
||||
return Mat4.of(
|
||||
x * x * d + c , x * y * d - z * s, x * z * d + y * s, 0.0f,
|
||||
y * x * d + z * s, y * y * d + c , y * z * d - x * s, 0.0f,
|
||||
z * x * d - y * s, z * y * d + x * s, z * z * d + c , 0.0f,
|
||||
0.0f , 0.0f , 0.0f , 1.0f
|
||||
x * x * d + c, x * y * d - z * s, x * z * d + y * s, 0.0f,
|
||||
y * x * d + z * s, y * y * d + c, y * z * d - x * s, 0.0f,
|
||||
z * x * d - y * s, z * y * d + x * s, z * z * d + c, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a Quaternion Rotation Matrix following the Hamilton convention
|
||||
*
|
||||
* Assume the destination and local coordinate spaces are initially aligned, and the local
|
||||
* coordinate space is then rotated counter-clockwise about a unit-length axis, k, by an angle,
|
||||
* theta.
|
||||
*/
|
||||
fun rotation(quaternion: Quaternion): Mat4 {
|
||||
val n = normalize(quaternion)
|
||||
return Mat4(
|
||||
Float4(
|
||||
1.0f - 2.0f * (n.y * n.y + n.z * n.z),
|
||||
2.0f * (n.x * n.y + n.z * n.w),
|
||||
2.0f * (n.x * n.z - n.y * n.w),
|
||||
),
|
||||
Float4(
|
||||
2.0f * (n.x * n.y - n.z * n.w),
|
||||
1.0f - 2.0f * (n.x * n.x + n.z * n.z),
|
||||
2.0f * (n.y * n.z + n.x * n.w),
|
||||
),
|
||||
Float4(
|
||||
2.0f * (n.x * n.z + n.y * n.w),
|
||||
2.0f * (n.y * n.z - n.x * n.w),
|
||||
1.0f - 2.0f * (n.x * n.x + n.y * n.y),
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract Quaternion rotation from a Matrix
|
||||
*/
|
||||
fun quaternion(m: Mat4): Quaternion {
|
||||
val trace = m.x.x + m.y.y + m.z.z
|
||||
return normalize(
|
||||
when {
|
||||
trace > 0.0f -> {
|
||||
val s = 2.0f * sqrt(trace + 1.0f)
|
||||
Quaternion(
|
||||
(m.y.z - m.z.y) / s,
|
||||
(m.z.x - m.x.z) / s,
|
||||
(m.x.y - m.y.x) / s,
|
||||
0.25f * s
|
||||
)
|
||||
}
|
||||
m.x.x > m.y.y && m.x.x > m.z.z -> {
|
||||
val s = 2.0f * sqrt(1.0f + m.x.x - m.y.y - m.z.z)
|
||||
Quaternion(
|
||||
0.25f * s,
|
||||
(m.y.x + m.x.y) / s,
|
||||
(m.z.x + m.x.z) / s,
|
||||
(m.y.z - m.z.y) / s
|
||||
)
|
||||
}
|
||||
m.y.y > m.z.z -> {
|
||||
val s = 2.0f * sqrt(1.0f + m.y.y - m.x.x - m.z.z)
|
||||
Quaternion(
|
||||
(m.y.x + m.x.y) / s,
|
||||
0.25f * s,
|
||||
(m.z.y + m.y.z) / s,
|
||||
(m.z.x - m.x.z) / s
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
val s = 2.0f * sqrt(1.0f + m.z.z - m.x.x - m.y.y)
|
||||
Quaternion(
|
||||
(m.z.x + m.x.z) / s,
|
||||
(m.z.y + m.y.z) / s,
|
||||
0.25f * s,
|
||||
(m.x.y - m.y.x) / s
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -500,7 +661,7 @@ fun lookTowards(eye: Float3, forward: Float3, up: Float3 = Float3(z = 1.0f)): Ma
|
||||
val f = normalize(forward)
|
||||
val r = normalize(f x up)
|
||||
val u = normalize(r x f)
|
||||
return Mat4(Float4(r), Float4(u), Float4(f), Float4(eye, 1.0f))
|
||||
return Mat4(Float4(r), Float4(u), Float4(-f), Float4(eye, 1.0f))
|
||||
}
|
||||
|
||||
fun perspective(fov: Float, ratio: Float, near: Float, far: Float): Mat4 {
|
||||
|
||||
@@ -58,7 +58,10 @@ private const val kSensitivity = 100f
|
||||
*
|
||||
* See `sample-gltf-viewer` for a usage example.
|
||||
*/
|
||||
class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
|
||||
class ModelViewer(
|
||||
val engine: Engine,
|
||||
private val uiHelper: UiHelper
|
||||
) : android.view.View.OnTouchListener {
|
||||
var asset: FilamentAsset? = null
|
||||
private set
|
||||
|
||||
@@ -71,6 +74,7 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
|
||||
|
||||
var normalizeSkinningWeights = true
|
||||
var recomputeBoundingBoxes = false
|
||||
var ignoreBindTransform = false
|
||||
|
||||
var cameraFocalLength = 28f
|
||||
set(value) {
|
||||
@@ -84,7 +88,6 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
|
||||
val renderer: Renderer
|
||||
@Entity val light: Int
|
||||
|
||||
private val uiHelper: UiHelper = UiHelper(UiHelper.ContextErrorPolicy.DONT_CHECK)
|
||||
private lateinit var displayHelper: DisplayHelper
|
||||
private lateinit var cameraManipulator: Manipulator
|
||||
private lateinit var gestureDetector: GestureDetector
|
||||
@@ -95,6 +98,7 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
|
||||
|
||||
private var swapChain: SwapChain? = null
|
||||
private var assetLoader: AssetLoader
|
||||
private var materialProvider: MaterialProvider
|
||||
private var resourceLoader: ResourceLoader
|
||||
private val readyRenderables = IntArray(128) // add up to 128 entities at a time
|
||||
|
||||
@@ -110,8 +114,9 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
|
||||
view.scene = scene
|
||||
view.camera = camera
|
||||
|
||||
assetLoader = AssetLoader(engine, UbershaderLoader(engine), EntityManager.get())
|
||||
resourceLoader = ResourceLoader(engine, normalizeSkinningWeights, recomputeBoundingBoxes)
|
||||
materialProvider = UbershaderLoader(engine)
|
||||
assetLoader = AssetLoader(engine, materialProvider, EntityManager.get())
|
||||
resourceLoader = ResourceLoader(engine, normalizeSkinningWeights, recomputeBoundingBoxes, ignoreBindTransform)
|
||||
|
||||
// Always add a direct light source since it is required for shadowing.
|
||||
// We highly recommend adding an indirect light as well.
|
||||
@@ -129,7 +134,12 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
|
||||
scene.addEntity(light)
|
||||
}
|
||||
|
||||
constructor(surfaceView: SurfaceView, engine: Engine = Engine.create(), manipulator: Manipulator? = null) : this(engine) {
|
||||
constructor(
|
||||
surfaceView: SurfaceView,
|
||||
engine: Engine = Engine.create(),
|
||||
uiHelper: UiHelper = UiHelper(UiHelper.ContextErrorPolicy.DONT_CHECK),
|
||||
manipulator: Manipulator? = null
|
||||
) : this(engine, uiHelper) {
|
||||
cameraManipulator = manipulator ?: Manipulator.Builder()
|
||||
.targetPosition(kDefaultObjectPosition.x, kDefaultObjectPosition.y, kDefaultObjectPosition.z)
|
||||
.viewport(surfaceView.width, surfaceView.height)
|
||||
@@ -144,7 +154,12 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
constructor(textureView: TextureView, engine: Engine = Engine.create(), manipulator: Manipulator? = null) : this(engine) {
|
||||
constructor(
|
||||
textureView: TextureView,
|
||||
engine: Engine = Engine.create(),
|
||||
uiHelper: UiHelper = UiHelper(UiHelper.ContextErrorPolicy.DONT_CHECK),
|
||||
manipulator: Manipulator? = null
|
||||
) : this(engine, uiHelper) {
|
||||
cameraManipulator = manipulator ?: Manipulator.Builder()
|
||||
.targetPosition(kDefaultObjectPosition.x, kDefaultObjectPosition.y, kDefaultObjectPosition.z)
|
||||
.viewport(textureView.width, textureView.height)
|
||||
@@ -215,8 +230,8 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
|
||||
fun transformToUnitCube(centerPoint: Float3 = kDefaultObjectPosition) {
|
||||
asset?.let { asset ->
|
||||
val tm = engine.transformManager
|
||||
var center = asset.boundingBox.center.let { v-> Float3(v[0], v[1], v[2]) }
|
||||
val halfExtent = asset.boundingBox.halfExtent.let { v-> Float3(v[0], v[1], v[2]) }
|
||||
var center = asset.boundingBox.center.let { v -> Float3(v[0], v[1], v[2]) }
|
||||
val halfExtent = asset.boundingBox.halfExtent.let { v -> Float3(v[0], v[1], v[2]) }
|
||||
val maxExtent = 2.0f * max(halfExtent)
|
||||
val scaleFactor = 2.0f / maxExtent
|
||||
center -= centerPoint / scaleFactor
|
||||
@@ -284,9 +299,9 @@ 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}
|
||||
val popRenderables = { count = asset.popRenderables(readyRenderables); count != 0 }
|
||||
while (popRenderables()) {
|
||||
for (i in 0..count-1) {
|
||||
for (i in 0..count - 1) {
|
||||
val ri = rcm.getInstance(readyRenderables[i])
|
||||
rcm.setScreenSpaceContactShadows(ri, true)
|
||||
}
|
||||
@@ -303,6 +318,8 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
|
||||
|
||||
destroyModel()
|
||||
assetLoader.destroy()
|
||||
materialProvider.destroyMaterials()
|
||||
materialProvider.destroy()
|
||||
resourceLoader.destroy()
|
||||
|
||||
engine.destroyEntity(light)
|
||||
@@ -383,4 +400,4 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
|
||||
companion object {
|
||||
private val kDefaultObjectPosition = Float3(0.0f, 0.0f, -4.0f)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,342 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Romain Guy
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@file:Suppress("NOTHING_TO_INLINE", "unused")
|
||||
|
||||
package com.google.android.filament.utils
|
||||
|
||||
import kotlin.math.*
|
||||
|
||||
enum class QuaternionComponent {
|
||||
X, Y, Z, W
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct Quaternion and set each value.
|
||||
* The Quaternion will be normalized during construction
|
||||
* Default: Identity
|
||||
*/
|
||||
data class Quaternion(
|
||||
var x: Float = 0.0f,
|
||||
var y: Float = 0.0f,
|
||||
var z: Float = 0.0f,
|
||||
var w: Float = 0.0f) {
|
||||
|
||||
constructor(v: Float3, w: Float = 0.0f) : this(v.x, v.y, v.z, w)
|
||||
constructor(v: Float4) : this(v.x, v.y, v.z, v.w)
|
||||
constructor(q: Quaternion) : this(q.x, q.y, q.z, q.w)
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Construct a Quaternion from an axis and angle in degrees
|
||||
*
|
||||
* @param axis Rotation direction
|
||||
* @param angle Angle size in degrees
|
||||
*/
|
||||
fun fromAxisAngle(axis: Float3, angle: Float): Quaternion {
|
||||
val r = radians(angle)
|
||||
return Quaternion(sin(r * 0.5f) * normalize(axis), cos(r * 0.5f))
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a Quaternion from Euler angles using YPR around ZYX respectively
|
||||
*
|
||||
* The Euler angles are applied in ZYX order.
|
||||
* i.e: a vector is first rotated about X (roll) then Y (pitch) and then Z (yaw).
|
||||
*
|
||||
* @param d Per axis Euler angles in degrees
|
||||
*/
|
||||
fun fromEuler(d: Float3): Quaternion {
|
||||
val r = transform(d, ::radians)
|
||||
return fromEulerZYX(r.z, r.y, r.x)
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a Quaternion from Euler angles using YPR around ZYX respectively
|
||||
*
|
||||
* The Euler angles are applied in ZYX order.
|
||||
* i.e: a vector is first rotated about X (roll) then Y (pitch) and then Z (yaw).
|
||||
*
|
||||
* @param roll about X axis in radians
|
||||
* @param pitch about Y axis in radians
|
||||
* @param yaw about Z axis in radians
|
||||
*/
|
||||
fun fromEulerZYX(yaw: Float = 0.0f, pitch: Float = 0.0f, roll: Float = 0.0f): Quaternion {
|
||||
val cy = cos(yaw * 0.5f)
|
||||
val sy = sin(yaw * 0.5f)
|
||||
val cp = cos(pitch * 0.5f)
|
||||
val sp = sin(pitch * 0.5f)
|
||||
val cr = cos(roll * 0.5f)
|
||||
val sr = sin(roll * 0.5f)
|
||||
|
||||
return Quaternion(
|
||||
sr * cp * cy - cr * sp * sy,
|
||||
cr * sp * cy + sr * cp * sy,
|
||||
cr * cp * sy - sr * sp * cy,
|
||||
cr * cp * cy + sr * sp * sy
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
inline var xyz: Float3
|
||||
get() = Float3(x, y, z)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
z = value.z
|
||||
}
|
||||
|
||||
inline var imaginary: Float3
|
||||
get() = xyz
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
z = value.z
|
||||
}
|
||||
|
||||
inline var real: Float
|
||||
get() = w
|
||||
set(value) {
|
||||
w = value
|
||||
}
|
||||
|
||||
inline var xyzw: Float4
|
||||
get() = Float4(x, y, z, w)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
z = value.z
|
||||
w = value.w
|
||||
}
|
||||
|
||||
operator fun get(index: QuaternionComponent) = when (index) {
|
||||
QuaternionComponent.X -> x
|
||||
QuaternionComponent.Y -> y
|
||||
QuaternionComponent.Z -> z
|
||||
QuaternionComponent.W -> w
|
||||
}
|
||||
|
||||
operator fun get(
|
||||
index1: QuaternionComponent,
|
||||
index2: QuaternionComponent,
|
||||
index3: QuaternionComponent): Float3 {
|
||||
return Float3(get(index1), get(index2), get(index3))
|
||||
}
|
||||
|
||||
operator fun get(
|
||||
index1: QuaternionComponent,
|
||||
index2: QuaternionComponent,
|
||||
index3: QuaternionComponent,
|
||||
index4: QuaternionComponent): Quaternion {
|
||||
return Quaternion(get(index1), get(index2), get(index3), get(index4))
|
||||
}
|
||||
|
||||
operator fun get(index: Int) = when (index) {
|
||||
0 -> x
|
||||
1 -> y
|
||||
2 -> z
|
||||
3 -> w
|
||||
else -> throw IllegalArgumentException("index must be in 0..3")
|
||||
}
|
||||
|
||||
operator fun get(index1: Int, index2: Int, index3: Int): Float3 {
|
||||
return Float3(get(index1), get(index2), get(index3))
|
||||
}
|
||||
|
||||
operator fun get(index1: Int, index2: Int, index3: Int, index4: Int): Quaternion {
|
||||
return Quaternion(get(index1), get(index2), get(index3), get(index4))
|
||||
}
|
||||
|
||||
inline operator fun invoke(index: Int) = get(index - 1)
|
||||
|
||||
operator fun set(index: Int, v: Float) = when (index) {
|
||||
0 -> x = v
|
||||
1 -> y = v
|
||||
2 -> z = v
|
||||
3 -> w = v
|
||||
else -> throw IllegalArgumentException("index must be in 0..3")
|
||||
}
|
||||
|
||||
operator fun set(index1: Int, index2: Int, v: Float) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
}
|
||||
|
||||
operator fun set(index1: Int, index2: Int, index3: Int, v: Float) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
set(index3, v)
|
||||
}
|
||||
|
||||
operator fun set(index1: Int, index2: Int, index3: Int, index4: Int, v: Float) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
set(index3, v)
|
||||
set(index4, v)
|
||||
}
|
||||
|
||||
operator fun set(index: QuaternionComponent, v: Float) = when (index) {
|
||||
QuaternionComponent.X -> x = v
|
||||
QuaternionComponent.Y -> y = v
|
||||
QuaternionComponent.Z -> z = v
|
||||
QuaternionComponent.W -> w = v
|
||||
}
|
||||
|
||||
operator fun set(index1: QuaternionComponent, index2: QuaternionComponent, v: Float) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
}
|
||||
|
||||
operator fun set(
|
||||
index1: QuaternionComponent, index2: QuaternionComponent, index3: QuaternionComponent, v: Float) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
set(index3, v)
|
||||
}
|
||||
|
||||
operator fun set(
|
||||
index1: QuaternionComponent, index2: QuaternionComponent,
|
||||
index3: QuaternionComponent, index4: QuaternionComponent, v: Float) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
set(index3, v)
|
||||
set(index4, v)
|
||||
}
|
||||
|
||||
operator fun unaryMinus() = Quaternion(-x, -y, -z, -w)
|
||||
|
||||
inline operator fun plus(v: Float) = Quaternion(x + v, y + v, z + v, w + v)
|
||||
inline operator fun minus(v: Float) = Quaternion(x - v, y - v, z - v, w - v)
|
||||
inline operator fun times(v: Float) = Quaternion(x * v, y * v, z * v, w * v)
|
||||
inline operator fun div(v: Float) = Quaternion(x / v, y / v, z / v, w / v)
|
||||
|
||||
inline operator fun times(v: Float3) = (this * Quaternion(v, 0.0f) * inverse(this)).xyz
|
||||
|
||||
inline operator fun plus(q: Quaternion) = Quaternion(x + q.x, y + q.y, z + q.z, w + q.w)
|
||||
inline operator fun minus(q: Quaternion) = Quaternion(x - q.x, y - q.y, z - q.z, w - q.w)
|
||||
inline operator fun times(q: Quaternion) = Quaternion(
|
||||
w * q.x + x * q.w + y * q.z - z * q.y,
|
||||
w * q.y - x * q.z + y * q.w + z * q.x,
|
||||
w * q.z + x * q.y - y * q.x + z * q.w,
|
||||
w * q.w - x * q.x - y * q.y - z * q.z)
|
||||
|
||||
inline fun transform(block: (Float) -> Float): Quaternion {
|
||||
x = block(x)
|
||||
y = block(y)
|
||||
z = block(z)
|
||||
w = block(w)
|
||||
return this
|
||||
}
|
||||
|
||||
fun toEulerAngles() = eulerAngles(this)
|
||||
|
||||
fun toMatrix() = rotation(this)
|
||||
|
||||
fun toFloatArray() = floatArrayOf(x, y, z, w)
|
||||
}
|
||||
|
||||
inline operator fun Float.plus(q: Quaternion) = Quaternion(this + q.x, this + q.y, this + q.z, this + q.w)
|
||||
inline operator fun Float.minus(q: Quaternion) = Quaternion(this - q.x, this - q.y, this - q.z, this - q.w)
|
||||
inline operator fun Float.times(q: Quaternion) = Quaternion(this * q.x, this * q.y, this * q.z, this * q.w)
|
||||
inline operator fun Float.div(q: Quaternion) = Quaternion(this / q.x, this / q.y, this / q.z, this / q.w)
|
||||
|
||||
inline fun abs(q: Quaternion) = Quaternion(abs(q.x), abs(q.y), abs(q.z), abs(q.w))
|
||||
inline fun length(q: Quaternion) = sqrt(q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w)
|
||||
inline fun length2(q: Quaternion) = q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w
|
||||
inline fun dot(a: Quaternion, b: Quaternion) = a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w
|
||||
|
||||
/**
|
||||
* Rescale the Quaternion to the unit length
|
||||
*/
|
||||
fun normalize(q: Quaternion): Quaternion {
|
||||
val l = 1.0f / length(q)
|
||||
return Quaternion(q.x * l, q.y * l, q.z * l, q.w * l)
|
||||
}
|
||||
|
||||
fun conjugate(q: Quaternion): Quaternion = Quaternion(-q.x, -q.y, -q.z, q.w)
|
||||
|
||||
fun inverse(q: Quaternion): Quaternion {
|
||||
val d = 1.0f / dot(q, q)
|
||||
return Quaternion(-q.x * d, -q.y * d, -q.z * d, q.w * d)
|
||||
}
|
||||
|
||||
fun cross(a: Quaternion, b: Quaternion): Quaternion {
|
||||
val m = a * b
|
||||
return Quaternion(m.x, m.y, m.z, 0.0f)
|
||||
}
|
||||
|
||||
/**
|
||||
* Spherical linear interpolation between two given orientations
|
||||
*
|
||||
* If t is 0 this returns a.
|
||||
* As t approaches 1 slerp may approach either b or -b (whichever is closest to a)
|
||||
* If t is above 1 or below 0 the result will be extrapolated.
|
||||
* @param a The beginning value
|
||||
* @param b The ending value
|
||||
* @param t The ratio between the two floats
|
||||
* @param valueEps Prevent blowing up when slerping between two quaternions that are very near each
|
||||
* other. Linear interpolation (lerp) is returned in this case.
|
||||
*
|
||||
* @return Interpolated value between the two floats
|
||||
*/
|
||||
fun slerp(a: Quaternion, b: Quaternion, t: Float, valueEps: Float = 0.0000000001f): Quaternion {
|
||||
// could also be computed as: pow(q * inverse(p), t) * p;
|
||||
val d = dot(a, b)
|
||||
val absd = abs(d)
|
||||
// Prevent blowing up when slerping between two quaternions that are very near each other.
|
||||
if ((1.0f - absd) < valueEps) {
|
||||
return normalize(lerp(if (d < 0.0f) -a else a, b, t))
|
||||
}
|
||||
val npq = sqrt(dot(a, a) * dot(b, b)) // ||p|| * ||q||
|
||||
val acos = acos(clamp(absd / npq, -1.0f, 1.0f))
|
||||
val acos0 = acos * (1.0f - t)
|
||||
val acos1 = acos * t
|
||||
val sina = sin(acos)
|
||||
if (sina < valueEps) {
|
||||
return normalize(lerp(a, b, t))
|
||||
}
|
||||
val isina = 1.0f / sina
|
||||
val s0 = sin(acos0) * isina
|
||||
val s1 = sin(acos1) * isina
|
||||
// ensure we're taking the "short" side
|
||||
return normalize(s0 * a + (if (d < 0.0f) -s1 else (s1)) * b)
|
||||
}
|
||||
|
||||
fun lerp(a: Quaternion, b: Quaternion, t: Float): Quaternion {
|
||||
return ((1 - t) * a) + (t * b)
|
||||
}
|
||||
|
||||
fun nlerp(a: Quaternion, b: Quaternion, t: Float): Quaternion {
|
||||
return normalize(lerp(a, b, t))
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a Quaternion to Euler angles using YPR around ZYX respectively
|
||||
*
|
||||
* The Euler angles are applied in ZYX order
|
||||
*/
|
||||
fun eulerAngles(q: Quaternion): Float3 {
|
||||
val nq = normalize(q)
|
||||
return Float3(
|
||||
// roll (x-axis rotation)
|
||||
degrees(atan2(2.0f * (nq.y * nq.z + nq.w * nq.x),
|
||||
nq.w * nq.w - nq.x * nq.x - nq.y * nq.y + nq.z * nq.z)),
|
||||
// pitch (y-axis rotation)
|
||||
degrees(asin(-2.0f * (nq.x * nq.z - nq.w * nq.y))),
|
||||
// yaw (z-axis rotation)
|
||||
degrees(atan2(2.0f * (nq.x * nq.y + nq.w * nq.z),
|
||||
nq.w * nq.w + nq.x * nq.x - nq.y * nq.y - nq.z * nq.z)))
|
||||
}
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
package com.google.android.filament.utils
|
||||
|
||||
import kotlin.math.pow
|
||||
|
||||
const val FPI = 3.1415926536f
|
||||
const val HALF_PI = FPI * 0.5f
|
||||
const val TWO_PI = FPI * 2.0f
|
||||
@@ -40,4 +42,4 @@ inline fun fract(v: Float) = v % 1
|
||||
|
||||
inline fun sqr(v: Float) = v * v
|
||||
|
||||
inline fun pow(x: Float, y: Float) = StrictMath.pow(x.toDouble(), y.toDouble()).toFloat()
|
||||
inline fun pow(x: Float, y: Float) = (x.toDouble().pow(y.toDouble())).toFloat()
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
@file:Suppress("NOTHING_TO_INLINE")
|
||||
@file:Suppress("NOTHING_TO_INLINE", "unused")
|
||||
|
||||
package com.google.android.filament.utils
|
||||
|
||||
@@ -117,17 +117,8 @@ data class Float2(var x: Float = 0.0f, var y: Float = 0.0f) {
|
||||
}
|
||||
|
||||
operator fun unaryMinus() = Float2(-x, -y)
|
||||
operator fun inc(): Float2 {
|
||||
x += 1.0f
|
||||
y += 1.0f
|
||||
return this
|
||||
}
|
||||
|
||||
operator fun dec(): Float2 {
|
||||
x -= 1.0f
|
||||
y -= 1.0f
|
||||
return this
|
||||
}
|
||||
operator fun inc() = Float2(x++, y++)
|
||||
operator fun dec() = Float2(x--, y--)
|
||||
|
||||
inline operator fun plus(v: Float) = Float2(x + v, y + v)
|
||||
inline operator fun minus(v: Float) = Float2(x - v, y - v)
|
||||
@@ -144,6 +135,8 @@ data class Float2(var x: Float = 0.0f, var y: Float = 0.0f) {
|
||||
y = block(y)
|
||||
return this
|
||||
}
|
||||
|
||||
fun toFloatArray() = floatArrayOf(x, y)
|
||||
}
|
||||
|
||||
data class Float3(var x: Float = 0.0f, var y: Float = 0.0f, var z: Float = 0.0f) {
|
||||
@@ -284,29 +277,15 @@ data class Float3(var x: Float = 0.0f, var y: Float = 0.0f, var z: Float = 0.0f)
|
||||
}
|
||||
|
||||
operator fun set(
|
||||
index1: VectorComponent,
|
||||
index2: VectorComponent,
|
||||
index3: VectorComponent,
|
||||
v: Float) {
|
||||
index1: VectorComponent, index2: VectorComponent, index3: VectorComponent, v: Float) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
set(index3, v)
|
||||
}
|
||||
|
||||
operator fun unaryMinus() = Float3(-x, -y, -z)
|
||||
operator fun inc(): Float3 {
|
||||
x += 1.0f
|
||||
y += 1.0f
|
||||
z += 1.0f
|
||||
return this
|
||||
}
|
||||
|
||||
operator fun dec(): Float3 {
|
||||
x -= 1.0f
|
||||
y -= 1.0f
|
||||
z -= 1.0f
|
||||
return this
|
||||
}
|
||||
operator fun inc() = Float3(x++, y++, z++)
|
||||
operator fun dec() = Float3(x--, y--, z--)
|
||||
|
||||
inline operator fun plus(v: Float) = Float3(x + v, y + v, z + v)
|
||||
inline operator fun minus(v: Float) = Float3(x - v, y - v, z - v)
|
||||
@@ -329,6 +308,8 @@ data class Float3(var x: Float = 0.0f, var y: Float = 0.0f, var z: Float = 0.0f)
|
||||
z = block(z)
|
||||
return this
|
||||
}
|
||||
|
||||
fun toFloatArray() = floatArrayOf(x, y, z)
|
||||
}
|
||||
|
||||
data class Float4(
|
||||
@@ -529,14 +510,15 @@ data class Float4(
|
||||
set(index2, v)
|
||||
}
|
||||
|
||||
operator fun set(index1: VectorComponent, index2: VectorComponent, index3: VectorComponent,
|
||||
v: Float) {
|
||||
operator fun set(
|
||||
index1: VectorComponent, index2: VectorComponent, index3: VectorComponent, v: Float) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
set(index3, v)
|
||||
}
|
||||
|
||||
operator fun set(index1: VectorComponent, index2: VectorComponent,
|
||||
operator fun set(
|
||||
index1: VectorComponent, index2: VectorComponent,
|
||||
index3: VectorComponent, index4: VectorComponent, v: Float) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
@@ -545,21 +527,8 @@ data class Float4(
|
||||
}
|
||||
|
||||
operator fun unaryMinus() = Float4(-x, -y, -z, -w)
|
||||
operator fun inc(): Float4 {
|
||||
x += 1.0f
|
||||
y += 1.0f
|
||||
z += 1.0f
|
||||
w += 1.0f
|
||||
return this
|
||||
}
|
||||
|
||||
operator fun dec(): Float4 {
|
||||
x -= 1.0f
|
||||
y -= 1.0f
|
||||
z -= 1.0f
|
||||
w -= 1.0f
|
||||
return this
|
||||
}
|
||||
operator fun inc() = Float4(x++, y++, z++, w++)
|
||||
operator fun dec() = Float4(x--, y--, z--, w--)
|
||||
|
||||
inline operator fun plus(v: Float) = Float4(x + v, y + v, z + v, w + v)
|
||||
inline operator fun minus(v: Float) = Float4(x - v, y - v, z - v, w - v)
|
||||
@@ -588,6 +557,8 @@ data class Float4(
|
||||
w = block(w)
|
||||
return this
|
||||
}
|
||||
|
||||
fun toFloatArray() = floatArrayOf(x, y, z, w)
|
||||
}
|
||||
|
||||
inline operator fun Float.plus(v: Float2) = Float2(this + v.x, this + v.y)
|
||||
@@ -615,25 +586,29 @@ fun refract(i: Float2, n: Float2, eta: Float): Float2 {
|
||||
inline fun clamp(v: Float2, min: Float, max: Float): Float2 {
|
||||
return Float2(
|
||||
clamp(v.x, min, max),
|
||||
clamp(v.y, min, max))
|
||||
clamp(v.y, min, max)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun clamp(v: Float2, min: Float2, max: Float2): Float2 {
|
||||
return Float2(
|
||||
clamp(v.x, min.x, max.x),
|
||||
clamp(v.y, min.y, max.y))
|
||||
clamp(v.y, min.y, max.y)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun mix(a: Float2, b: Float2, x: Float): Float2 {
|
||||
return Float2(
|
||||
mix(a.x, b.x, x),
|
||||
mix(a.y, b.y, x))
|
||||
mix(a.y, b.y, x)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun mix(a: Float2, b: Float2, x: Float2): Float2 {
|
||||
return Float2(
|
||||
mix(a.x, b.x, x.x),
|
||||
mix(a.y, b.y, x.y))
|
||||
mix(a.y, b.y, x.y)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun min(v: Float2) = min(v.x, v.y)
|
||||
@@ -704,28 +679,32 @@ inline fun clamp(v: Float3, min: Float, max: Float): Float3 {
|
||||
return Float3(
|
||||
clamp(v.x, min, max),
|
||||
clamp(v.y, min, max),
|
||||
clamp(v.z, min, max))
|
||||
clamp(v.z, min, max)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun clamp(v: Float3, min: Float3, max: Float3): Float3 {
|
||||
return Float3(
|
||||
clamp(v.x, min.x, max.x),
|
||||
clamp(v.y, min.y, max.y),
|
||||
clamp(v.z, min.z, max.z))
|
||||
clamp(v.z, min.z, max.z)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun mix(a: Float3, b: Float3, x: Float): Float3 {
|
||||
return Float3(
|
||||
mix(a.x, b.x, x),
|
||||
mix(a.y, b.y, x),
|
||||
mix(a.z, b.z, x))
|
||||
mix(a.z, b.z, x)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun mix(a: Float3, b: Float3, x: Float3): Float3 {
|
||||
return Float3(
|
||||
mix(a.x, b.x, x.x),
|
||||
mix(a.y, b.y, x.y),
|
||||
mix(a.z, b.z, x.z))
|
||||
mix(a.z, b.z, x.z)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun min(v: Float3) = min(v.x, min(v.y, v.z))
|
||||
@@ -784,7 +763,8 @@ inline fun clamp(v: Float4, min: Float, max: Float): Float4 {
|
||||
clamp(v.x, min, max),
|
||||
clamp(v.y, min, max),
|
||||
clamp(v.z, min, max),
|
||||
clamp(v.w, min, max))
|
||||
clamp(v.w, min, max)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun clamp(v: Float4, min: Float4, max: Float4): Float4 {
|
||||
@@ -792,7 +772,8 @@ inline fun clamp(v: Float4, min: Float4, max: Float4): Float4 {
|
||||
clamp(v.x, min.x, max.x),
|
||||
clamp(v.y, min.y, max.y),
|
||||
clamp(v.z, min.z, max.z),
|
||||
clamp(v.w, min.z, max.w))
|
||||
clamp(v.w, min.z, max.w)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun mix(a: Float4, b: Float4, x: Float): Float4 {
|
||||
@@ -800,7 +781,8 @@ inline fun mix(a: Float4, b: Float4, x: Float): Float4 {
|
||||
mix(a.x, b.x, x),
|
||||
mix(a.y, b.y, x),
|
||||
mix(a.z, b.z, x),
|
||||
mix(a.w, b.w, x))
|
||||
mix(a.w, b.w, x)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun mix(a: Float4, b: Float4, x: Float4): Float4 {
|
||||
@@ -1075,10 +1057,7 @@ data class Bool3(var x: Boolean = false, var y: Boolean = false, var z: Boolean
|
||||
}
|
||||
|
||||
operator fun set(
|
||||
index1: VectorComponent,
|
||||
index2: VectorComponent,
|
||||
index3: VectorComponent,
|
||||
v: Boolean) {
|
||||
index1: VectorComponent, index2: VectorComponent, index3: VectorComponent, v: Boolean) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
set(index3, v)
|
||||
@@ -1282,14 +1261,15 @@ data class Bool4(
|
||||
set(index2, v)
|
||||
}
|
||||
|
||||
operator fun set(index1: VectorComponent, index2: VectorComponent, index3: VectorComponent,
|
||||
v: Boolean) {
|
||||
operator fun set(
|
||||
index1: VectorComponent, index2: VectorComponent, index3: VectorComponent, v: Boolean) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
set(index3, v)
|
||||
}
|
||||
|
||||
operator fun set(index1: VectorComponent, index2: VectorComponent,
|
||||
operator fun set(
|
||||
index1: VectorComponent, index2: VectorComponent,
|
||||
index3: VectorComponent, index4: VectorComponent, v: Boolean) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
|
||||
@@ -45,8 +45,6 @@ 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
|
||||
@@ -76,6 +74,8 @@ set(GLTFIO_INCLUDE_DIRS
|
||||
..
|
||||
${FILAMENT_DIR}/include
|
||||
${FILAMENT_DIR}/include/gltfio/resources
|
||||
../../filament/backend/include
|
||||
../../libs/gltfio/include
|
||||
../../third_party/cgltf
|
||||
../../third_party/robin-map
|
||||
../../third_party/hat-trie
|
||||
|
||||
@@ -27,7 +27,8 @@ android {
|
||||
|
||||
dependencies {
|
||||
implementation deps.androidx.annotations
|
||||
implementation project(':filament-android')
|
||||
|
||||
api project(':filament-android')
|
||||
}
|
||||
|
||||
apply from: rootProject.file('gradle/gradle-mvn-push.gradle')
|
||||
|
||||
@@ -69,7 +69,7 @@ public:
|
||||
jclass providerClass = env->GetObjectClass(provider);
|
||||
|
||||
mCreateMaterialInstance = env->GetMethodID(providerClass, "createMaterialInstance",
|
||||
"(L" JAVA_MATERIAL_KEY ";[ILjava/lang/String;)Lcom/google/android/filament/MaterialInstance;");
|
||||
"(L" JAVA_MATERIAL_KEY ";[ILjava/lang/String;Ljava/lang/String;)Lcom/google/android/filament/MaterialInstance;");
|
||||
assert_invariant(mCreateMaterialInstance);
|
||||
|
||||
mGetMaterials = env->GetMethodID(providerClass, "getMaterials",
|
||||
@@ -89,7 +89,7 @@ public:
|
||||
delete mPreviousMaterials;
|
||||
}
|
||||
|
||||
MaterialInstance* createMaterialInstance(MaterialKey* config, UvMap* uvmap, const char* label) override {
|
||||
MaterialInstance* createMaterialInstance(MaterialKey* config, UvMap* uvmap, const char* label, const char* extras) override {
|
||||
// Create a Java object for the material key and copy the native fields into it.
|
||||
jobject javaKey = mEnv->NewObject(mMaterialKeyClass, mMaterialKeyConstructor);
|
||||
|
||||
@@ -99,12 +99,15 @@ public:
|
||||
// Convert the optional label into a Java string.
|
||||
jstring stringLabel = label ? mEnv->NewStringUTF(label) : nullptr;
|
||||
|
||||
// Convert the optional extras into a Java string.
|
||||
jstring stringExtras = extras ? mEnv->NewStringUTF(extras) : nullptr;
|
||||
|
||||
// Allocate space for the output argument.
|
||||
jintArray uvMapArray = mEnv->NewIntArray(8);
|
||||
|
||||
// Call the Java-based material provider.
|
||||
jobject materialInstance = mEnv->CallObjectMethod(mJavaProvider, mCreateMaterialInstance,
|
||||
javaKey, uvMapArray, stringLabel);
|
||||
javaKey, uvMapArray, stringLabel, stringExtras);
|
||||
|
||||
// Copy the UvMap results from the JVM array into the native array.
|
||||
if (uvmap) {
|
||||
@@ -125,6 +128,10 @@ public:
|
||||
mEnv->DeleteLocalRef(stringLabel);
|
||||
}
|
||||
|
||||
if (stringExtras) {
|
||||
mEnv->DeleteLocalRef(stringExtras);
|
||||
}
|
||||
|
||||
if (materialInstance == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -177,6 +184,8 @@ Java_com_google_android_filament_gltfio_AssetLoader_nCreateAssetLoader(JNIEnv* e
|
||||
jmethodID getNativeObject = env->GetMethodID(klass, "getNativeObject", "()J");
|
||||
if (getNativeObject) {
|
||||
materialProvider = (MaterialProvider*) env->CallLongMethod(provider, getNativeObject);
|
||||
} else {
|
||||
env->ExceptionClear();
|
||||
}
|
||||
|
||||
if (materialProvider == nullptr) {
|
||||
@@ -192,7 +201,6 @@ extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_AssetLoader_nDestroyAssetLoader(JNIEnv*, jclass,
|
||||
jlong nativeLoader) {
|
||||
AssetLoader* loader = (AssetLoader*) nativeLoader;
|
||||
delete loader->getMaterialProvider();
|
||||
NameComponentManager* names = loader->getNames();
|
||||
AssetLoader::destroy(&loader);
|
||||
delete names;
|
||||
@@ -237,6 +245,14 @@ Java_com_google_android_filament_gltfio_AssetLoader_nCreateInstancedAsset(JNIEnv
|
||||
return asset;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_gltfio_AssetLoader_nCreateInstance(JNIEnv* env, jclass,
|
||||
jlong nativeLoader, jlong nativeAsset) {
|
||||
AssetLoader* loader = (AssetLoader*) nativeLoader;
|
||||
FilamentAsset* primary = (FilamentAsset*) nativeAsset;
|
||||
return (jlong) loader->createInstance(primary);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_AssetLoader_nEnableDiagnostics(JNIEnv*, jclass,
|
||||
jlong nativeLoader, jboolean enable) {
|
||||
|
||||
@@ -215,6 +215,15 @@ Java_com_google_android_filament_gltfio_FilamentAsset_nGetResourceUriCount(JNIEn
|
||||
return (jint) asset->getResourceUriCount();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jstring JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nGetMorphTargetNameAt(JNIEnv* env, jclass,
|
||||
jlong nativeAsset, jint entityId, jint targetIndex) {
|
||||
Entity entity = Entity::import(entityId);
|
||||
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
|
||||
const char* val = asset->getMorphTargetNameAt(entity, (size_t) targetIndex);
|
||||
return val ? env->NewStringUTF(val) : nullptr;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_FilamentAsset_nGetResourceUris(JNIEnv* env, jclass,
|
||||
jlong nativeAsset,
|
||||
|
||||
@@ -63,15 +63,12 @@ void MaterialKeyHelper::init(JNIEnv* env) {
|
||||
sheenColorUV = field("sheenColorUV", "I");
|
||||
hasSheenRoughnessTexture = field("hasSheenRoughnessTexture", "Z");
|
||||
sheenRoughnessUV = field("sheenRoughnessUV", "I");
|
||||
hasVolumeThicknessTexture = field("hasVolumeThicknessTexture", "Z");
|
||||
volumeThicknessUV = field("volumeThicknessUV", "I");
|
||||
hasSheen = field("hasSheen", "Z");
|
||||
hasIOR = field("hasIOR", "Z");
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_MaterialProvider_00024MaterialKey_nGlobalInit(JNIEnv* env, jclass) {
|
||||
MaterialKeyHelper::get().init(env);
|
||||
}
|
||||
|
||||
void MaterialKeyHelper::copy(JNIEnv* env, MaterialKey& dst, jobject src) {
|
||||
dst.doubleSided = env->GetBooleanField(src, doubleSided);
|
||||
dst.unlit = env->GetBooleanField(src, unlit);
|
||||
@@ -104,6 +101,8 @@ void MaterialKeyHelper::copy(JNIEnv* env, MaterialKey& dst, jobject src) {
|
||||
dst.sheenColorUV = env->GetIntField(src, sheenColorUV);
|
||||
dst.hasSheenRoughnessTexture = env->GetBooleanField(src, hasSheenRoughnessTexture);
|
||||
dst.sheenRoughnessUV = env->GetIntField(src, sheenRoughnessUV);
|
||||
dst.hasVolumeThicknessTexture = env->GetBooleanField(src, hasVolumeThicknessTexture);
|
||||
dst.volumeThicknessUV = env->GetIntField(src, volumeThicknessUV);
|
||||
dst.hasSheen = env->GetBooleanField(src, hasSheen);
|
||||
dst.hasIOR = env->GetBooleanField(src, hasIOR);
|
||||
}
|
||||
@@ -140,6 +139,39 @@ void MaterialKeyHelper::copy(JNIEnv* env, jobject dst, const MaterialKey& src) {
|
||||
env->SetIntField(dst, sheenColorUV, src.sheenColorUV);
|
||||
env->SetBooleanField(dst, hasSheenRoughnessTexture, src.hasSheenRoughnessTexture);
|
||||
env->SetIntField(dst, sheenRoughnessUV, src.sheenRoughnessUV);
|
||||
env->SetBooleanField(dst, hasVolumeThicknessTexture, src.hasVolumeThicknessTexture);
|
||||
env->SetIntField(dst, volumeThicknessUV, src.volumeThicknessUV);
|
||||
env->SetBooleanField(dst, hasSheen, src.hasSheen);
|
||||
env->SetBooleanField(dst, hasIOR, src.hasIOR);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_MaterialProvider_00024MaterialKey_nGlobalInit(JNIEnv* env, jclass) {
|
||||
MaterialKeyHelper::get().init(env);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_gltfio_MaterialProvider_00024MaterialKey_nConstrainMaterial(JNIEnv* env, jclass,
|
||||
jobject materialKey, jintArray uvMap) {
|
||||
MaterialKey nativeMaterialKey = {};
|
||||
|
||||
auto& helper = MaterialKeyHelper::get();
|
||||
helper.copy(env, nativeMaterialKey, materialKey);
|
||||
|
||||
UvMap nativeUvMap = {};
|
||||
constrainMaterial(&nativeMaterialKey, &nativeUvMap);
|
||||
|
||||
// Copy the UvMap results from the native array into the JVM array.
|
||||
jint* elements = env->GetIntArrayElements(uvMap, nullptr);
|
||||
if (elements) {
|
||||
const size_t javaSize = env->GetArrayLength(uvMap);
|
||||
for (int i = 0, n = std::min(javaSize, nativeUvMap.size()); i < n; ++i) {
|
||||
elements[i] = nativeUvMap[i];
|
||||
}
|
||||
env->ReleaseIntArrayElements(uvMap, elements, 0);
|
||||
}
|
||||
|
||||
// The config parameter is an in-out parameter so we need to copy the results back to Java.
|
||||
helper.copy(env, materialKey, nativeMaterialKey);
|
||||
}
|
||||
|
||||
@@ -61,6 +61,8 @@ private:
|
||||
jfieldID sheenColorUV;
|
||||
jfieldID hasSheenRoughnessTexture;
|
||||
jfieldID sheenRoughnessUV;
|
||||
jfieldID hasVolumeThicknessTexture;
|
||||
jfieldID volumeThicknessUV;
|
||||
jfieldID hasSheen;
|
||||
jfieldID hasIOR;
|
||||
};
|
||||
|
||||
@@ -35,10 +35,11 @@ static void destroy(void*, size_t, void *userData) {
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_gltfio_ResourceLoader_nCreateResourceLoader(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jboolean normalizeSkinningWeights, jboolean recomputeBoundingBoxes) {
|
||||
jlong nativeEngine, jboolean normalizeSkinningWeights, jboolean recomputeBoundingBoxes,
|
||||
jboolean ignoreBindTransform) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
return (jlong) new ResourceLoader({ engine, {}, (bool) normalizeSkinningWeights,
|
||||
(bool) recomputeBoundingBoxes });
|
||||
(bool) recomputeBoundingBoxes, (bool) ignoreBindTransform});
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
|
||||
@@ -66,7 +66,7 @@ Java_com_google_android_filament_gltfio_UbershaderLoader_nCreateMaterialInstance
|
||||
for (int i = 0, n = std::min(javaSize, nativeUvMap.size()); i < n; ++i) {
|
||||
elements[i] = nativeUvMap[i];
|
||||
}
|
||||
env->ReleaseIntArrayElements(uvmap, elements, JNI_ABORT);
|
||||
env->ReleaseIntArrayElements(uvmap, elements, 0);
|
||||
}
|
||||
|
||||
// The config parameter is an in-out parameter so we need to copy the results back to Java.
|
||||
|
||||
@@ -45,7 +45,8 @@ import java.nio.Buffer;
|
||||
*
|
||||
* ...
|
||||
*
|
||||
* assetLoader = AssetLoader(engine, UbershaderLoader(engine), EntityManager.get())
|
||||
* materialProvider = UbershaderLoader(engine)
|
||||
* assetLoader = AssetLoader(engine, materialProvider, EntityManager.get())
|
||||
*
|
||||
* filamentAsset = assets.open("models/lucy.gltf").use { input ->
|
||||
* val bytes = ByteArray(input.available())
|
||||
@@ -60,7 +61,6 @@ import java.nio.Buffer;
|
||||
* }
|
||||
* resourceLoader.loadResources(filamentAsset)
|
||||
* resourceLoader.destroy()
|
||||
* animator = asset.getAnimator()
|
||||
* filamentAsset.releaseSourceData();
|
||||
*
|
||||
* scene.addEntities(filamentAsset.entities)
|
||||
@@ -104,11 +104,13 @@ public class AssetLoader {
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees all memory consumed by the native <code>AssetLoader</code> and its material cache.
|
||||
* Frees all memory consumed by the native <code>AssetLoader</code>
|
||||
*
|
||||
* This does not not automatically free the cache of materials, nor
|
||||
* does it free the entities for created assets (see destroyAsset).
|
||||
*/
|
||||
public void destroy() {
|
||||
nDestroyAssetLoader(mNativeObject);
|
||||
mMaterialCache.destroyMaterials();
|
||||
mNativeObject = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.google.android.filament.gltfio;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
@@ -197,11 +198,11 @@ public class FilamentAsset {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates or retrieves the <code>Animator</code> interface for this asset.
|
||||
* Retrieves the <code>Animator</code> interface for this asset.
|
||||
*
|
||||
* <p>When calling this for the first time, this must be called after
|
||||
* {@link ResourceLoader#loadResources}. When the asset is destroyed, its
|
||||
* animator becomes invalid.</p>
|
||||
* {@link ResourceLoader#loadResources} or {@link ResourceLoader#asyncBeginLoad}. When the asset
|
||||
* is destroyed, its animator becomes invalid.</p>
|
||||
*/
|
||||
public @NonNull Animator getAnimator() {
|
||||
if (mAnimator != null) {
|
||||
@@ -215,6 +216,13 @@ public class FilamentAsset {
|
||||
return mAnimator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the target name at target index in the given entity.
|
||||
*/
|
||||
public String getMorphTargetNameAt(@Entity int entity, int targetIndex) {
|
||||
return nGetMorphTargetNameAt(getNativeObject(), entity, targetIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets resource URIs for all externally-referenced buffers.
|
||||
*/
|
||||
@@ -227,9 +235,9 @@ public class FilamentAsset {
|
||||
/**
|
||||
* Reclaims CPU-side memory for URI strings, binding lists, and raw animation data.
|
||||
*
|
||||
* This should only be called after ResourceLoader#loadResources().
|
||||
* If using Animator, this should be called after getAnimator().
|
||||
* If this is an instanced asset, this prevents creation of new instances.
|
||||
* This should only be called after ResourceLoader#loadResources() or
|
||||
* ResourceLoader#asyncBeginLoad(). If this is an instanced asset, this prevents creation of new
|
||||
* instances.
|
||||
*/
|
||||
public void releaseSourceData() {
|
||||
nReleaseSourceData(mNativeObject);
|
||||
@@ -264,6 +272,7 @@ public class FilamentAsset {
|
||||
private static native String nGetName(long nativeAsset, int entity);
|
||||
private static native String nGetExtras(long nativeAsset, int entity);
|
||||
private static native long nGetAnimator(long nativeAsset);
|
||||
private static native String nGetMorphTargetNameAt(long nativeAsset, int entity, int targetIndex);
|
||||
private static native int nGetResourceUriCount(long nativeAsset);
|
||||
private static native void nGetResourceUris(long nativeAsset, String[] result);
|
||||
private static native void nReleaseSourceData(long nativeAsset);
|
||||
|
||||
@@ -74,10 +74,7 @@ public class FilamentInstance {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates or retrieves the <code>Animator</code> for this instance.
|
||||
*
|
||||
* <p>When calling this for the first time, this must be called after
|
||||
* {@link ResourceLoader#loadResources}.</p>
|
||||
* Retrieves the <code>Animator</code> for this instance.
|
||||
*/
|
||||
public @NonNull Animator getAnimator() {
|
||||
if (mAnimator != null) {
|
||||
|
||||
@@ -62,6 +62,8 @@ public interface MaterialProvider {
|
||||
public int sheenColorUV;
|
||||
public boolean hasSheenRoughnessTexture;
|
||||
public int sheenRoughnessUV;
|
||||
public boolean hasVolumeThicknessTexture;
|
||||
public int volumeThicknessUV;
|
||||
public boolean hasSheen;
|
||||
public boolean hasIOR;
|
||||
|
||||
@@ -69,7 +71,25 @@ public interface MaterialProvider {
|
||||
static {
|
||||
nGlobalInit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate UV map according to the material key, altering latter if required.
|
||||
*
|
||||
* Filament supports up to 2 UV sets. glTF has arbitrary texcoord set indices, but it
|
||||
* allows implementations to support only 2 simultaneous sets. Here we build a mapping
|
||||
* table with 1-based indices where 0 means unused. Note that the order in which we drop
|
||||
* textures can affect the look of certain assets. This "order of degradation" is
|
||||
* stipulated by the glTF 2.0 specification.
|
||||
*
|
||||
* @param uvmap Output argument that gets populated with a small table that maps from a
|
||||
* glTF uv index to a Filament uv index (0 = UNUSED, 1 = UV0, 2 = UV1).
|
||||
*/
|
||||
public void constrainMaterial(@NonNull @Size(min = 8) int[] uvmap) {
|
||||
nConstrainMaterial(this, uvmap);
|
||||
}
|
||||
|
||||
private static native void nGlobalInit();
|
||||
private static native void nConstrainMaterial(MaterialKey materialKey, int[] uvmap);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -79,9 +99,10 @@ public interface MaterialProvider {
|
||||
* @param uvmap Output argument that gets populated with a small table that maps from a glTF uv
|
||||
* index to a Filament uv index (0 = UNUSED, 1 = UV0, 2 = UV1).
|
||||
* @param label Optional tag that is not a part of the cache key.
|
||||
* @param extras Optional extras as stringified JSON (not a part of the cache key).
|
||||
*/
|
||||
public @Nullable MaterialInstance createMaterialInstance(MaterialKey config,
|
||||
@NonNull @Size(min = 8) int[] uvmap, @Nullable String label);
|
||||
@NonNull @Size(min = 8) int[] uvmap, @Nullable String label, @Nullable String extras);
|
||||
|
||||
/**
|
||||
* Creates and returns an array containing all cached materials.
|
||||
@@ -106,4 +127,10 @@ public interface MaterialProvider {
|
||||
* clients to take ownership of the cache if desired.
|
||||
*/
|
||||
public void destroyMaterials();
|
||||
|
||||
/**
|
||||
* Frees memory consumed by the native <code>MaterialProvider</code>, but does not destroy
|
||||
* cached materials.
|
||||
*/
|
||||
public void destroy();
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ public class ResourceLoader {
|
||||
*/
|
||||
public ResourceLoader(@NonNull Engine engine) {
|
||||
long nativeEngine = engine.getNativeObject();
|
||||
mNativeObject = nCreateResourceLoader(nativeEngine, false, false);
|
||||
mNativeObject = nCreateResourceLoader(nativeEngine, false, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,14 +54,15 @@ public class ResourceLoader {
|
||||
* @param engine the engine that gets passed to all builder methods
|
||||
* @param normalizeSkinningWeights scale non-conformant skinning weights so they sum to 1
|
||||
* @param recomputeBoundingBoxes use computed bounding boxes rather than the ones in the asset
|
||||
* @param ignoreBindTransform ignore skinned primitives bind transform when compute bounding boxes
|
||||
* @throws IllegalAccessException
|
||||
* @throws InvocationTargetException
|
||||
*/
|
||||
public ResourceLoader(@NonNull Engine engine, boolean normalizeSkinningWeights,
|
||||
boolean recomputeBoundingBoxes) {
|
||||
boolean recomputeBoundingBoxes, boolean ignoreBindTransform) {
|
||||
long nativeEngine = engine.getNativeObject();
|
||||
mNativeObject = nCreateResourceLoader(nativeEngine, normalizeSkinningWeights,
|
||||
recomputeBoundingBoxes);
|
||||
recomputeBoundingBoxes, ignoreBindTransform);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -166,7 +167,7 @@ public class ResourceLoader {
|
||||
}
|
||||
|
||||
private static native long nCreateResourceLoader(long nativeEngine,
|
||||
boolean normalizeSkinningWeights, boolean recomputeBoundingBoxes);
|
||||
boolean normalizeSkinningWeights, boolean recomputeBoundingBoxes, boolean ignoreBindTransform);
|
||||
private static native void nDestroyResourceLoader(long nativeLoader);
|
||||
private static native void nAddResourceData(long nativeLoader, String url, Buffer buffer,
|
||||
int remaining);
|
||||
|
||||
@@ -32,6 +32,9 @@ import androidx.annotation.Size;
|
||||
* Client applications do not need to call methods on it.</p>
|
||||
*/
|
||||
public class UbershaderLoader implements MaterialProvider {
|
||||
private static final VertexBuffer.VertexAttribute[] sVertexAttributesValues =
|
||||
VertexBuffer.VertexAttribute.values();
|
||||
|
||||
private long mNativeObject;
|
||||
|
||||
/**
|
||||
@@ -53,7 +56,7 @@ public class UbershaderLoader implements MaterialProvider {
|
||||
}
|
||||
|
||||
public @Nullable MaterialInstance createMaterialInstance(MaterialKey config,
|
||||
@NonNull @Size(min = 8) int[] uvmap, @Nullable String label) {
|
||||
@NonNull @Size(min = 8) int[] uvmap, @Nullable String label, @Nullable String extras) {
|
||||
long nativeMaterialInstance = nCreateMaterialInstance(mNativeObject, config, uvmap, label);
|
||||
return nativeMaterialInstance == 0 ? null : new MaterialInstance(null, nativeMaterialInstance);
|
||||
}
|
||||
@@ -70,7 +73,7 @@ public class UbershaderLoader implements MaterialProvider {
|
||||
}
|
||||
|
||||
public boolean needsDummyData(int attrib) {
|
||||
VertexBuffer.VertexAttribute vattrib = VertexBuffer.VertexAttribute.values()[attrib];
|
||||
VertexBuffer.VertexAttribute vattrib = sVertexAttributesValues[attrib];
|
||||
switch (vattrib) {
|
||||
case UV0:
|
||||
case UV1:
|
||||
@@ -92,7 +95,8 @@ public class UbershaderLoader implements MaterialProvider {
|
||||
private static native long nCreateUbershaderLoader(long nativeEngine);
|
||||
private static native void nDestroyUbershaderLoader(long nativeProvider);
|
||||
private static native void nDestroyMaterials(long nativeProvider);
|
||||
private static native long nCreateMaterialInstance(long nativeProvider, MaterialKey config, int[] uvmap, String label);
|
||||
private static native long nCreateMaterialInstance(long nativeProvider,
|
||||
MaterialKey config, int[] uvmap, String label);
|
||||
private static native int nGetMaterialCount(long nativeProvider);
|
||||
private static native void nGetMaterials(long nativeProvider, long[] result);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
GROUP=com.google.android.filament
|
||||
VERSION_NAME=1.11.1
|
||||
VERSION_NAME=1.20.4
|
||||
|
||||
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
|
||||
|
||||
@@ -18,3 +18,11 @@ POM_DEVELOPER_NAME=Filament Team
|
||||
org.gradle.jvmargs=-Xmx1536m
|
||||
|
||||
android.useAndroidX=true
|
||||
|
||||
org.gradle.unsafe.configuration-cache=true
|
||||
# TODO: Remove this when we switch to Gradle 7.4
|
||||
org.gradle.unsafe.configuration-cache.max-problems=3
|
||||
|
||||
com.google.android.filament.tools-dir=../../../out/release/filament
|
||||
com.google.android.filament.dist-dir=../out/android-release/filament
|
||||
com.google.android.filament.abis=all
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#Wed Nov 17 10:40:18 PST 2021
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: FilamentToolsPlugin
|
||||
plugins {
|
||||
id 'com.android.application'
|
||||
id 'kotlin-android'
|
||||
id 'filament-tools-plugin'
|
||||
}
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
@@ -10,6 +12,7 @@ filamentTools {
|
||||
iblOutputDir = project.layout.projectDirectory.dir("src/main/assets/envs")
|
||||
}
|
||||
|
||||
// don't forget to update MainACtivity.kt when/if changing this.
|
||||
task copyMesh(type: Copy) {
|
||||
from "../../../third_party/models/BusterDrone"
|
||||
into "src/main/assets/models"
|
||||
@@ -29,12 +32,17 @@ android {
|
||||
targetSdkVersion versions.targetSdk
|
||||
missingDimensionStrategy 'functionality', 'full'
|
||||
}
|
||||
// NOTE: This is a workaround required because the AGP task collectReleaseDependencies
|
||||
// is not configuration-cache friendly yet; this is only useful for Play publication
|
||||
dependenciesInfo {
|
||||
includeInApk = false
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation deps.kotlin
|
||||
implementation deps.coroutines.core
|
||||
implementation project(':filament-android')
|
||||
implementation project(':gltfio-android')
|
||||
implementation project(':filament-utils-android')
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.8'
|
||||
}
|
||||
|
||||
@@ -12,7 +12,9 @@
|
||||
android:supportsRtl="true"
|
||||
android:largeHeap="true"
|
||||
android:theme="@android:style/Theme.NoTitleBar">
|
||||
<activity android:name="com.google.android.filament.gltf.MainActivity"
|
||||
<activity
|
||||
android:exported="true"
|
||||
android:name="com.google.android.filament.gltf.MainActivity"
|
||||
android:screenOrientation="fullSensor"
|
||||
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden">
|
||||
<intent-filter>
|
||||
|
||||
@@ -27,6 +27,7 @@ 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.View
|
||||
import com.google.android.filament.utils.*
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -35,6 +36,7 @@ import kotlinx.coroutines.withContext
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.RandomAccessFile
|
||||
import java.net.URI
|
||||
import java.nio.Buffer
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.charset.StandardCharsets
|
||||
@@ -95,14 +97,36 @@ class MainActivity : Activity() {
|
||||
setStatusText("To load a new model, go to the above URL on your host machine.")
|
||||
|
||||
val view = modelViewer.view
|
||||
|
||||
/*
|
||||
* Note: The settings below are overriden when connecting to the remote UI.
|
||||
*/
|
||||
|
||||
// on mobile, better use lower quality color buffer
|
||||
view.renderQuality = view.renderQuality.apply {
|
||||
hdrColorBuffer = View.QualityLevel.MEDIUM
|
||||
}
|
||||
|
||||
// dynamic resolution often helps a lot
|
||||
view.dynamicResolutionOptions = view.dynamicResolutionOptions.apply {
|
||||
enabled = true
|
||||
quality = View.QualityLevel.MEDIUM
|
||||
}
|
||||
|
||||
// MSAA is needed with dynamic resolution MEDIUM
|
||||
view.multiSampleAntiAliasingOptions = view.multiSampleAntiAliasingOptions.apply {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
// FXAA is pretty cheap and helps a lot
|
||||
view.antiAliasing = View.AntiAliasing.FXAA
|
||||
|
||||
// ambient occlusion is the cheapest effect that adds a lot of quality
|
||||
view.ambientOcclusionOptions = view.ambientOcclusionOptions.apply {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
// bloom is pretty expensive but adds a fair amount of realism
|
||||
view.bloomOptions = view.bloomOptions.apply {
|
||||
enabled = true
|
||||
}
|
||||
@@ -194,8 +218,17 @@ class MainActivity : Activity() {
|
||||
|
||||
val sky = Skybox.Builder().environment(skyboxTexture).build(engine)
|
||||
|
||||
specularFilter.destroy()
|
||||
equirectToCubemap.destroy()
|
||||
context.destroy()
|
||||
|
||||
// destroy the previous IBl
|
||||
engine.destroyIndirectLight(modelViewer.scene.indirectLight!!)
|
||||
engine.destroySkybox(modelViewer.scene.skybox!!)
|
||||
|
||||
modelViewer.scene.skybox = sky
|
||||
modelViewer.scene.indirectLight = ibl
|
||||
viewerContent.indirectLight = ibl
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -211,7 +244,7 @@ class MainActivity : Activity() {
|
||||
val (zipStream, zipFile) = withContext(Dispatchers.IO) {
|
||||
val file = File.createTempFile("incoming", "zip", cacheDir)
|
||||
val raf = RandomAccessFile(file, "rw")
|
||||
raf.getChannel().write(message.buffer);
|
||||
raf.channel.write(message.buffer)
|
||||
message.buffer = null
|
||||
raf.seek(0)
|
||||
Pair(FileInputStream(file), file)
|
||||
@@ -266,19 +299,16 @@ class MainActivity : Activity() {
|
||||
|
||||
// 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 += "/"
|
||||
}
|
||||
var prefix = URI(gltfPath!!).resolve("..")
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
if (gltfPath!!.endsWith(".glb")) {
|
||||
modelViewer.loadModelGlb(gltfBuffer)
|
||||
} else {
|
||||
modelViewer.loadModelGltf(gltfBuffer) { uri ->
|
||||
val path = gltfPrefix + uri
|
||||
val path = prefix.resolve(uri).toString()
|
||||
if (!pathToBufferMapping.contains(path)) {
|
||||
Log.e(TAG, "Could not find $path in the zip.")
|
||||
Log.e(TAG, "Could not find '$uri' in zip using prefix '$prefix'")
|
||||
setStatusText("Zip is missing $path")
|
||||
}
|
||||
pathToBufferMapping[path]
|
||||
@@ -311,12 +341,10 @@ class MainActivity : Activity() {
|
||||
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)
|
||||
when {
|
||||
message.label.endsWith(".zip") -> loadZip(message)
|
||||
message.label.endsWith(".hdr") -> loadHdr(message)
|
||||
else -> loadGlb(message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: FilamentToolsPlugin
|
||||
plugins {
|
||||
id 'com.android.application'
|
||||
id 'kotlin-android'
|
||||
id 'filament-tools-plugin'
|
||||
}
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
@@ -17,10 +19,16 @@ android {
|
||||
compileSdkVersion versions.compileSdk
|
||||
defaultConfig {
|
||||
applicationId "com.google.android.filament.hellocamera"
|
||||
minSdkVersion versions.minSdk
|
||||
minSdkVersion 23
|
||||
targetSdkVersion versions.targetSdk
|
||||
}
|
||||
|
||||
// NOTE: This is a workaround required because the AGP task collectReleaseDependencies
|
||||
// is not configuration-cache friendly yet; this is only useful for Play publication
|
||||
dependenciesInfo {
|
||||
includeInApk = false
|
||||
}
|
||||
|
||||
// We use the .filamat extension for materials compiled with matc
|
||||
// Telling aapt to not compress them allows to load them efficiently
|
||||
aaptOptions {
|
||||
|
||||
@@ -31,7 +31,9 @@
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity android:name=".MainActivity">
|
||||
<activity
|
||||
android:exported="true"
|
||||
android:name=".MainActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
|
||||
|
||||
@@ -33,7 +33,9 @@ import android.graphics.ImageFormat
|
||||
import android.hardware.HardwareBuffer
|
||||
import android.media.ImageReader
|
||||
import android.opengl.Matrix
|
||||
import android.view.Display
|
||||
import android.os.Build
|
||||
import android.os.Looper
|
||||
import androidx.annotation.RequiresApi
|
||||
|
||||
import com.google.android.filament.*
|
||||
|
||||
@@ -44,7 +46,7 @@ import java.util.concurrent.TimeUnit
|
||||
* Toy class that handles all interaction with the Android camera2 API.
|
||||
* Sets the "textureTransform" and "videoTexture" parameters on the given Filament material.
|
||||
*/
|
||||
class CameraHelper(val activity: Activity, private val filamentEngine: Engine, private val filamentMaterial: MaterialInstance, private val display: Display) {
|
||||
class CameraHelper(val activity: Activity, private val filamentEngine: Engine, private val filamentMaterial: MaterialInstance) {
|
||||
private lateinit var cameraId: String
|
||||
private lateinit var captureRequest: CaptureRequest
|
||||
|
||||
@@ -63,6 +65,20 @@ class CameraHelper(val activity: Activity, private val filamentEngine: Engine, p
|
||||
kImageReaderMaxImages,
|
||||
HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE)
|
||||
|
||||
@Suppress("deprecation")
|
||||
private val display = if (Build.VERSION.SDK_INT >= 30) {
|
||||
Api30Impl.getDisplay(activity)
|
||||
} else {
|
||||
activity.windowManager.defaultDisplay!!
|
||||
}
|
||||
|
||||
@RequiresApi(30)
|
||||
class Api30Impl {
|
||||
companion object {
|
||||
fun getDisplay(context: Context) = context.display!!
|
||||
}
|
||||
}
|
||||
|
||||
private val cameraCallback = object : CameraDevice.StateCallback() {
|
||||
override fun onOpened(cameraDevice: CameraDevice) {
|
||||
cameraOpenCloseLock.release()
|
||||
@@ -87,7 +103,9 @@ class CameraHelper(val activity: Activity, private val filamentEngine: Engine, p
|
||||
val stream = filamentStream
|
||||
if (stream != null) {
|
||||
imageReader.acquireLatestImage()?.also {
|
||||
stream.setAcquiredImage(it.hardwareBuffer, Handler()) { it.close() }
|
||||
stream.setAcquiredImage(it.hardwareBuffer, Handler(Looper.getMainLooper())) {
|
||||
it.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
|
||||
setupView()
|
||||
setupScene()
|
||||
|
||||
cameraHelper = CameraHelper(this, engine, materialInstance, windowManager.defaultDisplay)
|
||||
cameraHelper = CameraHelper(this, engine, materialInstance)
|
||||
cameraHelper.openCamera()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: FilamentToolsPlugin
|
||||
plugins {
|
||||
id 'com.android.application'
|
||||
id 'kotlin-android'
|
||||
id 'filament-tools-plugin'
|
||||
}
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
@@ -21,6 +23,12 @@ android {
|
||||
targetSdkVersion versions.targetSdk
|
||||
}
|
||||
|
||||
// NOTE: This is a workaround required because the AGP task collectReleaseDependencies
|
||||
// is not configuration-cache friendly yet; this is only useful for Play publication
|
||||
dependenciesInfo {
|
||||
includeInApk = false
|
||||
}
|
||||
|
||||
// We use the .filamat extension for materials compiled with matc
|
||||
// Telling aapt to not compress them allows to load them efficiently
|
||||
aaptOptions {
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity android:name=".MainActivity">
|
||||
<activity
|
||||
android:exported="true"
|
||||
android:name=".MainActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: FilamentToolsPlugin
|
||||
plugins {
|
||||
id 'com.android.application'
|
||||
id 'kotlin-android'
|
||||
id 'filament-tools-plugin'
|
||||
}
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
@@ -27,6 +29,12 @@ android {
|
||||
targetSdkVersion versions.targetSdk
|
||||
}
|
||||
|
||||
// NOTE: This is a workaround required because the AGP task collectReleaseDependencies
|
||||
// is not configuration-cache friendly yet; this is only useful for Play publication
|
||||
dependenciesInfo {
|
||||
includeInApk = false
|
||||
}
|
||||
|
||||
// We use the .filamat extension for materials compiled with matc
|
||||
// Telling aapt to not compress them allows to load them efficiently
|
||||
aaptOptions {
|
||||
|
||||
@@ -11,7 +11,9 @@
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity android:name=".MainActivity">
|
||||
<activity
|
||||
android:exported="true"
|
||||
android:name=".MainActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: FilamentToolsPlugin
|
||||
plugins {
|
||||
id 'com.android.application'
|
||||
id 'kotlin-android'
|
||||
id 'filament-tools-plugin'
|
||||
}
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
@@ -20,6 +22,12 @@ android {
|
||||
targetSdkVersion versions.targetSdk
|
||||
}
|
||||
|
||||
// NOTE: This is a workaround required because the AGP task collectReleaseDependencies
|
||||
// is not configuration-cache friendly yet; this is only useful for Play publication
|
||||
dependenciesInfo {
|
||||
includeInApk = false
|
||||
}
|
||||
|
||||
// We use the .filamat extension for materials compiled with matc
|
||||
// Telling aapt to not compress them allows to load them efficiently
|
||||
aaptOptions {
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity android:name=".MainActivity">
|
||||
<activity
|
||||
android:exported="true"
|
||||
android:name=".MainActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
|
||||
|
||||
@@ -10,9 +10,16 @@ android {
|
||||
minSdkVersion versions.minSdk
|
||||
targetSdkVersion versions.targetSdk
|
||||
}
|
||||
|
||||
// NOTE: This is a workaround required because the AGP task collectReleaseDependencies
|
||||
// is not configuration-cache friendly yet; this is only useful for Play publication
|
||||
dependenciesInfo {
|
||||
includeInApk = false
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation deps.kotlin
|
||||
implementation deps.androidx.annotations
|
||||
implementation project(':filament-android')
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
<service
|
||||
android:exported="true"
|
||||
android:name=".FilamentLiveWallpaper"
|
||||
android:label="@string/wallpaper_label"
|
||||
android:permission="android.permission.BIND_WALLPAPER">
|
||||
|
||||
@@ -18,19 +18,21 @@ package com.google.android.filament.livewallpaper
|
||||
|
||||
import android.animation.ValueAnimator
|
||||
import android.app.Service
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.graphics.PixelFormat
|
||||
import android.os.Build
|
||||
import android.service.wallpaper.WallpaperService
|
||||
import android.view.Choreographer
|
||||
import android.view.Surface
|
||||
import android.view.SurfaceHolder
|
||||
import android.view.WindowManager
|
||||
import android.view.animation.LinearInterpolator
|
||||
import androidx.annotation.RequiresApi
|
||||
import com.google.android.filament.*
|
||||
import com.google.android.filament.android.DisplayHelper
|
||||
import com.google.android.filament.android.UiHelper
|
||||
|
||||
|
||||
class FilamentLiveWallpaper : WallpaperService() {
|
||||
// Make sure to initialize Filament first
|
||||
// This loads the JNI library needed by most API calls
|
||||
@@ -196,9 +198,14 @@ class FilamentLiveWallpaper : WallpaperService() {
|
||||
override fun onNativeWindowChanged(surface: Surface) {
|
||||
swapChain?.let { engine.destroySwapChain(it) }
|
||||
swapChain = engine.createSwapChain(surface)
|
||||
val display =
|
||||
(application.getSystemService(Service.WINDOW_SERVICE) as WindowManager)
|
||||
.defaultDisplay
|
||||
|
||||
@Suppress("deprecation")
|
||||
val display = if (Build.VERSION.SDK_INT >= 30) {
|
||||
Api30Impl.getDisplay(displayContext!!)
|
||||
} else {
|
||||
(getSystemService(Service.WINDOW_SERVICE) as WindowManager).defaultDisplay
|
||||
}
|
||||
|
||||
displayHelper.attach(renderer, display)
|
||||
}
|
||||
|
||||
@@ -222,4 +229,11 @@ class FilamentLiveWallpaper : WallpaperService() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(30)
|
||||
class Api30Impl {
|
||||
companion object {
|
||||
fun getDisplay(context: Context) = context.display!!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: FilamentToolsPlugin
|
||||
plugins {
|
||||
id 'com.android.application'
|
||||
id 'kotlin-android'
|
||||
id 'filament-tools-plugin'
|
||||
}
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
@@ -31,6 +33,12 @@ android {
|
||||
missingDimensionStrategy 'functionality', 'full'
|
||||
}
|
||||
|
||||
// NOTE: This is a workaround required because the AGP task collectReleaseDependencies
|
||||
// is not configuration-cache friendly yet; this is only useful for Play publication
|
||||
dependenciesInfo {
|
||||
includeInApk = false
|
||||
}
|
||||
|
||||
// We use the .filamat extension for materials compiled with matc
|
||||
// Telling aapt to not compress them allows to load them efficiently
|
||||
aaptOptions {
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity android:name=".MainActivity">
|
||||
<activity
|
||||
android:exported="true"
|
||||
android:name=".MainActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: FilamentToolsPlugin
|
||||
plugins {
|
||||
id 'com.android.application'
|
||||
id 'kotlin-android'
|
||||
id 'filament-tools-plugin'
|
||||
}
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
@@ -20,6 +22,12 @@ android {
|
||||
targetSdkVersion versions.targetSdk
|
||||
}
|
||||
|
||||
// NOTE: This is a workaround required because the AGP task collectReleaseDependencies
|
||||
// is not configuration-cache friendly yet; this is only useful for Play publication
|
||||
dependenciesInfo {
|
||||
includeInApk = false
|
||||
}
|
||||
|
||||
// We use the .filamat extension for materials compiled with matc
|
||||
// Telling aapt to not compress them allows to load them efficiently
|
||||
aaptOptions {
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity android:name=".MainActivity">
|
||||
<activity
|
||||
android:exported="true"
|
||||
android:name=".MainActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user