Compare commits
757 Commits
bjd/fix-we
...
v1.50.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f3a61f100c | ||
|
|
60db518b75 | ||
|
|
3c5316f1e9 | ||
|
|
1f33a6efd2 | ||
|
|
4127f619e1 | ||
|
|
13a23703ad | ||
|
|
57f6ca625c | ||
|
|
02f5903b67 | ||
|
|
c39a870abc | ||
|
|
09b8008e17 | ||
|
|
59b59cf6be | ||
|
|
0df6013263 | ||
|
|
d5041fced7 | ||
|
|
9c54b8a777 | ||
|
|
8a534d0940 | ||
|
|
130825422e | ||
|
|
984006ee25 | ||
|
|
b3cc4d11b8 | ||
|
|
8523f4e970 | ||
|
|
b676002521 | ||
|
|
6b7450dc0b | ||
|
|
8bdf7bd1e5 | ||
|
|
7b384fb5e8 | ||
|
|
1262cb286c | ||
|
|
20dc6d479b | ||
|
|
ee6f3fb1dc | ||
|
|
b9a9586abb | ||
|
|
6ee20a57aa | ||
|
|
368fa2bf39 | ||
|
|
8f642892b4 | ||
|
|
0736f3c3b3 | ||
|
|
5435a8ed3b | ||
|
|
5fd7a4e153 | ||
|
|
20ff230b92 | ||
|
|
44ff79ad34 | ||
|
|
102d2db008 | ||
|
|
6a7767f4e4 | ||
|
|
5c9039e650 | ||
|
|
1203c24f06 | ||
|
|
9704d27aeb | ||
|
|
c6f2c3fc1c | ||
|
|
2faf868341 | ||
|
|
628d387cbd | ||
|
|
81f6260843 | ||
|
|
75a1c6d7a8 | ||
|
|
1a9063d53a | ||
|
|
8c76370e2d | ||
|
|
6062b3c8c6 | ||
|
|
d9186c44ba | ||
|
|
bdc15a5c2d | ||
|
|
acfe9298d9 | ||
|
|
6d06e00934 | ||
|
|
b4021a1fbc | ||
|
|
2c9559f9b8 | ||
|
|
57f6e5371b | ||
|
|
e2da13f817 | ||
|
|
addae314b4 | ||
|
|
5e3c51822d | ||
|
|
9d817a0cc9 | ||
|
|
9fa3cbfcde | ||
|
|
c81ece5c3c | ||
|
|
95ecc3d1e4 | ||
|
|
cabaa4323e | ||
|
|
d6b2ec49b0 | ||
|
|
93004aa5bc | ||
|
|
27fa8ab46d | ||
|
|
aae48c1121 | ||
|
|
918ce935b8 | ||
|
|
614990f413 | ||
|
|
6f37e07dba | ||
|
|
171b3279e0 | ||
|
|
da058028fd | ||
|
|
55c75453df | ||
|
|
f5eff10532 | ||
|
|
56a0364534 | ||
|
|
c8aae3cdaa | ||
|
|
4f94c575c9 | ||
|
|
1a29f020c9 | ||
|
|
d5847a3c6a | ||
|
|
3dbae482d3 | ||
|
|
27572e3be6 | ||
|
|
dedf276e26 | ||
|
|
111ad96134 | ||
|
|
2a67152dda | ||
|
|
2f62978e4c | ||
|
|
fdb90f2f49 | ||
|
|
b3a1cfe7c9 | ||
|
|
d273838e07 | ||
|
|
5418b8c4cc | ||
|
|
724cab3623 | ||
|
|
a1de8c924d | ||
|
|
d9faea264a | ||
|
|
72765a5b0a | ||
|
|
e1beabaa98 | ||
|
|
ebaee14b8b | ||
|
|
d4f08dafbb | ||
|
|
753fb102c4 | ||
|
|
b219113a55 | ||
|
|
6116c2f9eb | ||
|
|
95fdba0c5d | ||
|
|
9c56517370 | ||
|
|
08f06f4298 | ||
|
|
b1794a82ca | ||
|
|
56bd2871ec | ||
|
|
5a9c47bcb5 | ||
|
|
51c2fa2728 | ||
|
|
334c71de52 | ||
|
|
001098098b | ||
|
|
9140d44b29 | ||
|
|
8b0d65768a | ||
|
|
35a00b1d84 | ||
|
|
b517a45213 | ||
|
|
f8057b9a5b | ||
|
|
d9ee526a72 | ||
|
|
349bf7be38 | ||
|
|
164d7507bb | ||
|
|
a01d282f14 | ||
|
|
b007e9137e | ||
|
|
06bae26e1b | ||
|
|
1be3e13427 | ||
|
|
e7c67d1adb | ||
|
|
9b67d80961 | ||
|
|
b066678a37 | ||
|
|
b10d5c58aa | ||
|
|
3c3296a114 | ||
|
|
61501ba122 | ||
|
|
000bff5ce1 | ||
|
|
99ba40e965 | ||
|
|
47d45a64fa | ||
|
|
4116af7971 | ||
|
|
2fab93faff | ||
|
|
b92c5cab07 | ||
|
|
8ed9678cbe | ||
|
|
731e52a3c1 | ||
|
|
687b6da800 | ||
|
|
2bd48f58ff | ||
|
|
f2f4f556b5 | ||
|
|
5aa15f061b | ||
|
|
63db4f0bf0 | ||
|
|
7797f5af38 | ||
|
|
f9def09d17 | ||
|
|
494934f34e | ||
|
|
caae42fdf6 | ||
|
|
8f6c4841cb | ||
|
|
64f4c097ac | ||
|
|
5d0c06e3f2 | ||
|
|
7d31a7f7ea | ||
|
|
0191e1fe46 | ||
|
|
21093067db | ||
|
|
4f4a439f8b | ||
|
|
1b10e7d4f3 | ||
|
|
2306b56ea7 | ||
|
|
5b2d3ac225 | ||
|
|
422dfcc1e6 | ||
|
|
eebb40d30d | ||
|
|
0d304393f4 | ||
|
|
766e4f2ec9 | ||
|
|
b0a584c915 | ||
|
|
57aa99e964 | ||
|
|
cfc133fcf1 | ||
|
|
8eade6be1f | ||
|
|
d5bab43ceb | ||
|
|
485ae1b324 | ||
|
|
2250664e58 | ||
|
|
75e8961109 | ||
|
|
0e9b2eda0a | ||
|
|
a900bc69fb | ||
|
|
edbfefda0a | ||
|
|
1a0b5ddc14 | ||
|
|
e8bed52b3f | ||
|
|
06e8b1d689 | ||
|
|
8a27cc8b7f | ||
|
|
d786d59ea1 | ||
|
|
9c351b28ab | ||
|
|
cbc3bb3326 | ||
|
|
79116905aa | ||
|
|
763950ec18 | ||
|
|
0eb851ff8c | ||
|
|
038f07cb34 | ||
|
|
62adb234d1 | ||
|
|
53d8d2a41f | ||
|
|
974a69a273 | ||
|
|
7d694ee85e | ||
|
|
46e6664c3d | ||
|
|
4fd7c418e5 | ||
|
|
a3fdca7997 | ||
|
|
7f1704481e | ||
|
|
e6b962b038 | ||
|
|
668fb07ac2 | ||
|
|
f64eef02a3 | ||
|
|
239e98ccec | ||
|
|
919cfae6b2 | ||
|
|
0b9389430b | ||
|
|
1d157677d1 | ||
|
|
ef3f0cb326 | ||
|
|
fcf53f2c3e | ||
|
|
13571868de | ||
|
|
0f2c89b140 | ||
|
|
f8b70e8ec5 | ||
|
|
7abdea5a2e | ||
|
|
d6fda03b06 | ||
|
|
a76addd2bf | ||
|
|
b1f7731dbe | ||
|
|
e3e12dbf73 | ||
|
|
31a75029f0 | ||
|
|
e5c24cc718 | ||
|
|
2b86c8df6f | ||
|
|
4d8e6eefa1 | ||
|
|
8aeec2ba35 | ||
|
|
4eb4fd5aba | ||
|
|
56355231bd | ||
|
|
9ccb8fce31 | ||
|
|
e674420e9c | ||
|
|
8a9cbcfb99 | ||
|
|
f0d5cd3fa1 | ||
|
|
cb3e808e8d | ||
|
|
b2e0b97bad | ||
|
|
73b0751ccf | ||
|
|
cc95a4a7a3 | ||
|
|
d76cf643c5 | ||
|
|
6e249c4c1b | ||
|
|
9c0cbed214 | ||
|
|
c531a9c077 | ||
|
|
af0c6a7fe9 | ||
|
|
7b7dfad552 | ||
|
|
deb3eb0b11 | ||
|
|
d3016adaff | ||
|
|
6c29542fad | ||
|
|
0d2a96d630 | ||
|
|
d3fe46765f | ||
|
|
892f94e3c4 | ||
|
|
f75f7039f4 | ||
|
|
8303d6b28e | ||
|
|
0f9a2dd6af | ||
|
|
626621fb1c | ||
|
|
2a1f762e23 | ||
|
|
2b78fd8359 | ||
|
|
4dd98e63e4 | ||
|
|
9d181a172a | ||
|
|
d4b9d1e023 | ||
|
|
1b7187f427 | ||
|
|
b62991d967 | ||
|
|
562ea65d5c | ||
|
|
6498cf5b64 | ||
|
|
3c77d2c3f5 | ||
|
|
960c6170fe | ||
|
|
37c2fe31d5 | ||
|
|
21b51caf3d | ||
|
|
0dddd94eab | ||
|
|
76dbc08176 | ||
|
|
1b0db0fca2 | ||
|
|
163f02035f | ||
|
|
14263efbea | ||
|
|
7c6103a458 | ||
|
|
92846305f5 | ||
|
|
2ef0244266 | ||
|
|
d5ebca0c49 | ||
|
|
38ceee8d75 | ||
|
|
fc6744ba75 | ||
|
|
0774bf9501 | ||
|
|
8f5b2fd230 | ||
|
|
078a17469a | ||
|
|
0887e388db | ||
|
|
e4a57cedf9 | ||
|
|
d92bdce852 | ||
|
|
76bf906856 | ||
|
|
b5e23162df | ||
|
|
eeb53606c8 | ||
|
|
dd23f271e3 | ||
|
|
e78a06797c | ||
|
|
6279613b79 | ||
|
|
78d433cafa | ||
|
|
6590f62052 | ||
|
|
f1f7aeb14f | ||
|
|
5190b03f89 | ||
|
|
2cd492ed38 | ||
|
|
07975868fe | ||
|
|
5ab526cbb0 | ||
|
|
df935b75e5 | ||
|
|
b4d6f975c1 | ||
|
|
2cf86454bb | ||
|
|
5572097fb3 | ||
|
|
274191036f | ||
|
|
13afbc2876 | ||
|
|
480cfb2820 | ||
|
|
39d555d115 | ||
|
|
df50f4c25d | ||
|
|
a7bb0a60fb | ||
|
|
976f304ee7 | ||
|
|
21ea99a1d9 | ||
|
|
f0b0505207 | ||
|
|
11997d007a | ||
|
|
0650b13358 | ||
|
|
6cd851e77e | ||
|
|
c0327c95d4 | ||
|
|
e1dfea0f12 | ||
|
|
b2cef9bfee | ||
|
|
f6b979c8e4 | ||
|
|
87a8cb3872 | ||
|
|
a4869eaf19 | ||
|
|
2e9dd03222 | ||
|
|
9a6b8bf24e | ||
|
|
3aee9402d5 | ||
|
|
fcf5866fc3 | ||
|
|
864a854c13 | ||
|
|
5a18cdf0f6 | ||
|
|
6ebd22f474 | ||
|
|
9f5c1bb0dc | ||
|
|
1740220f6a | ||
|
|
9cbf741ac2 | ||
|
|
04c8845284 | ||
|
|
d82b7a529c | ||
|
|
72c60b35d7 | ||
|
|
5d30435620 | ||
|
|
d02231dce9 | ||
|
|
ea70fe540f | ||
|
|
cb9bfaeb83 | ||
|
|
3dcdb202d1 | ||
|
|
da73f89a23 | ||
|
|
9474798c75 | ||
|
|
13df6652ae | ||
|
|
4f925f07e8 | ||
|
|
5deccffdce | ||
|
|
a76eacba67 | ||
|
|
8f64756721 | ||
|
|
ee31ca6fc0 | ||
|
|
9f62dc2f2f | ||
|
|
7dd6686087 | ||
|
|
9c0fb67b87 | ||
|
|
0b97de425f | ||
|
|
373c5710b1 | ||
|
|
fdffd93949 | ||
|
|
91b55bdea1 | ||
|
|
976b8c6ae4 | ||
|
|
f0a0a9b2e1 | ||
|
|
e743e9243f | ||
|
|
c80fbfdf17 | ||
|
|
d4d03e4a35 | ||
|
|
2114995489 | ||
|
|
ec30ddd2fb | ||
|
|
c35a60808c | ||
|
|
58017a0e6a | ||
|
|
d9c2893976 | ||
|
|
1ff0a2dd6d | ||
|
|
da96b45827 | ||
|
|
8e13d53b1e | ||
|
|
9ac4fa63ed | ||
|
|
ff274c8387 | ||
|
|
8d621561f3 | ||
|
|
2c63a5ad7a | ||
|
|
d328b64dce | ||
|
|
3ab7780c38 | ||
|
|
6fd5d45295 | ||
|
|
e08e1c209b | ||
|
|
de310ed9ad | ||
|
|
4f11a02889 | ||
|
|
a57225cf2e | ||
|
|
dc818abadc | ||
|
|
c808d8f260 | ||
|
|
e0a37de1ba | ||
|
|
4e2a791e81 | ||
|
|
60627f836f | ||
|
|
22c9d350c1 | ||
|
|
d11a782c3e | ||
|
|
b4a45f126a | ||
|
|
35a8e73675 | ||
|
|
8d7743ce67 | ||
|
|
682585be4a | ||
|
|
9046d04de4 | ||
|
|
d01b29fa01 | ||
|
|
8cba3d4366 | ||
|
|
0f21c6c90b | ||
|
|
cc6a6454d7 | ||
|
|
609dc97c4a | ||
|
|
87351097ad | ||
|
|
be1e51ad91 | ||
|
|
29ce1cad84 | ||
|
|
6a967ad007 | ||
|
|
694766682f | ||
|
|
c946ebd1e6 | ||
|
|
25a8291101 | ||
|
|
60c689688d | ||
|
|
763bc1f34a | ||
|
|
ef07638eef | ||
|
|
fe2bb3d9a4 | ||
|
|
cd7973bdcf | ||
|
|
0aa0efe159 | ||
|
|
ef7bcd1e19 | ||
|
|
702ceda82a | ||
|
|
66b78074de | ||
|
|
8d440cea17 | ||
|
|
3ab8e4d725 | ||
|
|
97f20afdd7 | ||
|
|
42989e76d7 | ||
|
|
e6384e0e92 | ||
|
|
ad45cc9092 | ||
|
|
04669f6ab9 | ||
|
|
c3c0dde82f | ||
|
|
e63dc17f54 | ||
|
|
af338cf2ec | ||
|
|
ecd5b681d0 | ||
|
|
66081e6cc1 | ||
|
|
aa6e94a128 | ||
|
|
098be2e115 | ||
|
|
17caf6cae9 | ||
|
|
26952631a3 | ||
|
|
fc7b6447b7 | ||
|
|
6c0db37919 | ||
|
|
69f78dbcbe | ||
|
|
c0389ac54c | ||
|
|
c0db909c13 | ||
|
|
46e4e966b9 | ||
|
|
288b59a348 | ||
|
|
1c7293db8d | ||
|
|
f1d8a04337 | ||
|
|
b13497e2a0 | ||
|
|
6006b47c44 | ||
|
|
6bb29f6e01 | ||
|
|
f1b160db04 | ||
|
|
3bb52f083b | ||
|
|
88337ab358 | ||
|
|
0935fe3fe3 | ||
|
|
96ed19549e | ||
|
|
945e9a2cb5 | ||
|
|
4d703e3807 | ||
|
|
f537f62adf | ||
|
|
7840404132 | ||
|
|
afad361cac | ||
|
|
58b23c290c | ||
|
|
12a73137d7 | ||
|
|
7a136eec5d | ||
|
|
e9bd9ab3a6 | ||
|
|
083bff62e3 | ||
|
|
f713316541 | ||
|
|
175c9f9966 | ||
|
|
1a50420b46 | ||
|
|
bcfdf2f70d | ||
|
|
018d6f877f | ||
|
|
1e4172b820 | ||
|
|
6b6827b70d | ||
|
|
bbad75a012 | ||
|
|
96cccc83c6 | ||
|
|
2468a3a854 | ||
|
|
f68825f2ed | ||
|
|
2a12f71f96 | ||
|
|
74b64a5451 | ||
|
|
7d01e0349b | ||
|
|
80014bf2b1 | ||
|
|
adf3421f4a | ||
|
|
51c65ccfdc | ||
|
|
25c08f19e3 | ||
|
|
5d37d08cf8 | ||
|
|
59063fb7b4 | ||
|
|
71f60de0ad | ||
|
|
eb18d75b2e | ||
|
|
743661109d | ||
|
|
549c582287 | ||
|
|
6c05029a9f | ||
|
|
b2278986dd | ||
|
|
98a2b8f159 | ||
|
|
0ba891fb14 | ||
|
|
042cd670aa | ||
|
|
95c7e4d02b | ||
|
|
d302525674 | ||
|
|
3dbb7298f8 | ||
|
|
0ed71ab53b | ||
|
|
b1491ae5b1 | ||
|
|
03b8dc8027 | ||
|
|
e3568cd89f | ||
|
|
b35e24daa7 | ||
|
|
f506b27a31 | ||
|
|
5014cbb023 | ||
|
|
4142e7a1cf | ||
|
|
9452d5be1d | ||
|
|
ea3f449a08 | ||
|
|
dc9510fe25 | ||
|
|
731dd761d9 | ||
|
|
6726ccb2fb | ||
|
|
5fce0f9ecf | ||
|
|
ad03fc4118 | ||
|
|
3f77ff8815 | ||
|
|
26b5fa1e38 | ||
|
|
24286e6016 | ||
|
|
626577fe3d | ||
|
|
176915b59c | ||
|
|
0b60933c2a | ||
|
|
0e31d6936a | ||
|
|
a721e648b7 | ||
|
|
358e89ef08 | ||
|
|
78d9c43ef1 | ||
|
|
ce253a9563 | ||
|
|
e023e90e7a | ||
|
|
a5b5b0c3a7 | ||
|
|
18c3c36727 | ||
|
|
4e6f6a4579 | ||
|
|
84487f4d8d | ||
|
|
45f5a07989 | ||
|
|
b7b4d3c295 | ||
|
|
0061883dbf | ||
|
|
47e3be11f0 | ||
|
|
420f4000c2 | ||
|
|
4582ce8769 | ||
|
|
3beb39f30b | ||
|
|
b72d6c058a | ||
|
|
a445c4e156 | ||
|
|
1432c59499 | ||
|
|
4c7c10fad0 | ||
|
|
0c8f367b29 | ||
|
|
50045edb4f | ||
|
|
f538d1aa43 | ||
|
|
7c8a0d1967 | ||
|
|
4bd8d2a3b7 | ||
|
|
9fa952d968 | ||
|
|
1edad92d73 | ||
|
|
11fbacea20 | ||
|
|
8cd70454c3 | ||
|
|
52282baeff | ||
|
|
1d988182fc | ||
|
|
dba49f00df | ||
|
|
85ab9d211d | ||
|
|
6e99a4dcfc | ||
|
|
89c0b44da9 | ||
|
|
4f450fd5c4 | ||
|
|
f0943cfca2 | ||
|
|
35c91827af | ||
|
|
5c11b237f3 | ||
|
|
432b5d0427 | ||
|
|
b8b1fadfa1 | ||
|
|
74f5d8a066 | ||
|
|
09aeeccfa7 | ||
|
|
9aa52b79d4 | ||
|
|
094abdc194 | ||
|
|
f4b97028b0 | ||
|
|
e14cbf2163 | ||
|
|
032cbab7b0 | ||
|
|
e306856c4f | ||
|
|
c1f164190b | ||
|
|
8030a078ff | ||
|
|
11adcbed25 | ||
|
|
c2b10859c9 | ||
|
|
a82125dbbd | ||
|
|
e0e2c76d2f | ||
|
|
24fcb299b5 | ||
|
|
753aa9ca61 | ||
|
|
b0238c1560 | ||
|
|
a33eada7ec | ||
|
|
5ffb52a17d | ||
|
|
6b34e72418 | ||
|
|
d43c632e55 | ||
|
|
d55dfdebde | ||
|
|
4b12876ebc | ||
|
|
3e12449b8f | ||
|
|
fdc3f302d9 | ||
|
|
07642fec83 | ||
|
|
676a2be874 | ||
|
|
4ce93232c3 | ||
|
|
ccea370cd9 | ||
|
|
8f6885689b | ||
|
|
64b15fafe2 | ||
|
|
c95d466cdd | ||
|
|
d891acb8c0 | ||
|
|
de0bc718be | ||
|
|
283a06e200 | ||
|
|
3cfb2f8339 | ||
|
|
3d8ac384ad | ||
|
|
21164885e8 | ||
|
|
0d745c4fea | ||
|
|
57424cc7e9 | ||
|
|
0e2f8b5dda | ||
|
|
321777e8c1 | ||
|
|
aa9f0a4ca3 | ||
|
|
bee8862897 | ||
|
|
fed69025d2 | ||
|
|
f953488a31 | ||
|
|
25708e8082 | ||
|
|
78fe4ba547 | ||
|
|
a8afa91b7d | ||
|
|
2806221eda | ||
|
|
a9763376b7 | ||
|
|
153dc08aa7 | ||
|
|
332b924325 | ||
|
|
b2ee4e93d4 | ||
|
|
fda62e0065 | ||
|
|
faafb1464c | ||
|
|
edfd06eaef | ||
|
|
1a83083651 | ||
|
|
5cb3b16f36 | ||
|
|
3aa6913538 | ||
|
|
2c6f723317 | ||
|
|
ddfeaef2ca | ||
|
|
a71baef5d3 | ||
|
|
e63ec23922 | ||
|
|
da17b6f867 | ||
|
|
002becdc4f | ||
|
|
2ade1778b1 | ||
|
|
f6c8ce1fd1 | ||
|
|
8aa1435fbd | ||
|
|
a3d25cd22b | ||
|
|
56bf841bac | ||
|
|
3e29b6e443 | ||
|
|
dfdf0db794 | ||
|
|
1a138aea1a | ||
|
|
d40712937d | ||
|
|
cfe1abec08 | ||
|
|
719ed28d7e | ||
|
|
aa1773d633 | ||
|
|
9b8b882818 | ||
|
|
17664d294e | ||
|
|
2ae4ee85e0 | ||
|
|
70bb08a93a | ||
|
|
88f6360321 | ||
|
|
f7538342df | ||
|
|
8e6d5d11b6 | ||
|
|
bf6bd4eca8 | ||
|
|
ac74f09dc8 | ||
|
|
36c69dda9c | ||
|
|
f14fdc11f5 | ||
|
|
0157487b1f | ||
|
|
1716c856c3 | ||
|
|
f47265e9c5 | ||
|
|
9243887a3a | ||
|
|
4efac2c0fa | ||
|
|
f3e1d5592a | ||
|
|
c67d9ce09b | ||
|
|
27ee90a56d | ||
|
|
41ccbdbf17 | ||
|
|
17fc3c23ed | ||
|
|
fdb0798f28 | ||
|
|
b4d842c342 | ||
|
|
7cddd832aa | ||
|
|
6a10753267 | ||
|
|
38dba5394e | ||
|
|
108cdd4242 | ||
|
|
228aa6c631 | ||
|
|
8936b3aa66 | ||
|
|
31521c70c2 | ||
|
|
6558448eae | ||
|
|
88be599c2e | ||
|
|
cf1bbf63fc | ||
|
|
8cac90d81e | ||
|
|
388b4f5efb | ||
|
|
f9b5a7f301 | ||
|
|
4e888d142b | ||
|
|
00c78cc225 | ||
|
|
2bdb8b560c | ||
|
|
a5e6d9ef3d | ||
|
|
5e58af466c | ||
|
|
899c15f023 | ||
|
|
861da7b5c9 | ||
|
|
a974fddd4c | ||
|
|
83a3e243da | ||
|
|
b62cf698a5 | ||
|
|
b928e5c4dc | ||
|
|
b748ea7239 | ||
|
|
bd9ba1139e | ||
|
|
5ed25aa327 | ||
|
|
7f51f21512 | ||
|
|
c24cc726e8 | ||
|
|
7b90a8f921 | ||
|
|
9fb96cd200 | ||
|
|
f881b59d60 | ||
|
|
ebb07520c0 | ||
|
|
f286e308bf | ||
|
|
29af3be2e3 | ||
|
|
29d5ae621a | ||
|
|
6e275514ad | ||
|
|
08503943f4 | ||
|
|
0c547748bf | ||
|
|
6623dcbebf | ||
|
|
89dc43f361 | ||
|
|
b77aac43ea | ||
|
|
0d63fa02ee | ||
|
|
19ab9f0403 | ||
|
|
c895554a22 | ||
|
|
968c2c40fa | ||
|
|
de845d2885 | ||
|
|
0e1f57d712 | ||
|
|
6b3dfbc635 | ||
|
|
5e2b4dec99 | ||
|
|
0cd4a143ab | ||
|
|
c7ad9acc79 | ||
|
|
afeaf90d0d | ||
|
|
e187bc442d | ||
|
|
d62268fbfb | ||
|
|
3603aaafa6 | ||
|
|
6cab8d2cd4 | ||
|
|
ca2f3d76e6 | ||
|
|
a2beaf0582 | ||
|
|
4a116e6791 | ||
|
|
040fc64583 | ||
|
|
e19011d0e0 | ||
|
|
8d3b395e86 | ||
|
|
2d1d8a6eec | ||
|
|
498a355fb2 | ||
|
|
944031af14 | ||
|
|
ee9d427526 | ||
|
|
3b73e3de60 | ||
|
|
7685736d6c | ||
|
|
9b98ae66ce | ||
|
|
b8a3a7f221 | ||
|
|
126ba44719 | ||
|
|
503e3ba555 | ||
|
|
c264d26edd | ||
|
|
185c68c55b | ||
|
|
4624b0d1a1 | ||
|
|
5fe0a50c99 | ||
|
|
a484fe1de3 | ||
|
|
e48690bdf9 | ||
|
|
bc40ff7f19 | ||
|
|
30979124b5 | ||
|
|
6eb4c5e356 | ||
|
|
38ede3719f | ||
|
|
4503ad1e34 | ||
|
|
9fc6b0d654 | ||
|
|
d00223332e | ||
|
|
d3013ae151 | ||
|
|
b2fc46c320 | ||
|
|
53aac259a0 | ||
|
|
af35b87d5b | ||
|
|
0171452b02 | ||
|
|
065a33c846 | ||
|
|
90601b9471 | ||
|
|
327f630ed7 | ||
|
|
96acc6900d | ||
|
|
91cc36f1ec | ||
|
|
575e54e5d6 | ||
|
|
9a2fd38f33 | ||
|
|
7cba0da0a2 | ||
|
|
d8eb48c9de | ||
|
|
3ccd592eab | ||
|
|
732628acf5 | ||
|
|
a157546d82 | ||
|
|
3ec704b91c | ||
|
|
331af7bf35 | ||
|
|
473aff9093 | ||
|
|
6ff08f2ac1 | ||
|
|
3db7f6675e | ||
|
|
e501a15ef2 | ||
|
|
4e8974bcd9 | ||
|
|
7914372707 | ||
|
|
3c794247c3 | ||
|
|
7bd00d2b30 | ||
|
|
ae12e3a51c | ||
|
|
0759797e61 | ||
|
|
fdc2ab30c0 | ||
|
|
122541eedc | ||
|
|
fddc5160c7 | ||
|
|
7e54bc8bcd | ||
|
|
e1ebe97eb5 | ||
|
|
9fed30af55 | ||
|
|
4fd02d7e75 | ||
|
|
e30a99f692 | ||
|
|
b891c52d9b | ||
|
|
74eb8a77e5 | ||
|
|
ba59d6d1b7 | ||
|
|
46efeb7fa8 | ||
|
|
673c1104b2 |
7
.dir-locals.el
Normal file
7
.dir-locals.el
Normal file
@@ -0,0 +1,7 @@
|
||||
;;; Directory Local Variables -*- no-byte-compile: t -*-
|
||||
;;; For more information see (info "(emacs) Directory Variables")
|
||||
|
||||
((c++-mode . ((c-file-style . "filament")
|
||||
(apheleia-inhibit . t)))
|
||||
(c-mode . ((c-file-style . "filament")
|
||||
(apheleia-inhibit . t))))
|
||||
11
.editorconfig
Normal file
11
.editorconfig
Normal file
@@ -0,0 +1,11 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
charset = utf-8
|
||||
|
||||
[*.{c,cpp,h,inc,kt,java,js,md}]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
max_line_length = 100
|
||||
6
.github/ISSUE_TEMPLATE/bug_report.md
vendored
6
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -4,6 +4,8 @@ about: Create a report to help us improve
|
||||
|
||||
---
|
||||
|
||||
⚠️ **Issues not using this template will be systematically closed.**
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
@@ -18,8 +20,8 @@ A clear and concise description of what you expected to happen.
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Logs**
|
||||
If applicable, copy logs from your console here. Please *do not*
|
||||
use screenshots of logs, copy them as text.
|
||||
If applicable, copy **full** logs from your console here. Please *do not*
|
||||
use screenshots of logs, copy them as text, use gist or attach an *uncompressed* file.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: [e.g. iOS]
|
||||
|
||||
10
.github/workflows/android-continuous.yml
vendored
10
.github/workflows/android-continuous.yml
vendored
@@ -10,10 +10,14 @@ on:
|
||||
jobs:
|
||||
build-android:
|
||||
name: build-android
|
||||
runs-on: macos-latest
|
||||
runs-on: macos-14
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '17'
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/android && printf "y" | ./build.sh continuous
|
||||
@@ -25,10 +29,6 @@ jobs:
|
||||
with:
|
||||
name: filamat-android-full
|
||||
path: out/filamat-android-release.aar
|
||||
- uses: actions/upload-artifact@v1.0.0
|
||||
with:
|
||||
name: filamat-android-lite
|
||||
path: out/filamat-android-lite-release.aar
|
||||
- uses: actions/upload-artifact@v1.0.0
|
||||
with:
|
||||
name: gltfio-android-release
|
||||
|
||||
30
.github/workflows/cocopods-deploy.yml
vendored
Normal file
30
.github/workflows/cocopods-deploy.yml
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
name: CocoaPods Deploy
|
||||
|
||||
# This must be run after the iOS release job has finished, and the iOS release
|
||||
# asset has been uploaded to Github.
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
release_tag:
|
||||
description: 'Release tag to deploy (e.g., v1.42.2)'
|
||||
required: true
|
||||
default: 'v1.42.2'
|
||||
|
||||
jobs:
|
||||
cocoapods-deploy:
|
||||
name: cocoapods-deploy
|
||||
runs-on: macos-14
|
||||
steps:
|
||||
- name: Check out iOS/CocoaPods directory
|
||||
uses: Bhacaz/checkout-files@49fc3050859046bf4f4873678d46099985640e89
|
||||
with:
|
||||
files: ios/CocoaPods
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
branch: ${{ github.event.inputs.release_tag }}
|
||||
- name: Move podspec to root
|
||||
run: mv ios/CocoaPods/*.podspec .
|
||||
- name: Install CocoaPods
|
||||
run: gem install cocoapods
|
||||
- uses: michaelhenry/deploy-to-cocoapods-github-action@745686ab065f90596e0d5cfcf97bb2416d94262e
|
||||
env:
|
||||
COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }}
|
||||
2
.github/workflows/ios-continuous.yml
vendored
2
.github/workflows/ios-continuous.yml
vendored
@@ -10,7 +10,7 @@ on:
|
||||
jobs:
|
||||
build-ios:
|
||||
name: build-ios
|
||||
runs-on: macos-latest
|
||||
runs-on: macos-14
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
|
||||
2
.github/workflows/mac-continuous.yml
vendored
2
.github/workflows/mac-continuous.yml
vendored
@@ -10,7 +10,7 @@ on:
|
||||
jobs:
|
||||
build-mac:
|
||||
name: build-mac
|
||||
runs-on: macos-latest
|
||||
runs-on: macos-14
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
|
||||
33
.github/workflows/npm-deploy.yml
vendored
Normal file
33
.github/workflows/npm-deploy.yml
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
name: Npm Deploy
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
release_tag:
|
||||
description: 'Release tag to deploy (e.g., v1.42.2)'
|
||||
required: true
|
||||
default: 'v1.42.2'
|
||||
|
||||
jobs:
|
||||
npm-deploy:
|
||||
name: npm-deploy
|
||||
runs-on: macos-14
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
with:
|
||||
ref: ${{ github.event.inputs.release_tag }}
|
||||
# Setup .npmrc file to publish to npm
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '18.x'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/web && printf "y" | ./build.sh release
|
||||
- name: Deploy to npm
|
||||
run: |
|
||||
cd out/cmake-webgl-release/web/filament-js
|
||||
npm publish
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
12
.github/workflows/presubmit.yml
vendored
12
.github/workflows/presubmit.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-latest, ubuntu-22.04]
|
||||
os: [macos-14, ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
@@ -40,17 +40,21 @@ jobs:
|
||||
|
||||
build-android:
|
||||
name: build-android
|
||||
runs-on: macos-latest
|
||||
runs-on: macos-14
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '17'
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/android && printf "y" | ./build.sh presubmit
|
||||
|
||||
build-ios:
|
||||
name: build-iOS
|
||||
runs-on: macos-latest
|
||||
runs-on: macos-14
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
@@ -63,7 +67,7 @@ jobs:
|
||||
|
||||
build-web:
|
||||
name: build-web
|
||||
runs-on: macos-latest
|
||||
runs-on: macos-14
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
|
||||
18
.github/workflows/release.yml
vendored
18
.github/workflows/release.yml
vendored
@@ -31,7 +31,7 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-latest, ubuntu-22.04]
|
||||
os: [macos-14, ubuntu-22.04]
|
||||
|
||||
steps:
|
||||
- name: Decide Git ref
|
||||
@@ -65,7 +65,7 @@ jobs:
|
||||
|
||||
build-web:
|
||||
name: build-web
|
||||
runs-on: macos-latest
|
||||
runs-on: macos-14
|
||||
if: github.event_name == 'release' || github.event.inputs.platform == 'web'
|
||||
|
||||
steps:
|
||||
@@ -98,7 +98,7 @@ jobs:
|
||||
|
||||
build-android:
|
||||
name: build-android
|
||||
runs-on: macos-latest
|
||||
runs-on: macos-14
|
||||
if: github.event_name == 'release' || github.event.inputs.platform == 'android'
|
||||
|
||||
steps:
|
||||
@@ -112,6 +112,10 @@ jobs:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
with:
|
||||
ref: ${{ steps.git_ref.outputs.ref }}
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '17'
|
||||
- name: Run build script
|
||||
env:
|
||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||
@@ -120,13 +124,12 @@ jobs:
|
||||
cd ../..
|
||||
mv out/filament-android-release.aar out/filament-${TAG}-android.aar
|
||||
mv out/filamat-android-release.aar out/filamat-${TAG}-android.aar
|
||||
mv out/filamat-android-lite-release.aar out/filamat-${TAG}-lite-android.aar
|
||||
mv out/gltfio-android-release.aar out/gltfio-${TAG}-android.aar
|
||||
mv out/filament-utils-android-release.aar out/filament-utils-${TAG}-android.aar
|
||||
- name: Sign sample-gltf-viewer
|
||||
run: |
|
||||
echo "${APK_KEYSTORE_BASE64}" > filament.jks.base64
|
||||
base64 --decode filament.jks.base64 > filament.jks
|
||||
base64 --decode -i filament.jks.base64 > filament.jks
|
||||
BUILD_TOOLS_VERSION=$(ls ${ANDROID_HOME}/build-tools | sort -V | tail -n 1)
|
||||
APKSIGNER=${ANDROID_HOME}/build-tools/${BUILD_TOOLS_VERSION}/apksigner
|
||||
IN_FILE="out/sample-gltf-viewer-release.apk"
|
||||
@@ -149,7 +152,7 @@ jobs:
|
||||
|
||||
build-ios:
|
||||
name: build-ios
|
||||
runs-on: macos-latest
|
||||
runs-on: macos-14
|
||||
if: github.event_name == 'release' || github.event.inputs.platform == 'ios'
|
||||
|
||||
steps:
|
||||
@@ -202,8 +205,7 @@ jobs:
|
||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||
run: |
|
||||
build\windows\build-github.bat release
|
||||
cd ..\..
|
||||
move out\filament-windows.tgz out\filament-%TAG%-windows.tgz
|
||||
move out\filament-windows.tgz out\filament-$Env:TAG-windows.tgz
|
||||
shell: cmd
|
||||
- uses: actions/github-script@v6
|
||||
env:
|
||||
|
||||
2
.github/workflows/web-continuous.yml
vendored
2
.github/workflows/web-continuous.yml
vendored
@@ -10,7 +10,7 @@ on:
|
||||
jobs:
|
||||
build-web:
|
||||
name: build-web
|
||||
runs-on: macos-latest
|
||||
runs-on: macos-14
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -16,3 +16,5 @@ settings.json
|
||||
test*.png
|
||||
test*.json
|
||||
results
|
||||
/compile_commands.json
|
||||
/.cache
|
||||
|
||||
159
BUILDING.md
159
BUILDING.md
@@ -5,7 +5,7 @@
|
||||
To build Filament, you must first install the following tools:
|
||||
|
||||
- CMake 3.19 (or more recent)
|
||||
- clang 7.0 (or more recent)
|
||||
- clang 14.0 (or more recent)
|
||||
- [ninja 1.10](https://github.com/ninja-build/ninja/wiki/Pre-built-Ninja-packages) (or more recent)
|
||||
|
||||
Additional dependencies may be required for your operating system. Please refer to the appropriate
|
||||
@@ -13,9 +13,10 @@ section below.
|
||||
|
||||
To build Filament for Android you must also install the following:
|
||||
|
||||
- Android Studio Arctic Fox or more recent
|
||||
- Android Studio Flamingo or more recent
|
||||
- Android SDK
|
||||
- Android NDK 25.1 or higher
|
||||
- Java 17
|
||||
|
||||
### Environment variables
|
||||
|
||||
@@ -39,25 +40,27 @@ inside the Filament source tree.
|
||||
|
||||
To trigger an incremental debug build:
|
||||
|
||||
```
|
||||
$ ./build.sh debug
|
||||
```shell
|
||||
./build.sh debug
|
||||
```
|
||||
|
||||
To trigger an incremental release build:
|
||||
|
||||
```
|
||||
$ ./build.sh release
|
||||
```shell
|
||||
./build.sh release
|
||||
```
|
||||
|
||||
To trigger both incremental debug and release builds:
|
||||
|
||||
```
|
||||
$ ./build.sh debug release
|
||||
```shell
|
||||
./build.sh debug release
|
||||
```
|
||||
|
||||
If build fails for some reasons, it may leave the `out/` directory in a broken state. You can
|
||||
force a clean build by adding the `-c` flag in that case.
|
||||
|
||||
To install the libraries and executables in `out/debug/` and `out/release/`, add the `-i` flag.
|
||||
You can force a clean build by adding the `-c` flag. The script offers more features described
|
||||
by executing `build.sh -h`.
|
||||
The script offers more features described by executing `build.sh -h`.
|
||||
|
||||
### Filament-specific CMake Options
|
||||
|
||||
@@ -75,9 +78,9 @@ The following CMake options are boolean options specific to Filament:
|
||||
|
||||
To turn an option on or off:
|
||||
|
||||
```
|
||||
$ cd <cmake-build-directory>
|
||||
$ cmake . -DOPTION=ON # Relace OPTION with the option name, set to ON / OFF
|
||||
```shell
|
||||
cd <cmake-build-directory>
|
||||
cmake . -DOPTION=ON # Replace OPTION with the option name, set to ON / OFF
|
||||
```
|
||||
|
||||
Options can also be set with the CMake GUI.
|
||||
@@ -86,10 +89,10 @@ Options can also be set with the CMake GUI.
|
||||
|
||||
Make sure you've installed the following dependencies:
|
||||
|
||||
- `clang-7` or higher
|
||||
- `clang-14` or higher
|
||||
- `libglu1-mesa-dev`
|
||||
- `libc++-7-dev` (`libcxx-devel` and `libcxx-static` on Fedora) or higher
|
||||
- `libc++abi-7-dev` (`libcxxabi-static` on Fedora) or higher
|
||||
- `libc++-14-dev` (`libcxx-devel` and `libcxx-static` on Fedora) or higher
|
||||
- `libc++abi-14-dev` (`libcxxabi-static` on Fedora) or higher
|
||||
- `ninja-build`
|
||||
- `libxi-dev`
|
||||
- `libxcomposite-dev` (`libXcomposite-devel` on Fedora)
|
||||
@@ -101,38 +104,38 @@ script.
|
||||
If you'd like to run `cmake` directly rather than using the build script, it can be invoked as
|
||||
follows, with some caveats that are explained further down.
|
||||
|
||||
```
|
||||
$ mkdir out/cmake-release
|
||||
$ cd out/cmake-release
|
||||
$ cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../release/filament ../..
|
||||
```shell
|
||||
mkdir out/cmake-release
|
||||
cd out/cmake-release
|
||||
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../release/filament ../..
|
||||
```
|
||||
|
||||
Your Linux distribution might default to `gcc` instead of `clang`, if that's the case invoke
|
||||
`cmake` with the following command:
|
||||
|
||||
```
|
||||
$ mkdir out/cmake-release
|
||||
$ cd out/cmake-release
|
||||
# Or use a specific version of clang, for instance /usr/bin/clang-7
|
||||
$ CC=/usr/bin/clang CXX=/usr/bin/clang++ CXXFLAGS=-stdlib=libc++ \
|
||||
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../release/filament ../..
|
||||
```shell
|
||||
mkdir out/cmake-release
|
||||
cd out/cmake-release
|
||||
# Or use a specific version of clang, for instance /usr/bin/clang-14
|
||||
CC=/usr/bin/clang CXX=/usr/bin/clang++ CXXFLAGS=-stdlib=libc++ \
|
||||
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../release/filament ../..
|
||||
```
|
||||
|
||||
You can also export the `CC` and `CXX` environment variables to always point to `clang`. Another
|
||||
solution is to use `update-alternatives` to both change the default compiler, and point to a
|
||||
specific version of clang:
|
||||
|
||||
```
|
||||
$ update-alternatives --install /usr/bin/clang clang /usr/bin/clang-7 100
|
||||
$ update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-7 100
|
||||
$ update-alternatives --install /usr/bin/cc cc /usr/bin/clang 100
|
||||
$ update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++ 100
|
||||
```shell
|
||||
update-alternatives --install /usr/bin/clang clang /usr/bin/clang-14 100
|
||||
update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-14 100
|
||||
update-alternatives --install /usr/bin/cc cc /usr/bin/clang 100
|
||||
update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++ 100
|
||||
```
|
||||
|
||||
Finally, invoke `ninja`:
|
||||
|
||||
```
|
||||
$ ninja
|
||||
```shell
|
||||
ninja
|
||||
```
|
||||
|
||||
This will build Filament, its tests and samples, and various host tools.
|
||||
@@ -142,8 +145,8 @@ This will build Filament, its tests and samples, and various host tools.
|
||||
To compile Filament you must have the most recent version of Xcode installed and you need to
|
||||
make sure the command line tools are setup by running:
|
||||
|
||||
```
|
||||
$ xcode-select --install
|
||||
```shell
|
||||
xcode-select --install
|
||||
```
|
||||
|
||||
If you wish to run the Vulkan backend instead of the default Metal backend, you must install
|
||||
@@ -151,11 +154,11 @@ the LunarG SDK, enable "System Global Components", and reboot your machine.
|
||||
|
||||
Then run `cmake` and `ninja` to trigger a build:
|
||||
|
||||
```
|
||||
$ mkdir out/cmake-release
|
||||
$ cd out/cmake-release
|
||||
$ cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../release/filament ../..
|
||||
$ ninja
|
||||
```shell
|
||||
mkdir out/cmake-release
|
||||
cd out/cmake-release
|
||||
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../release/filament ../..
|
||||
ninja
|
||||
```
|
||||
|
||||
### iOS
|
||||
@@ -163,24 +166,24 @@ $ ninja
|
||||
The easiest way to build Filament for iOS is to use `build.sh` and the
|
||||
`-p ios` flag. For instance to build the debug target:
|
||||
|
||||
```
|
||||
$ ./build.sh -p ios debug
|
||||
```shell
|
||||
./build.sh -p ios debug
|
||||
```
|
||||
|
||||
See [ios/samples/README.md](./ios/samples/README.md) for more information.
|
||||
|
||||
### Windows
|
||||
|
||||
#### Building on Windows with Visual Studio 2019
|
||||
#### Building on Windows with Visual Studio 2019 or later
|
||||
|
||||
Install the following components:
|
||||
|
||||
- [Visual Studio 2019](https://www.visualstudio.com/downloads)
|
||||
- [Windows 10 SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk)
|
||||
- [Visual Studio 2019 or later](https://www.visualstudio.com/downloads)
|
||||
- [Windows SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/)
|
||||
- [Python 3.7](https://www.python.org/ftp/python/3.7.0/python-3.7.0.exe)
|
||||
- [CMake 3.14 or later](https://github.com/Kitware/CMake/releases/download/v3.14.7/cmake-3.14.7-win64-x64.msi)
|
||||
|
||||
The latest Windows SDK can also by installed by opening Visual Studio and selecting _Get Tools and
|
||||
The latest Windows SDK can also be installed by opening Visual Studio and selecting _Get Tools and
|
||||
Features..._ under the _Tools_ menu.
|
||||
|
||||
By default, Windows treats the file system as case insensitive. Please do not enable case
|
||||
@@ -190,10 +193,10 @@ using `fsutil.exe file queryCaseSensitiveInfo`.
|
||||
Next, open `x64 Native Tools Command Prompt for VS 2019`, create a working directory, and run
|
||||
CMake in it:
|
||||
|
||||
```
|
||||
> mkdir out
|
||||
> cd out
|
||||
> cmake ..
|
||||
```bat
|
||||
mkdir out
|
||||
cd out
|
||||
cmake ..
|
||||
```
|
||||
|
||||
Open the generated solution file `TNT.sln` in Visual Studio.
|
||||
@@ -203,15 +206,15 @@ target in the _Solution Explorer_ and choose _Build_ to build a specific target.
|
||||
|
||||
For example, build the `material_sandbox` sample and run it from the `out` directory with:
|
||||
|
||||
```
|
||||
> samples\Debug\material_sandbox.exe ..\assets\models\monkey\monkey.obj
|
||||
```bat
|
||||
samples\Debug\material_sandbox.exe ..\assets\models\monkey\monkey.obj
|
||||
```
|
||||
|
||||
You can also use CMake to invoke the build without opening Visual Studio. For example, from the
|
||||
`out` folder run the following command.
|
||||
|
||||
```
|
||||
> cmake --build . --target gltf_viewer --config Release
|
||||
```bat
|
||||
cmake --build . --target gltf_viewer --config Release
|
||||
```
|
||||
|
||||
### Android
|
||||
@@ -236,8 +239,8 @@ To build Android on Windows machines, see [android/Windows.md](android/Windows.m
|
||||
The easiest way to build Filament for Android is to use `build.sh` and the
|
||||
`-p android` flag. For instance to build the release target:
|
||||
|
||||
```
|
||||
$ ./build.sh -p android release
|
||||
```shell
|
||||
./build.sh -p android release
|
||||
```
|
||||
|
||||
Run `build.sh -h` for more information.
|
||||
@@ -247,23 +250,23 @@ Run `build.sh -h` for more information.
|
||||
Invoke CMake in a build directory of your choice, inside of filament's directory. The commands
|
||||
below show how to build Filament for ARM 64-bit (`aarch64`).
|
||||
|
||||
```
|
||||
$ mkdir out/android-build-release-aarch64
|
||||
$ cd out/android-build-release-aarch64
|
||||
$ cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=../../build/toolchain-aarch64-linux-android.cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../android-release/filament ../..
|
||||
```shell
|
||||
mkdir out/android-build-release-aarch64
|
||||
cd out/android-build-release-aarch64
|
||||
cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=../../build/toolchain-aarch64-linux-android.cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../android-release/filament ../..
|
||||
```
|
||||
|
||||
And then invoke `ninja`:
|
||||
|
||||
```
|
||||
$ ninja install
|
||||
```shell
|
||||
ninja install
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
$ ninja install/strip
|
||||
```shell
|
||||
ninja install/strip
|
||||
```
|
||||
|
||||
This will generate Filament's Android binaries in `out/android-release`. This location is important
|
||||
@@ -295,8 +298,8 @@ AAR.
|
||||
Alternatively you can build the AAR from the command line by executing the following in the
|
||||
`android/` directory:
|
||||
|
||||
```
|
||||
$ ./gradlew -Pcom.google.android.filament.dist-dir=../../out/android-release/filament assembleRelease
|
||||
```shell
|
||||
./gradlew -Pcom.google.android.filament.dist-dir=../../out/android-release/filament assembleRelease
|
||||
```
|
||||
|
||||
The `-Pcom.google.android.filament.dist-dir` can be used to specify a different installation
|
||||
@@ -310,7 +313,7 @@ sure to add the newly created module as a dependency to your application.
|
||||
If you do not wish to include all supported ABIs, make sure to create the appropriate flavors in
|
||||
your Gradle build file. For example:
|
||||
|
||||
```
|
||||
```gradle
|
||||
flavorDimensions 'cpuArch'
|
||||
productFlavors {
|
||||
arm8 {
|
||||
@@ -352,7 +355,7 @@ started, follow the instructions for building Filament on your platform ([macOS]
|
||||
Next, you need to install the Emscripten SDK. The following instructions show how to install the
|
||||
same version that our continuous builds use.
|
||||
|
||||
```
|
||||
```shell
|
||||
cd <your chosen parent folder for the emscripten SDK>
|
||||
curl -L https://github.com/emscripten-core/emsdk/archive/refs/tags/3.1.15.zip > emsdk.zip
|
||||
unzip emsdk.zip ; mv emsdk-* emsdk ; cd emsdk
|
||||
@@ -363,7 +366,7 @@ source ./emsdk_env.sh
|
||||
|
||||
After this you can invoke the [easy build](#easy-build) script as follows:
|
||||
|
||||
```
|
||||
```shell
|
||||
export EMSDK=<your chosen home for the emscripten SDK>
|
||||
./build.sh -p webgl release
|
||||
```
|
||||
@@ -373,7 +376,7 @@ creates a `samples` folder that can be used as the root of a simple static web s
|
||||
cannot open the HTML directly from the filesystem due to CORS. We recommend using the emrun tool
|
||||
to create a quick localhost server:
|
||||
|
||||
```
|
||||
```shell
|
||||
emrun out/cmake-webgl-release/web/samples --no_browser --port 8000
|
||||
```
|
||||
|
||||
@@ -394,7 +397,7 @@ Some of the samples accept FBX/OBJ meshes while others rely on the `filamesh` fi
|
||||
generate a `filamesh ` file from an FBX/OBJ asset, run the `filamesh` tool
|
||||
(`./tools/filamesh/filamesh` in your build directory):
|
||||
|
||||
```
|
||||
```shell
|
||||
filamesh ./assets/models/monkey/monkey.obj monkey.filamesh
|
||||
```
|
||||
|
||||
@@ -404,7 +407,7 @@ files for the IBL (which are PNGs containing `R11F_G11F_B10F` data) or a path to
|
||||
containing two `.ktx` files (one for the IBL itself, one for the skybox). To generate an IBL
|
||||
simply use this command:
|
||||
|
||||
```
|
||||
```shell
|
||||
cmgen -f ktx -x ./ibls/ my_ibl.exr
|
||||
```
|
||||
|
||||
@@ -426,9 +429,9 @@ value is the desired roughness between 0 and 1.
|
||||
To generate the documentation you must first install `doxygen` and `graphviz`, then run the
|
||||
following commands:
|
||||
|
||||
```
|
||||
$ cd filament/filament
|
||||
$ doxygen docs/doxygen/filament.doxygen
|
||||
```shell
|
||||
cd filament/filament
|
||||
doxygen docs/doxygen/filament.doxygen
|
||||
```
|
||||
|
||||
Finally simply open `docs/html/index.html` in your web browser.
|
||||
@@ -438,7 +441,7 @@ Finally simply open `docs/html/index.html` in your web browser.
|
||||
To try out Filament's Vulkan support with SwiftShader, first build SwiftShader and set the
|
||||
`SWIFTSHADER_LD_LIBRARY_PATH` variable to the folder that contains `libvk_swiftshader.dylib`:
|
||||
|
||||
```
|
||||
```shell
|
||||
git clone https://github.com/google/swiftshader.git
|
||||
cd swiftshader/build
|
||||
cmake .. && make -j
|
||||
@@ -453,7 +456,7 @@ Continuous testing turnaround can be quite slow if you need to build SwiftShader
|
||||
provide an Ubuntu-based Docker image that has it already built. The Docker image also includes
|
||||
everything necessary for building Filament. You can fetch and run the image as follows:
|
||||
|
||||
```
|
||||
```shell
|
||||
docker pull ghcr.io/filament-assets/swiftshader
|
||||
docker run -it ghcr.io/filament-assets/swiftshader
|
||||
```
|
||||
|
||||
@@ -3,6 +3,14 @@
|
||||
# ==================================================================================================
|
||||
cmake_minimum_required(VERSION 3.19)
|
||||
|
||||
# ==================================================================================================
|
||||
# Toolchain configuration
|
||||
# ==================================================================================================
|
||||
if (APPLE AND NOT IOS)
|
||||
# This must be set before project() is called
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.15 CACHE STRING "")
|
||||
endif()
|
||||
|
||||
# ==================================================================================================
|
||||
# Project declaration
|
||||
# ==================================================================================================
|
||||
@@ -33,6 +41,10 @@ option(FILAMENT_LINUX_IS_MOBILE "Treat Linux as Mobile" OFF)
|
||||
|
||||
option(FILAMENT_ENABLE_ASAN_UBSAN "Enable Address and Undefined Behavior Sanitizers" OFF)
|
||||
|
||||
option(FILAMENT_ENABLE_TSAN "Enable Thread Sanitizer" OFF)
|
||||
|
||||
option(FILAMENT_ENABLE_FEATURE_LEVEL_0 "Enable Feature Level 0" ON)
|
||||
|
||||
set(FILAMENT_NDK_VERSION "" CACHE STRING
|
||||
"Android NDK version or version prefix to be used when building for Android."
|
||||
)
|
||||
@@ -57,6 +69,9 @@ set(FILAMENT_METAL_HANDLE_ARENA_SIZE_IN_MB "8" CACHE STRING
|
||||
"Size of the Metal handle arena, default 8."
|
||||
)
|
||||
|
||||
# Enable exceptions by default in spirv-cross.
|
||||
set(SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS OFF)
|
||||
|
||||
# ==================================================================================================
|
||||
# CMake policies
|
||||
# ==================================================================================================
|
||||
@@ -124,11 +139,16 @@ if (LINUX)
|
||||
add_definitions(-DFILAMENT_SUPPORTS_XCB)
|
||||
endif()
|
||||
|
||||
# Default Swiftshader build does not enable the xlib extension
|
||||
if (FILAMENT_SUPPORTS_XLIB AND FILAMENT_USE_SWIFTSHADER)
|
||||
set(FILAMENT_SUPPORTS_XLIB OFF)
|
||||
endif()
|
||||
|
||||
if (FILAMENT_SUPPORTS_XLIB)
|
||||
add_definitions(-DFILAMENT_SUPPORTS_XLIB)
|
||||
endif()
|
||||
|
||||
if (FILAMENT_SUPPORTS_XCB OR FILAMENT_SUPORTS_XLIB)
|
||||
if (FILAMENT_SUPPORTS_XCB OR FILAMENT_SUPPORTS_XLIB)
|
||||
add_definitions(-DFILAMENT_SUPPORTS_X11)
|
||||
set(FILAMENT_SUPPORTS_X11 TRUE)
|
||||
endif()
|
||||
@@ -212,6 +232,21 @@ if (WIN32)
|
||||
# we don't need them on CI.
|
||||
string(REPLACE "/INCREMENTAL" "/INCREMENTAL:NO" ${LinkerFlag} ${${LinkerFlag}})
|
||||
endforeach()
|
||||
|
||||
# We turn off compile-time optimizations for CI, as options that speed up the compile-time
|
||||
# (e.g. /MP) might increase memory usage, leading to instabilities on limited CI machines.
|
||||
option(FILAMENT_SHORTEN_MSVC_COMPILATION "Shorten compile-time in Visual Studio" OFF)
|
||||
else()
|
||||
option(FILAMENT_SHORTEN_MSVC_COMPILATION "Shorten compile-time in Visual Studio" ON)
|
||||
endif()
|
||||
|
||||
if (MSVC)
|
||||
if (FILAMENT_SHORTEN_MSVC_COMPILATION)
|
||||
# enable multi-processor compilation
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
||||
# disable run-time STL checks to improve tools (e.g. matc) performance
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /D_ITERATOR_DEBUG_LEVEL=0")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -324,6 +359,7 @@ endif()
|
||||
|
||||
if (CYGWIN)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions -fno-rtti")
|
||||
set(SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS ON)
|
||||
endif()
|
||||
|
||||
if (MSVC)
|
||||
@@ -360,6 +396,7 @@ endif()
|
||||
# saved by -fno-exception and 10 KiB saved by -fno-rtti).
|
||||
if (ANDROID OR IOS OR WEBGL)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-exceptions -fno-rtti")
|
||||
set(SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS ON)
|
||||
|
||||
if (ANDROID OR WEBGL)
|
||||
# Omitting unwind info prevents the generation of readable stack traces in crash reports on iOS
|
||||
@@ -367,6 +404,13 @@ if (ANDROID OR IOS OR WEBGL)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Turn off exceptions on iOS debug as well. This fixes an availability error we see when using
|
||||
# std::visit, which is not supported on iOS 11.0 when exceptions are enabled.
|
||||
if (IOS)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-exceptions")
|
||||
set(SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS ON)
|
||||
endif()
|
||||
|
||||
# With WebGL, we disable RTTI even for debug builds because we pass emscripten::val back and forth
|
||||
# between C++ and JavaScript in order to efficiently access typed arrays, which are unbound.
|
||||
# NOTE: This is not documented in emscripten so we should consider a different approach.
|
||||
@@ -384,7 +428,13 @@ endif()
|
||||
if (FILAMENT_ENABLE_ASAN_UBSAN)
|
||||
set(EXTRA_SANITIZE_OPTIONS "-fsanitize=address -fsanitize=undefined")
|
||||
endif()
|
||||
|
||||
if (FILAMENT_ENABLE_TSAN)
|
||||
set(EXTRA_SANITIZE_OPTIONS "-fsanitize=thread")
|
||||
endif()
|
||||
if (ANDROID)
|
||||
# keep STL debug infos (mimics what the NDK does)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-limit-debug-info")
|
||||
endif()
|
||||
if (NOT MSVC AND NOT WEBGL)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fstack-protector")
|
||||
endif()
|
||||
@@ -504,6 +554,11 @@ if (FILAMENT_SUPPORTS_METAL)
|
||||
set(MATC_API_FLAGS ${MATC_API_FLAGS} -a metal)
|
||||
endif()
|
||||
|
||||
# Disable ESSL 1.0 code generation.
|
||||
if (NOT FILAMENT_ENABLE_FEATURE_LEVEL_0)
|
||||
set(MATC_API_FLAGS ${MATC_API_FLAGS} -1)
|
||||
endif()
|
||||
|
||||
# Enable debug info (preserves names in SPIR-V)
|
||||
if (FILAMENT_ENABLE_MATDBG)
|
||||
set(MATC_OPT_FLAGS ${MATC_OPT_FLAGS} -d)
|
||||
@@ -579,9 +634,9 @@ function(combine_static_libs TARGET OUTPUT DEPS)
|
||||
# Loop through the dependent libraries and query their location on disk.
|
||||
set(DEPS_FILES )
|
||||
foreach(DEPENDENCY ${DEPS})
|
||||
if(TARGET ${DEPENDENCY})
|
||||
if (TARGET ${DEPENDENCY})
|
||||
get_property(dep_type TARGET ${DEPENDENCY} PROPERTY TYPE)
|
||||
if(dep_type STREQUAL "STATIC_LIBRARY")
|
||||
if (dep_type STREQUAL "STATIC_LIBRARY")
|
||||
list(APPEND DEPS_FILES "$<TARGET_FILE:${DEPENDENCY}>")
|
||||
endif()
|
||||
endif()
|
||||
@@ -666,7 +721,6 @@ add_subdirectory(${LIBRARIES}/filabridge)
|
||||
add_subdirectory(${LIBRARIES}/filaflat)
|
||||
add_subdirectory(${LIBRARIES}/filagui)
|
||||
add_subdirectory(${LIBRARIES}/filameshio)
|
||||
add_subdirectory(${LIBRARIES}/geometry)
|
||||
add_subdirectory(${LIBRARIES}/gltfio)
|
||||
add_subdirectory(${LIBRARIES}/ibl)
|
||||
add_subdirectory(${LIBRARIES}/iblprefilter)
|
||||
@@ -694,6 +748,9 @@ add_subdirectory(${EXTERNAL}/jsmn/tnt)
|
||||
add_subdirectory(${EXTERNAL}/stb/tnt)
|
||||
add_subdirectory(${EXTERNAL}/getopt)
|
||||
|
||||
# Note that this has to be placed after mikktspace in order for combine_static_libs to work.
|
||||
add_subdirectory(${LIBRARIES}/geometry)
|
||||
|
||||
if (FILAMENT_BUILD_FILAMAT OR IS_HOST_PLATFORM)
|
||||
# spirv-tools must come before filamat, as filamat relies on the presence of the
|
||||
# spirv-tools_SOURCE_DIR variable.
|
||||
@@ -711,6 +768,8 @@ endif()
|
||||
if (FILAMENT_SUPPORTS_VULKAN)
|
||||
add_subdirectory(${LIBRARIES}/bluevk)
|
||||
add_subdirectory(${EXTERNAL}/vkmemalloc/tnt)
|
||||
set(SPIRV_HEADERS_SKIP_EXAMPLES ON)
|
||||
add_subdirectory(${EXTERNAL}/spirv-headers)
|
||||
endif()
|
||||
|
||||
set(FILAMENT_SAMPLES_BINARY_DIR ${PROJECT_BINARY_DIR}/samples)
|
||||
|
||||
@@ -27,7 +27,7 @@ again.
|
||||
|
||||
## Code Style
|
||||
|
||||
See [CodeStyle.md](/CODE_STYLE.md)
|
||||
See [CODE_STYLE.md](/CODE_STYLE.md)
|
||||
|
||||
## Code reviews
|
||||
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -187,7 +187,7 @@
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
Copyright 2023 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.
|
||||
|
||||
@@ -31,7 +31,7 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.android.filament:filament-android:1.32.0'
|
||||
implementation 'com.google.android.filament:filament-android:1.50.2'
|
||||
}
|
||||
```
|
||||
|
||||
@@ -40,8 +40,8 @@ Here are all the libraries available in the group `com.google.android.filament`:
|
||||
| Artifact | Description |
|
||||
| ------------- | ------------- |
|
||||
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-android) | The Filament rendering engine itself. |
|
||||
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-android-debug) | Debug version of `filament-android`. |
|
||||
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android) | A glTF 2.0 loader for Filament, depends on `filament-android`. |
|
||||
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android-lite) | Trimmed version of `gltfio` that does not support some glTF extensions. |
|
||||
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-utils-android) | KTX loading, Kotlin math, and camera utilities, depends on `gltfio-android`. |
|
||||
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android) | A runtime material builder/compiler. This library is large but contains a full shader compiler/validator/optimizer and supports both OpenGL and Vulkan. |
|
||||
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android-lite) | A much smaller alternative to `filamat-android` that can only generate OpenGL shaders. It does not provide validation or optimizations. |
|
||||
@@ -50,8 +50,8 @@ 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.32.0'
|
||||
```shell
|
||||
pod 'Filament', '~> 1.50.2'
|
||||
```
|
||||
|
||||
### Snapshots
|
||||
|
||||
@@ -9,26 +9,15 @@ Before starting, ensure that each of these branches is up-to-date with origin:
|
||||
- rc/$RELEASE
|
||||
- main
|
||||
|
||||
## 0. Make sure the rc/$RELEASE branch has the correct version.
|
||||
## 0. Check versions.
|
||||
|
||||
It should have the version corresponding to its name, $RELEASE.
|
||||
Make sure the rc/$RELEASE branch has the correct Filament version. It should have the version
|
||||
corresponding to its name, $RELEASE.
|
||||
|
||||
## 1. Update RELEASE_NOTES.md on the rc branch.
|
||||
Make sure `MATERIAL_VERSION` has been bumped to a new version if this is a MAJOR or MINOR release
|
||||
(first two version numbers).
|
||||
|
||||
Checkout the rc/$RELEASE branch. In RELEASE_NOTES.md, locate the header corresponding to $RELEASE
|
||||
and write release notes. To see which commits make up the release, run:
|
||||
|
||||
```
|
||||
build/common/release.sh -c rc/$RELEASE
|
||||
```
|
||||
|
||||
Commit the changes to rc/$RELEASE with the title:
|
||||
|
||||
```
|
||||
Update RELEASE_NOTES for $RELEASE
|
||||
```
|
||||
|
||||
## 2. Bump versions on main to $RELEASE.
|
||||
## 1. Bump Filament versions on main to $RELEASE.
|
||||
|
||||
Checkout main and run the following command to bump Filament's version to $RELEASE:
|
||||
|
||||
@@ -44,49 +33,19 @@ Release Filament $RELEASE
|
||||
|
||||
Do not push to origin yet.
|
||||
|
||||
## 3. Cherry-pick RELEASE_NOTES change from rc branch to main.
|
||||
## 2. Update RELEASE_NOTES.md on main.
|
||||
|
||||
```
|
||||
git cherry-pick rc/$RELEASE
|
||||
```
|
||||
Create a new header in RELEASE_NOTES.md for $NEXT_RELEASE. Copy the release notes in
|
||||
NEW_RELEASE_NOTES.md to RELEASE_NOTES.md under the new header. Clear NEW_RELEASE_NOTES.md.
|
||||
|
||||
Update the headers. The "main branch" header becomes a header for $NEXT_RELEASE, and a new "main
|
||||
branch" header is added.
|
||||
|
||||
For example, this:
|
||||
|
||||
```
|
||||
## main branch
|
||||
- foo
|
||||
- bar
|
||||
|
||||
## v1.9.3
|
||||
- baz
|
||||
- bat
|
||||
```
|
||||
|
||||
becomes:
|
||||
|
||||
```
|
||||
## main branch
|
||||
|
||||
## v1.9.4
|
||||
- foo
|
||||
- bar
|
||||
|
||||
## v1.9.3
|
||||
- baz
|
||||
- bat
|
||||
```
|
||||
|
||||
Ammend these changes to the cherry-picked change.
|
||||
Amend these changes to the "Release Filament $RELEASE" commit.
|
||||
|
||||
```
|
||||
git add -u
|
||||
git commit --amend --no-edit
|
||||
```
|
||||
|
||||
## 4. Run release script.
|
||||
## 3. Run release script.
|
||||
|
||||
```
|
||||
build/common/release.sh rc/$RELEASE rc/$NEXT_RELEASE
|
||||
@@ -95,18 +54,18 @@ build/common/release.sh rc/$RELEASE rc/$NEXT_RELEASE
|
||||
This script will merge rc/$RELEASE into release, delete the rc branch, and create a new rc
|
||||
branch called rc/$NEXT_RELEASE. Verify that everything looks okay locally.
|
||||
|
||||
## 5. Push the release branch.
|
||||
## 4. Push the release branch.
|
||||
|
||||
```
|
||||
git push origin release
|
||||
```
|
||||
|
||||
## 6. Create the GitHub release.
|
||||
## 5. Create the GitHub release.
|
||||
|
||||
Use the GitHub UI to create a GitHub release corresponding to $RELEASE version.
|
||||
Make sure the target is set to the release branch.
|
||||
|
||||
## 7. Delete the old rc branch (optional).
|
||||
## 6. Delete the old rc branch (optional).
|
||||
|
||||
This step is optional. The old rc branch may be left alive for a few weeks for posterity.
|
||||
|
||||
@@ -114,7 +73,7 @@ This step is optional. The old rc branch may be left alive for a few weeks for p
|
||||
git push origin --delete rc/$RELEASE
|
||||
```
|
||||
|
||||
## 8. Bump the version on the new rc branch to $NEXT_RELEASE.
|
||||
## 7. Bump the version on the new rc branch to $NEXT_RELEASE.
|
||||
|
||||
```
|
||||
git checkout rc/$NEXT_RELEASE
|
||||
@@ -127,19 +86,19 @@ Commit the changes to rc/$NEXT_RELEASE with the title:
|
||||
Bump version to $NEXT_RELEASE
|
||||
```
|
||||
|
||||
## 9. Push main.
|
||||
## 8. Push main.
|
||||
|
||||
```
|
||||
git push origin main
|
||||
```
|
||||
|
||||
## 10. Push the new rc branch.
|
||||
## 9. Push the new rc branch.
|
||||
|
||||
```
|
||||
git push origin -u rc/$NEXT_RELEASE
|
||||
```
|
||||
|
||||
## 11. Rebuild the GitHub release (if failed).
|
||||
## 10. Rebuild the GitHub release (if failed).
|
||||
|
||||
Sometimes the GitHub release job will fail. In this case, you can manually re-run the release job.
|
||||
|
||||
@@ -169,3 +128,15 @@ Navigate to [Filament's release
|
||||
workflow](https://github.com/google/filament/actions/workflows/release.yml). Hit the _Run workflow_
|
||||
dropdown. Modify _Platform to build_ and _Release tag to build_, then hit _Run workflow_. This will
|
||||
initiate a new release run.
|
||||
|
||||
## 11. Kick off the npm and CocoaPods release jobs
|
||||
|
||||
Navigate to [Filament's npm deploy
|
||||
workflow](https://github.com/google/filament/actions/workflows/npm-deploy.yml).
|
||||
Hit the _Run workflow_ dropdown. Modify _Release tag to deploy_ to the tag corresponding to this
|
||||
release (for example, v1.42.2).
|
||||
|
||||
Navigate to [Filament's CocoaPods deploy
|
||||
workflow](https://github.com/google/filament/actions/workflows/cocopods-deploy.yml).
|
||||
Hit the _Run workflow_ dropdown. Modify _Release tag to deploy_ to the tag corresponding to this
|
||||
release (for example, v1.42.2).
|
||||
|
||||
207
RELEASE_NOTES.md
207
RELEASE_NOTES.md
@@ -7,6 +7,213 @@ A new header is inserted each time a *tag* is created.
|
||||
Instead, if you are authoring a PR for the main branch, add your release note to
|
||||
[NEW_RELEASE_NOTES.md](./NEW_RELEASE_NOTES.md).
|
||||
|
||||
## v1.50.2
|
||||
|
||||
|
||||
## v1.50.1
|
||||
|
||||
- Metal: fix some shader artifacts by disabling fast math optimizations.
|
||||
- backend: remove `atan2` overload which had a typo and wasn't useful. Fixes b/320856413.
|
||||
- utils: remove usages of `SpinLock`. Fixes b/321101014.
|
||||
|
||||
## v1.50.0
|
||||
- engine: TAA now supports 4x upscaling [BETA] [⚠️ **New Material Version**]
|
||||
|
||||
## v1.49.3
|
||||
|
||||
- matc: Generate stereo variants for FL0 materials [⚠️ **Recompile materials**]
|
||||
|
||||
## v1.49.2
|
||||
|
||||
|
||||
## v1.49.1
|
||||
|
||||
|
||||
## v1.49.0
|
||||
|
||||
- matc: Fix ESSL 1.0 codegen when using external samplers [⚠️ **Recompile materials**]
|
||||
|
||||
## v1.48.0
|
||||
|
||||
- matc: New option `-1` to disable generation of ESSL 1.0 code in Feature Level 0 materials
|
||||
- matc: Support optimizations for ESSL 1.0 code [⚠️ **Recompile materials**]
|
||||
|
||||
## v1.47.0
|
||||
|
||||
- engine: Support up to 4 side-by-side stereoscopic eyes, configurable at Engine creation time. See
|
||||
`Engine::Config::stereoscopicEyeCount`. [⚠️ **Recompile Materials**]
|
||||
|
||||
## v1.46.0
|
||||
|
||||
- engine: Allow instantiating Engine at a given feature level via `Engine::Builder::featureLevel`
|
||||
- matc: Enable `GL_OES_standard_derivatives` extension in ESSL 1.0 shaders
|
||||
- matc: Fix code generation of double sided and masked materials in ESSL 1.0 shaders
|
||||
- filagui: Add support for feature level 0
|
||||
- matc: Add support for post-process materials in feature level 0
|
||||
- engine: Add `Material::getFeatureLevel()`
|
||||
- engine: Add missing `Material::getReflectionMode()` method in Java
|
||||
- engine: Support basic usage of post-processing materials on feature level 0
|
||||
- engine: Fix critical GLES 2.0 bugs
|
||||
- engine: Add `FILAMENT_ENABLE_FEATURE_LEVEL_0` build-time option optionally allow building Filament
|
||||
without FL0 support.
|
||||
|
||||
## v1.45.1
|
||||
|
||||
- engine: Added parameter for configuring JobSystem thread count
|
||||
- engine: In Java, introduce Engine.Builder
|
||||
- gltfio: fix ubershader index for transmission&volume material
|
||||
- engine: New tone mapper: `AgXTonemapper`.
|
||||
- matinfo: Add support for viewing ESSL 1.0 shaders
|
||||
- engine: Add `Renderer::getClearOptions()` [b/243846268]
|
||||
- engine: Fix stable shadows (again) when an IBL rotation is used
|
||||
|
||||
## v1.45.0
|
||||
|
||||
- materials: fix alpha masked materials when MSAA is turned on [⚠️ **Recompile materials**]
|
||||
- materials: better support materials with custom depth [**Recompile Materials**]
|
||||
- engine: fade shadows at shadowFar distance instead of hard cutoff [⚠️ **New Material Version**]
|
||||
|
||||
## v1.44.0
|
||||
|
||||
- engine: add support for skinning with more than four bones per vertex.
|
||||
- engine: remove `BloomOptions::anamorphism` which wasn't working well in most cases [**API CHANGE**]
|
||||
- engine: new API to return a Material's supported variants, C++ only (b/297456590)
|
||||
- build: fix emscripten-1.3.46 build
|
||||
- engine: materials built for feature level 0 can now also be loaded in higher feature levels [⚠️
|
||||
**New Material Version**]
|
||||
|
||||
## v1.43.1
|
||||
|
||||
## v1.43.0
|
||||
|
||||
- gltfio: Fix possible change of scale sign when decomposing transform matrix for animation
|
||||
- engine: Fixes "stable" shadows (see b/299310624)
|
||||
|
||||
## v1.42.2
|
||||
|
||||
- Fix possible NPE when updating fog options from Java/Kotlin
|
||||
- The `emissive` property was not applied properly to `MASKED` materials, and could cause
|
||||
dark fringes to appear (recompile materials)
|
||||
- Allow glTF materials with transmission/volume extensions to choose their alpha mode
|
||||
instead of forcing `MASKED`
|
||||
- Fix a crash in gltfio when not using ubershaders
|
||||
- Use flatmat for mat parameter in jsbinding
|
||||
- Fix TextureFlags for sheenRoughnessMap when textures of sheenRoughnessMap and sheenColorMap is same
|
||||
- Directional shadows can now be transformed (b/297095805)
|
||||
|
||||
## v1.42.1
|
||||
|
||||
- Fix potential `EXC_BAD_ACCESS` with Metal backend: b/297059776
|
||||
- `setFrameCompletedCallback` now takes a `backend::CallbackHandler`.
|
||||
|
||||
## v1.42.0
|
||||
|
||||
- engine: add preliminary support for instanced stereoscopic rendering [⚠️ **Recompile materials**]
|
||||
|
||||
## v1.41.0
|
||||
|
||||
- backend: fix #6997 : picking can fail on Adreno [⚠️ **New Material Version**]
|
||||
- backend: A partial workaround for PowerVR devices (#5118, b/190221124) [⚠️ **Recompile Materials**]
|
||||
|
||||
## v1.40.5
|
||||
|
||||
- backend: Disable timer queries on all Mali GPUs (fixes b/233754398)
|
||||
- engine: Add a way to query the validity of most filament objects (see `Engine::isValid`)
|
||||
- opengl: fix b/290388359 : possible crash when shutting down the engine
|
||||
- engine: Improve precision of frame time measurement when using emulated TimerQueries
|
||||
- backend: Improve frame pacing on Android and Vulkan.
|
||||
- backend: workaround b/291140208 (gltf_viewer crashes on Nexus 6P)
|
||||
- engine: support `setDepthFunc` for `MaterialInstance`
|
||||
- web: Added setDepthFunc()/getDepthFunc() to MaterialInstance
|
||||
- android: Added setDepthFunc()/getDepthFunc() to MaterialInstance
|
||||
|
||||
## v1.40.4
|
||||
|
||||
- gltfio: fix crash when compute morph target without material
|
||||
- matc: fix buggy `variant-filter` flag
|
||||
- web: Added missing setMat3Parameter()/setMat4Parameter() to MaterialInstance
|
||||
- opengl: fix b/290670707 : crash when using the blob cache
|
||||
- engine: fix a crash with `Material::compile()` when a callback is specified
|
||||
|
||||
## v1.40.3
|
||||
|
||||
## v1.40.2
|
||||
|
||||
- rendering: dynamic resolution would not work with a translucent render target and quality > low
|
||||
- Java/Kotlin: user callbacks were not invoked on successful texture upload
|
||||
|
||||
## v1.40.1
|
||||
|
||||
## v1.40.0
|
||||
|
||||
- matc: fix VSM high precision option on mobile [⚠️ **Recompile materials**]
|
||||
- vulkan: support sRGB swap chain
|
||||
- Add new `getMaxAutomaticInstances()` API on `Engine` to get max supported automatic instances.
|
||||
- UiHelper: fix jank when a `TextureView` is resized (fixes b\282220665)
|
||||
- backend: parallel shader compilation support. This breaks and improves the recent `Material::compile` API.
|
||||
|
||||
## v1.39.0
|
||||
|
||||
- matc: workaround a bug in spirv-tools causing vsm to fail [⚠️ **Recompile materials**]
|
||||
|
||||
## v1.38.0
|
||||
|
||||
- engine: a new feature to set a transform on the global-scale fog [⚠️ **Recompile materials**]
|
||||
- engine: large-scale fog can now be opted-out on a per-renderable basis
|
||||
- engine: improve froxelizer resource efficiency [⚠️ **Recompile materials**]
|
||||
- matc: better accounting and validation of used samplers in user materials
|
||||
- engine: add support for sampling fog color from a custom texture [⚠️ **Recompile materials**]
|
||||
- vulkan: introduce new custom swapchain API
|
||||
- vulkan: new context sharing API
|
||||
|
||||
## v1.37.0
|
||||
|
||||
- backend: added `Platform` blob cache APIs, typically used to cache programs [⚠️ **Recompile materials**]
|
||||
|
||||
## v1.36.0
|
||||
|
||||
- engine: a local transform can now be supplied for each GPU instance [⚠️ **Recompile materials**]
|
||||
- everything: Add limited support for OpenGL ES 2.0 devices. [⚠️ **Recompile Materials**]
|
||||
- platform: New virtual on `OpenGLPlatform` to preserve ancillary buffers
|
||||
|
||||
## v1.35.0
|
||||
|
||||
- materials: Materials can now access up to 4 global `vec4` visible by all materials [⚠️ **Recompile Materials**]
|
||||
|
||||
## v1.34.0
|
||||
|
||||
- materials: picking is done in float (prepare for ES2) [⚠️ **New Material Version**]
|
||||
- materials: postLightingBlending is now applied before the fog [⚠️ **Recompile materials**]
|
||||
- vulkan: fix adreno optimized material artifacts [⚠️ **Recompile Materials**]
|
||||
|
||||
## v1.33.0
|
||||
|
||||
- materials: prepare ES2 support [⚠️ **New Material Version**]
|
||||
|
||||
## v1.32.4
|
||||
|
||||
- engine: Add support for _constant parameters_, which are constants that can be specialized after material compilation.
|
||||
- materials: improved size reduction of OpenGL/Metal shaders by ~65% when compiling materials with
|
||||
size optimizations (`matc -S`) [⚠️ **Recompile Materials**]
|
||||
- engine: fix potential crash on Metal devices with A8X GPU (iPad Air 2) [⚠️ **Recompile Materials**]
|
||||
- opengl: support the external image on macOS
|
||||
|
||||
## v1.32.3
|
||||
|
||||
- fog: added an option to disable the fog after a certain distance [⚠️ **Recompile Materials**].
|
||||
- fog: fog color now takes exposure and IBL intensity into account [⚠️ **Recompile Materials**].
|
||||
- materials: implement cascades debugging as a post-process [⚠️ **Recompile Materials**].
|
||||
- materials: use 9 digits or less for floats [⚠️ **Recompile Materials**].
|
||||
- gltfio: fix skinning when objects are far from the origin
|
||||
- materials: remove 4 unneeded variants from `unlit` materials [⚠️ **Recompile Materials**].
|
||||
|
||||
## v1.32.2
|
||||
|
||||
- lighting: the sun disc was computed in low/medium quality instead of high quality. This will
|
||||
provide performance improvements to mobile devices [⚠️ **Recompile Materials**]
|
||||
|
||||
## v1.32.1
|
||||
|
||||
## v1.32.0
|
||||
|
||||
- fog: fixed fog height falloff and computation precision on mobile [⚠️ **Recompile Materials**]
|
||||
|
||||
@@ -135,7 +135,7 @@ gradlew -Pcom.google.android.filament.dist-dir=..\out\android-release\filament a
|
||||
If you're only interested in building SDK, you may skip samples build by passing a `com.google.android.filament.skip-samples` flag:
|
||||
|
||||
```
|
||||
gradlew -Pcom.google.android.filament.dist-dir=..\out\android-release\filament assembleRelease -Pfilament_skip_samples
|
||||
gradlew -Pcom.google.android.filament.dist-dir=..\out\android-release\filament assembleRelease -Pcom.google.android.filament.skip-samples
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -79,15 +79,16 @@ buildscript {
|
||||
}
|
||||
|
||||
ext.versions = [
|
||||
'jdk': 17,
|
||||
'minSdk': 19,
|
||||
'targetSdk': 33,
|
||||
'compileSdk': 33,
|
||||
'kotlin': '1.8.0',
|
||||
'kotlin_coroutines': '1.6.4',
|
||||
'buildTools': '33.0.1',
|
||||
'ndk': '25.1.8937393',
|
||||
'androidx_core': '1.9.0',
|
||||
'androidx_annotations': '1.3.0'
|
||||
'targetSdk': 34,
|
||||
'compileSdk': 34,
|
||||
'kotlin': '1.9.21',
|
||||
'kotlin_coroutines': '1.7.3',
|
||||
'buildTools': '34.0.0',
|
||||
'ndk': '26.1.10909125',
|
||||
'androidx_core': '1.12.0',
|
||||
'androidx_annotations': '1.7.0'
|
||||
]
|
||||
|
||||
ext.deps = [
|
||||
@@ -103,7 +104,7 @@ buildscript {
|
||||
]
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.4.0'
|
||||
classpath 'com.android.tools.build:gradle:8.2.0'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}"
|
||||
}
|
||||
|
||||
@@ -126,6 +127,7 @@ buildscript {
|
||||
"-fno-asynchronous-unwind-tables",
|
||||
"-fno-rtti",
|
||||
"-ffast-math",
|
||||
"-fno-finite-math-only",
|
||||
"-ffp-contract=fast",
|
||||
"-fvisibility-inlines-hidden",
|
||||
"-fvisibility=hidden",
|
||||
@@ -150,7 +152,7 @@ buildscript {
|
||||
}
|
||||
|
||||
plugins {
|
||||
id "io.github.gradle-nexus.publish-plugin" version "1.1.0"
|
||||
id "io.github.gradle-nexus.publish-plugin" version "1.3.0"
|
||||
}
|
||||
|
||||
// See https://github.com/gradle-nexus/publish-plugin
|
||||
@@ -193,6 +195,7 @@ subprojects {
|
||||
}
|
||||
|
||||
ndk {
|
||||
//noinspection ChromeOsAbiSupport
|
||||
abiFilters(*rootProject.ext.abis)
|
||||
}
|
||||
|
||||
@@ -213,8 +216,8 @@ subprojects {
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
sourceCompatibility versions.jdk
|
||||
targetCompatibility versions.jdk
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,6 +142,14 @@ abstract class MaterialCompiler extends TaskWithBinary {
|
||||
if (!exclude_vulkan) {
|
||||
matcArgs += ['-a', 'vulkan']
|
||||
}
|
||||
|
||||
def mat_no_opt = providers
|
||||
.gradleProperty("com.google.android.filament.matnopt")
|
||||
.forUseAtConfigurationTime().present
|
||||
if (mat_no_opt) {
|
||||
matcArgs += ['-g']
|
||||
}
|
||||
|
||||
matcArgs += ['-a', 'opengl', '-p', 'mobile', '-o', getOutputFile(file), file]
|
||||
|
||||
exec.exec {
|
||||
|
||||
@@ -6,9 +6,6 @@ option(FILAMENT_ENABLE_MATDBG "Enables Material debugger" OFF)
|
||||
set(FILAMENT_DIR ${FILAMENT_DIST_DIR})
|
||||
|
||||
set(FILAMAT_FLAVOR "filamat")
|
||||
if(FILAMAT_LITE)
|
||||
set(FILAMAT_FLAVOR "filamat_lite")
|
||||
endif()
|
||||
|
||||
if (FILAMENT_SUPPORTS_VULKAN)
|
||||
message("Library filamat ignores Vulkan settings")
|
||||
|
||||
@@ -1,20 +1,10 @@
|
||||
android {
|
||||
namespace 'com.google.android.filament.filamat'
|
||||
|
||||
flavorDimensions "functionality"
|
||||
productFlavors {
|
||||
full {
|
||||
dimension "functionality"
|
||||
}
|
||||
|
||||
lite {
|
||||
dimension "functionality"
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments.add("-DFILAMAT_LITE=ON")
|
||||
}
|
||||
}
|
||||
publishing {
|
||||
singleVariant("release") {
|
||||
withSourcesJar()
|
||||
withJavadocJar()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,14 +18,9 @@ apply from: rootProject.file('gradle/gradle-mvn-push.gradle')
|
||||
afterEvaluate { project ->
|
||||
publishing {
|
||||
publications {
|
||||
fullRelease(MavenPublication) {
|
||||
release(MavenPublication) {
|
||||
artifactId = POM_ARTIFACT_ID_FULL
|
||||
from components.fullRelease
|
||||
}
|
||||
|
||||
liteRelease(MavenPublication) {
|
||||
artifactId = POM_ARTIFACT_ID_LITE
|
||||
from components.liteRelease
|
||||
from components.release
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
android {
|
||||
namespace 'com.google.android.filament'
|
||||
|
||||
publishing {
|
||||
singleVariant("release") {
|
||||
withSourcesJar()
|
||||
withJavadocJar()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@@ -25,15 +25,8 @@
|
||||
using namespace filament;
|
||||
using namespace utils;
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_Engine_nCreateEngine(JNIEnv*, jclass, jlong backend,
|
||||
jlong sharedContext) {
|
||||
return (jlong) Engine::create((Engine::Backend) backend, nullptr, (void*) sharedContext);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Engine_nDestroyEngine(JNIEnv*, jclass,
|
||||
jlong nativeEngine) {
|
||||
Java_com_google_android_filament_Engine_nDestroyEngine(JNIEnv*, jclass, jlong nativeEngine) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
Engine::destroy(&engine);
|
||||
}
|
||||
@@ -278,6 +271,112 @@ Java_com_google_android_filament_Engine_nDestroyEntity(JNIEnv*, jclass,
|
||||
engine->destroy(entity);
|
||||
}
|
||||
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Engine_nIsValidRenderer(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeRenderer) {
|
||||
Engine* engine = (Engine *)nativeEngine;
|
||||
return (jboolean)engine->isValid((Renderer*)nativeRenderer);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Engine_nIsValidView(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeView) {
|
||||
Engine* engine = (Engine *)nativeEngine;
|
||||
return (jboolean)engine->isValid((View*)nativeView);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Engine_nIsValidScene(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeScene) {
|
||||
Engine* engine = (Engine *)nativeEngine;
|
||||
return (jboolean)engine->isValid((Scene*)nativeScene);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Engine_nIsValidFence(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeFence) {
|
||||
Engine* engine = (Engine *)nativeEngine;
|
||||
return (jboolean)engine->isValid((Fence*)nativeFence);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Engine_nIsValidStream(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeStream) {
|
||||
Engine* engine = (Engine *)nativeEngine;
|
||||
return (jboolean)engine->isValid((Stream*)nativeStream);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Engine_nIsValidIndexBuffer(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeIndexBuffer) {
|
||||
Engine* engine = (Engine *)nativeEngine;
|
||||
return (jboolean)engine->isValid((IndexBuffer*)nativeIndexBuffer);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Engine_nIsValidVertexBuffer(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeVertexBuffer) {
|
||||
Engine* engine = (Engine *)nativeEngine;
|
||||
return (jboolean)engine->isValid((VertexBuffer*)nativeVertexBuffer);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Engine_nIsValidSkinningBuffer(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeSkinningBuffer) {
|
||||
Engine* engine = (Engine *)nativeEngine;
|
||||
return (jboolean)engine->isValid((SkinningBuffer*)nativeSkinningBuffer);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Engine_nIsValidIndirectLight(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeIndirectLight) {
|
||||
Engine* engine = (Engine *)nativeEngine;
|
||||
return (jboolean)engine->isValid((IndirectLight*)nativeIndirectLight);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Engine_nIsValidMaterial(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeMaterial) {
|
||||
Engine* engine = (Engine *)nativeEngine;
|
||||
return (jboolean)engine->isValid((Material*)nativeMaterial);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Engine_nIsValidSkybox(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeSkybox) {
|
||||
Engine* engine = (Engine *)nativeEngine;
|
||||
return (jboolean)engine->isValid((Skybox*)nativeSkybox);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Engine_nIsValidColorGrading(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeColorGrading) {
|
||||
Engine* engine = (Engine *)nativeEngine;
|
||||
return (jboolean)engine->isValid((ColorGrading*)nativeColorGrading);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Engine_nIsValidTexture(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeTexture) {
|
||||
Engine* engine = (Engine *)nativeEngine;
|
||||
return (jboolean)engine->isValid((Texture*)nativeTexture);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Engine_nIsValidRenderTarget(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeTarget) {
|
||||
Engine* engine = (Engine *)nativeEngine;
|
||||
return (jboolean)engine->isValid((RenderTarget*)nativeTarget);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Engine_nIsValidSwapChain(JNIEnv*, jclass,
|
||||
jlong nativeEngine, jlong nativeSwapChain) {
|
||||
Engine* engine = (Engine *)nativeEngine;
|
||||
return (jboolean)engine->isValid((SwapChain*)nativeSwapChain);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Engine_nFlushAndWait(JNIEnv*, jclass,
|
||||
jlong nativeEngine) {
|
||||
@@ -285,6 +384,13 @@ Java_com_google_android_filament_Engine_nFlushAndWait(JNIEnv*, jclass,
|
||||
engine->flushAndWait();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Engine_nFlush(JNIEnv*, jclass,
|
||||
jlong nativeEngine) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
engine->flush();
|
||||
}
|
||||
|
||||
// Managers...
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
@@ -329,6 +435,13 @@ Java_com_google_android_filament_Engine_nIsAutomaticInstancingEnabled(JNIEnv*, j
|
||||
return (jboolean)engine->isAutomaticInstancingEnabled();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_Engine_nGetMaxStereoscopicEyes(JNIEnv*, jclass, jlong nativeEngine) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
return (jlong) engine->getMaxStereoscopicEyes();
|
||||
}
|
||||
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Engine_nGetSupportedFeatureLevel(JNIEnv *, jclass,
|
||||
jlong nativeEngine) {
|
||||
@@ -348,4 +461,57 @@ Java_com_google_android_filament_Engine_nGetActiveFeatureLevel(JNIEnv *, jclass,
|
||||
jlong nativeEngine) {
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
return (jint)engine->getActiveFeatureLevel();
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL Java_com_google_android_filament_Engine_nCreateBuilder(JNIEnv*,
|
||||
jclass) {
|
||||
Engine::Builder* builder = new Engine::Builder{};
|
||||
return (jlong) builder;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_Engine_nDestroyBuilder(JNIEnv*,
|
||||
jclass, jlong nativeBuilder) {
|
||||
Engine::Builder* builder = (Engine::Builder*) nativeBuilder;
|
||||
delete builder;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_Engine_nSetBuilderBackend(
|
||||
JNIEnv*, jclass, jlong nativeBuilder, jlong backend) {
|
||||
Engine::Builder* builder = (Engine::Builder*) nativeBuilder;
|
||||
builder->backend((Engine::Backend) backend);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_Engine_nSetBuilderConfig(JNIEnv*,
|
||||
jclass, jlong nativeBuilder, jlong commandBufferSizeMB, jlong perRenderPassArenaSizeMB,
|
||||
jlong driverHandleArenaSizeMB, jlong minCommandBufferSizeMB, jlong perFrameCommandsSizeMB,
|
||||
jlong jobSystemThreadCount, jlong stereoscopicEyeCount) {
|
||||
Engine::Builder* builder = (Engine::Builder*) nativeBuilder;
|
||||
Engine::Config config = {
|
||||
.commandBufferSizeMB = (uint32_t) commandBufferSizeMB,
|
||||
.perRenderPassArenaSizeMB = (uint32_t) perRenderPassArenaSizeMB,
|
||||
.driverHandleArenaSizeMB = (uint32_t) driverHandleArenaSizeMB,
|
||||
.minCommandBufferSizeMB = (uint32_t) minCommandBufferSizeMB,
|
||||
.perFrameCommandsSizeMB = (uint32_t) perFrameCommandsSizeMB,
|
||||
.jobSystemThreadCount = (uint32_t) jobSystemThreadCount,
|
||||
.stereoscopicEyeCount = (uint8_t) stereoscopicEyeCount,
|
||||
};
|
||||
builder->config(&config);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_Engine_nSetBuilderFeatureLevel(
|
||||
JNIEnv*, jclass, jlong nativeBuilder, jint ordinal) {
|
||||
Engine::Builder* builder = (Engine::Builder*) nativeBuilder;
|
||||
builder->featureLevel((Engine::FeatureLevel)ordinal);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_Engine_nSetBuilderSharedContext(
|
||||
JNIEnv*, jclass, jlong nativeBuilder, jlong sharedContext) {
|
||||
Engine::Builder* builder = (Engine::Builder*) nativeBuilder;
|
||||
builder->sharedContext((void*) sharedContext);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_Engine_nBuilderBuild(JNIEnv*, jclass, jlong nativeBuilder) {
|
||||
Engine::Builder* builder = (Engine::Builder*) nativeBuilder;
|
||||
return (jlong) builder->build();
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ Java_com_google_android_filament_EntityManager_nCreateArray(JNIEnv* env, jclass,
|
||||
// (which it is), but still.
|
||||
em->create((size_t) n, reinterpret_cast<Entity *>(entities));
|
||||
|
||||
env->ReleaseIntArrayElements(entities_, entities, 0);
|
||||
env->ReleaseIntArrayElements(entities_, entities, JNI_ABORT);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
|
||||
@@ -79,7 +79,8 @@ Java_com_google_android_filament_LightManager_nBuilderShadowOptions(JNIEnv* env,
|
||||
jfloat shadowFarHint, jboolean stable, jboolean lispsm,
|
||||
jfloat polygonOffsetConstant, jfloat polygonOffsetSlope,
|
||||
jboolean screenSpaceContactShadows, jint stepCount,
|
||||
jfloat maxShadowDistance, jboolean elvsm, jfloat blurWidth, jfloat shadowBulbRadius) {
|
||||
jfloat maxShadowDistance, jboolean elvsm, jfloat blurWidth, jfloat shadowBulbRadius,
|
||||
jfloatArray transform) {
|
||||
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
|
||||
LightManager::ShadowOptions shadowOptions {
|
||||
.mapSize = (uint32_t)mapSize,
|
||||
@@ -102,12 +103,18 @@ Java_com_google_android_filament_LightManager_nBuilderShadowOptions(JNIEnv* env,
|
||||
},
|
||||
.shadowBulbRadius = shadowBulbRadius
|
||||
};
|
||||
|
||||
jfloat *nativeSplits = env->GetFloatArrayElements(splitPositions, NULL);
|
||||
const jsize splitCount = std::min((jsize) 3, env->GetArrayLength(splitPositions));
|
||||
for (jsize i = 0; i < splitCount; i++) {
|
||||
shadowOptions.cascadeSplitPositions[i] = nativeSplits[i];
|
||||
}
|
||||
std::copy_n(nativeSplits, splitCount, shadowOptions.cascadeSplitPositions);
|
||||
env->ReleaseFloatArrayElements(splitPositions, nativeSplits, 0);
|
||||
|
||||
jfloat* nativeTransform = env->GetFloatArrayElements(transform, NULL);
|
||||
std::copy_n(nativeTransform,
|
||||
std::min(4, env->GetArrayLength(transform)),
|
||||
shadowOptions.transform.xyzw.v);
|
||||
env->ReleaseFloatArrayElements(transform, nativeTransform, 0);
|
||||
|
||||
builder->shadowOptions(shadowOptions);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <filament/Material.h>
|
||||
|
||||
#include "common/NioUtils.h"
|
||||
#include "common/CallbackUtils.h"
|
||||
|
||||
using namespace filament;
|
||||
|
||||
@@ -105,6 +106,22 @@ Java_com_google_android_filament_Material_nGetRefractionType(JNIEnv*, jclass,
|
||||
return (jint) material->getRefractionType();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Material_nGetReflectionMode(JNIEnv*, jclass,
|
||||
jlong nativeMaterial) {
|
||||
Material* material = (Material*) nativeMaterial;
|
||||
return (jint) material->getReflectionMode();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Material_nGetFeatureLevel(JNIEnv*, jclass,
|
||||
jlong nativeMaterial) {
|
||||
Material* material = (Material*) nativeMaterial;
|
||||
return (jint) material->getFeatureLevel();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Material_nGetVertexDomain(JNIEnv*, jclass,
|
||||
@@ -255,3 +272,17 @@ Java_com_google_android_filament_Material_nHasParameter(JNIEnv* env, jclass,
|
||||
env->ReleaseStringUTFChars(name_, name);
|
||||
return (jboolean) hasParameter;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_Material_nCompile(JNIEnv *env, jclass clazz,
|
||||
jlong nativeMaterial, jint priority, jint variants, jobject handler, jobject runnable) {
|
||||
Material* material = (Material*) nativeMaterial;
|
||||
JniCallback* jniCallback = JniCallback::make(env, handler, runnable);
|
||||
material->compile(
|
||||
(Material::CompilerPriorityQueue) priority,
|
||||
(UserVariantFilterBit) variants,
|
||||
jniCallback->getHandler(), [jniCallback](Material*){
|
||||
JniCallback::postToJavaAndDestroy(jniCallback);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -205,7 +205,7 @@ Java_com_google_android_filament_MaterialInstance_nSetIntParameterArray(JNIEnv *
|
||||
break;
|
||||
}
|
||||
|
||||
env->ReleaseIntArrayElements(v_, v, 0);
|
||||
env->ReleaseIntArrayElements(v_, v, JNI_ABORT);
|
||||
|
||||
env->ReleaseStringUTFChars(name_, name);
|
||||
}
|
||||
@@ -246,17 +246,21 @@ Java_com_google_android_filament_MaterialInstance_nSetFloatParameterArray(JNIEnv
|
||||
env->ReleaseStringUTFChars(name_, name);
|
||||
}
|
||||
|
||||
// defined in TextureSampler.cpp
|
||||
namespace filament::JniUtils {
|
||||
TextureSampler from_long(jlong params) noexcept;
|
||||
} // TextureSamplerJniUtils
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nSetParameterTexture(
|
||||
JNIEnv *env, jclass, jlong nativeMaterialInstance, jstring name_,
|
||||
jlong nativeTexture, jint sampler_) {
|
||||
jlong nativeTexture, jlong sampler_) {
|
||||
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
|
||||
Texture* texture = (Texture*) nativeTexture;
|
||||
TextureSampler& sampler = reinterpret_cast<TextureSampler&>(sampler_);
|
||||
|
||||
const char *name = env->GetStringUTFChars(name_, 0);
|
||||
instance->setParameter(name, texture, sampler);
|
||||
instance->setParameter(name, texture, JniUtils::from_long(sampler_));
|
||||
env->ReleaseStringUTFChars(name_, name);
|
||||
}
|
||||
|
||||
@@ -357,6 +361,14 @@ Java_com_google_android_filament_MaterialInstance_nSetDepthCulling(JNIEnv*,
|
||||
instance->setDepthCulling(enable);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nSetDepthFunc(JNIEnv*,
|
||||
jclass, jlong nativeMaterialInstance, jlong function) {
|
||||
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
|
||||
instance->setDepthFunc(static_cast<MaterialInstance::DepthFunc>(function));
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nSetStencilCompareFunction(JNIEnv*, jclass,
|
||||
@@ -524,3 +536,11 @@ Java_com_google_android_filament_MaterialInstance_nIsDepthCullingEnabled(JNIEnv*
|
||||
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
|
||||
return instance->isDepthCullingEnabled();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nGetDepthFunc(JNIEnv* env, jclass clazz,
|
||||
jlong nativeMaterialInstance) {
|
||||
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
|
||||
return (jint)instance->getDepthFunc();
|
||||
}
|
||||
|
||||
@@ -201,12 +201,19 @@ Java_com_google_android_filament_RenderableManager_nBuilderSkinning(JNIEnv*, jcl
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nEnableSkinningBuffers(JNIEnv*, jclass,
|
||||
Java_com_google_android_filament_RenderableManager_nBuilderEnableSkinningBuffers(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jboolean enabled) {
|
||||
RenderableManager::Builder *builder = (RenderableManager::Builder *) nativeBuilder;
|
||||
builder->enableSkinningBuffers(enabled);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nBuilderFog(JNIEnv*, jclass,
|
||||
jlong nativeBuilder, jboolean enabled) {
|
||||
RenderableManager::Builder *builder = (RenderableManager::Builder *) nativeBuilder;
|
||||
builder->fog(enabled);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nBuilderSkinningBones(JNIEnv* env, jclass,
|
||||
jlong nativeBuilder, jint boneCount, jobject bones, jint remaining) {
|
||||
@@ -360,6 +367,20 @@ Java_com_google_android_filament_RenderableManager_nSetCulling(JNIEnv*, jclass,
|
||||
rm->setCulling((RenderableManager::Instance) i, enabled);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nSetFogEnabled(JNIEnv*, jclass,
|
||||
jlong nativeRenderableManager, jint i, jboolean enabled) {
|
||||
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
|
||||
rm->setFogEnabled((RenderableManager::Instance) i, enabled);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nGetFogEnabled(JNIEnv*, jclass,
|
||||
jlong nativeRenderableManager, jint i) {
|
||||
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
|
||||
return (jboolean)rm->getFogEnabled((RenderableManager::Instance) i);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_RenderableManager_nSetCastShadows(JNIEnv*, jclass,
|
||||
jlong nativeRenderableManager, jint i, jboolean enabled) {
|
||||
|
||||
@@ -71,6 +71,13 @@ Java_com_google_android_filament_Scene_nRemoveEntities(JNIEnv *env, jclass type,
|
||||
env->ReleaseIntArrayElements(entities, (jint*) nativeEntities, JNI_ABORT);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Scene_nGetEntityCount(JNIEnv *env, jclass type,
|
||||
jlong nativeScene) {
|
||||
Scene* scene = (Scene*) nativeScene;
|
||||
return (jint) scene->getEntityCount();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_Scene_nGetRenderableCount(JNIEnv *env, jclass type,
|
||||
jlong nativeScene) {
|
||||
@@ -91,3 +98,22 @@ Java_com_google_android_filament_Scene_nHasEntity(JNIEnv *env, jclass type, jlon
|
||||
Entity entity = Entity::import(entityId);
|
||||
return (jboolean) scene->hasEntity(entity);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_Scene_nGetEntities(JNIEnv *env, jclass ,
|
||||
jlong nativeScene, jintArray outArray, jint length) {
|
||||
Scene const* const scene = (Scene*) nativeScene;
|
||||
if (length < scene->getEntityCount()) {
|
||||
// should not happen because we already checked on the java side
|
||||
return JNI_FALSE;
|
||||
}
|
||||
jint *out = (jint *) env->GetIntArrayElements(outArray, nullptr);
|
||||
scene->forEach([out, length, i = 0](Entity entity)mutable {
|
||||
if (i < length) { // this is just paranoia here
|
||||
out[i++] = (jint) entity.getId();
|
||||
}
|
||||
});
|
||||
env->ReleaseIntArrayElements(outArray, (jint*) out, 0);
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
@@ -27,11 +27,10 @@ extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_SwapChain_nSetFrameCompletedCallback(JNIEnv* env, jclass,
|
||||
jlong nativeSwapChain, jobject handler, jobject runnable) {
|
||||
SwapChain* swapChain = (SwapChain*) nativeSwapChain;
|
||||
auto *callback = JniCallback::make(env, handler, runnable);
|
||||
swapChain->setFrameCompletedCallback([](void* user) {
|
||||
JniCallback* callback = (JniCallback*)user;
|
||||
auto* callback = JniCallback::make(env, handler, runnable);
|
||||
swapChain->setFrameCompletedCallback(nullptr, [callback](SwapChain* swapChain) {
|
||||
JniCallback::postToJavaAndDestroy(callback);
|
||||
}, callback);
|
||||
});
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
|
||||
@@ -511,9 +511,7 @@ public:
|
||||
|
||||
private:
|
||||
void* mData = nullptr;
|
||||
jobject mBitmap = nullptr;
|
||||
jobject mHandler = nullptr;
|
||||
jobject mCallback = nullptr;
|
||||
jobject mBitmap{};
|
||||
AndroidBitmapInfo mInfo{};
|
||||
};
|
||||
|
||||
|
||||
@@ -18,142 +18,139 @@
|
||||
|
||||
#include <filament/TextureSampler.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
|
||||
using namespace filament;
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_TextureSampler_nCreateSampler(JNIEnv *env, jclass type, jint min,
|
||||
namespace filament::JniUtils {
|
||||
|
||||
jlong to_long(TextureSampler const& sampler) noexcept {
|
||||
return jlong(utils::bit_cast<uint32_t>(sampler.getSamplerParams()));
|
||||
}
|
||||
|
||||
TextureSampler from_long(jlong params) noexcept {
|
||||
return TextureSampler{
|
||||
utils::bit_cast<backend::SamplerParams>(
|
||||
static_cast<uint32_t>(params))};
|
||||
}
|
||||
|
||||
} // namespace filament::JniUtils
|
||||
|
||||
using namespace JniUtils;
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_TextureSampler_nCreateSampler(JNIEnv *, jclass, jint min,
|
||||
jint max, jint s, jint t, jint r) {
|
||||
return TextureSampler(static_cast<TextureSampler::MinFilter>(min),
|
||||
static_cast<TextureSampler::MagFilter>(max), static_cast<TextureSampler::WrapMode>(s),
|
||||
static_cast<TextureSampler::WrapMode>(t),
|
||||
static_cast<TextureSampler::WrapMode>(r)).getSamplerParams().u;
|
||||
TextureSampler sampler(static_cast<TextureSampler::MinFilter>(min),
|
||||
static_cast<TextureSampler::MagFilter>(max),
|
||||
static_cast<TextureSampler::WrapMode>(s),
|
||||
static_cast<TextureSampler::WrapMode>(t),
|
||||
static_cast<TextureSampler::WrapMode>(r));
|
||||
return to_long(sampler);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_TextureSampler_nCreateCompareSampler(JNIEnv *env, jclass type,
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_TextureSampler_nCreateCompareSampler(JNIEnv *, jclass,
|
||||
jint mode, jint function) {
|
||||
return TextureSampler(static_cast<TextureSampler::CompareMode>(mode),
|
||||
static_cast<TextureSampler::CompareFunc>(function)).getSamplerParams().u;
|
||||
TextureSampler sampler(static_cast<TextureSampler::CompareMode>(mode),
|
||||
static_cast<TextureSampler::CompareFunc>(function));
|
||||
return to_long(sampler);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_TextureSampler_nGetMinFilter(JNIEnv *env, jclass type,
|
||||
jint sampler_) {
|
||||
TextureSampler &sampler = reinterpret_cast<TextureSampler &>(sampler_);
|
||||
return static_cast<jint>(sampler.getMinFilter());
|
||||
Java_com_google_android_filament_TextureSampler_nGetMinFilter(JNIEnv *, jclass, jlong sampler) {
|
||||
return static_cast<jint>(from_long(sampler).getMinFilter());
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_TextureSampler_nSetMinFilter(JNIEnv *env, jclass type,
|
||||
jint sampler_, jint filter) {
|
||||
TextureSampler &sampler = reinterpret_cast<TextureSampler &>(sampler_);
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_TextureSampler_nSetMinFilter(JNIEnv *, jclass, jlong sampler_, jint filter) {
|
||||
TextureSampler sampler{from_long(sampler_)};
|
||||
sampler.setMinFilter(static_cast<TextureSampler::MinFilter>(filter));
|
||||
return sampler.getSamplerParams().u;
|
||||
return to_long(sampler);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_TextureSampler_nGetMagFilter(JNIEnv *env, jclass type,
|
||||
jint sampler_) {
|
||||
TextureSampler &sampler = reinterpret_cast<TextureSampler &>(sampler_);
|
||||
return static_cast<jint>(sampler.getMagFilter());
|
||||
Java_com_google_android_filament_TextureSampler_nGetMagFilter(JNIEnv *, jclass, jlong sampler) {
|
||||
return static_cast<jint>(from_long(sampler).getMagFilter());
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_TextureSampler_nSetMagFilter(JNIEnv *env, jclass type,
|
||||
jint sampler_, jint filter) {
|
||||
TextureSampler &sampler = reinterpret_cast<TextureSampler &>(sampler_);
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_TextureSampler_nSetMagFilter(JNIEnv *, jclass, jlong sampler_, jint filter) {
|
||||
TextureSampler sampler{from_long(sampler_)};
|
||||
sampler.setMagFilter(static_cast<TextureSampler::MagFilter>(filter));
|
||||
return sampler.getSamplerParams().u;
|
||||
return to_long(sampler);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_TextureSampler_nGetWrapModeS(JNIEnv *env, jclass type,
|
||||
jint sampler_) {
|
||||
TextureSampler &sampler = reinterpret_cast<TextureSampler &>(sampler_);
|
||||
return static_cast<jint>(sampler.getWrapModeS());
|
||||
Java_com_google_android_filament_TextureSampler_nGetWrapModeS(JNIEnv *, jclass, jlong sampler) {
|
||||
return static_cast<jint>(from_long(sampler).getWrapModeS());
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_TextureSampler_nSetWrapModeS(JNIEnv *env, jclass type,
|
||||
jint sampler_, jint mode) {
|
||||
TextureSampler &sampler = reinterpret_cast<TextureSampler &>(sampler_);
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_TextureSampler_nSetWrapModeS(JNIEnv *, jclass, jlong sampler_, jint mode) {
|
||||
TextureSampler sampler{from_long(sampler_)};
|
||||
sampler.setWrapModeS(static_cast<TextureSampler::WrapMode>(mode));
|
||||
return sampler.getSamplerParams().u;
|
||||
return to_long(sampler);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_TextureSampler_nGetWrapModeT(JNIEnv *env, jclass type,
|
||||
jint sampler_) {
|
||||
TextureSampler &sampler = reinterpret_cast<TextureSampler &>(sampler_);
|
||||
return static_cast<jint>(sampler.getWrapModeT());
|
||||
Java_com_google_android_filament_TextureSampler_nGetWrapModeT(JNIEnv *, jclass, jlong sampler) {
|
||||
return static_cast<jint>(from_long(sampler).getWrapModeT());
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_TextureSampler_nSetWrapModeT(JNIEnv *env, jclass type,
|
||||
jint sampler_, jint mode) {
|
||||
TextureSampler &sampler = reinterpret_cast<TextureSampler &>(sampler_);
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_TextureSampler_nSetWrapModeT(JNIEnv *, jclass, jlong sampler_, jint mode) {
|
||||
TextureSampler sampler{from_long(sampler_)};
|
||||
sampler.setWrapModeT(static_cast<TextureSampler::WrapMode>(mode));
|
||||
return sampler.getSamplerParams().u;
|
||||
return to_long(sampler);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_TextureSampler_nGetWrapModeR(JNIEnv *env, jclass type,
|
||||
jint sampler_) {
|
||||
TextureSampler &sampler = reinterpret_cast<TextureSampler &>(sampler_);
|
||||
return static_cast<jint>(sampler.getWrapModeR());
|
||||
Java_com_google_android_filament_TextureSampler_nGetWrapModeR(JNIEnv *, jclass, jlong sampler) {
|
||||
return static_cast<jint>(from_long(sampler).getWrapModeR());
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_TextureSampler_nSetWrapModeR(JNIEnv *env, jclass type,
|
||||
jint sampler_, jint mode) {
|
||||
TextureSampler &sampler = reinterpret_cast<TextureSampler &>(sampler_);
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_TextureSampler_nSetWrapModeR(JNIEnv *, jclass, jlong sampler_, jint mode) {
|
||||
TextureSampler sampler{from_long(sampler_)};
|
||||
sampler.setWrapModeR(static_cast<TextureSampler::WrapMode>(mode));
|
||||
return sampler.getSamplerParams().u;
|
||||
return to_long(sampler);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_TextureSampler_nGetCompareMode(JNIEnv *env, jclass type,
|
||||
jint sampler_) {
|
||||
TextureSampler &sampler = reinterpret_cast<TextureSampler &>(sampler_);
|
||||
return static_cast<jint>(sampler.getCompareMode());
|
||||
Java_com_google_android_filament_TextureSampler_nGetCompareMode(JNIEnv *, jclass, jlong sampler) {
|
||||
return static_cast<jint>(from_long(sampler).getCompareMode());
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_TextureSampler_nSetCompareMode(JNIEnv *env, jclass type,
|
||||
jint sampler_, jint mode) {
|
||||
TextureSampler &sampler = reinterpret_cast<TextureSampler &>(sampler_);
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_TextureSampler_nSetCompareMode(JNIEnv *, jclass, jlong sampler_, jint mode) {
|
||||
TextureSampler sampler{from_long(sampler_)};
|
||||
sampler.setCompareMode(static_cast<TextureSampler::CompareMode>(mode),
|
||||
sampler.getCompareFunc());
|
||||
return sampler.getSamplerParams().u;
|
||||
return to_long(sampler);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_TextureSampler_nGetCompareFunction(JNIEnv *env, jclass type,
|
||||
jint sampler_) {
|
||||
TextureSampler &sampler = reinterpret_cast<TextureSampler &>(sampler_);
|
||||
return static_cast<jint>(sampler.getCompareFunc());
|
||||
Java_com_google_android_filament_TextureSampler_nGetCompareFunction(JNIEnv *, jclass, jlong sampler) {
|
||||
return static_cast<jint>(from_long(sampler).getCompareFunc());
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_TextureSampler_nSetCompareFunction(JNIEnv *env, jclass type,
|
||||
jint sampler_, jint function) {
|
||||
TextureSampler &sampler = reinterpret_cast<TextureSampler &>(sampler_);
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_TextureSampler_nSetCompareFunction(JNIEnv *, jclass, jlong sampler_, jint function) {
|
||||
TextureSampler sampler{from_long(sampler_)};
|
||||
sampler.setCompareMode(sampler.getCompareMode(),
|
||||
static_cast<TextureSampler::CompareFunc>(function));
|
||||
return sampler.getSamplerParams().u;
|
||||
return to_long(sampler);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jfloat JNICALL
|
||||
Java_com_google_android_filament_TextureSampler_nGetAnisotropy(JNIEnv *env, jclass type,
|
||||
jint sampler_) {
|
||||
TextureSampler &sampler = reinterpret_cast<TextureSampler &>(sampler_);
|
||||
return sampler.getAnisotropy();
|
||||
Java_com_google_android_filament_TextureSampler_nGetAnisotropy(JNIEnv *, jclass, jlong sampler) {
|
||||
return from_long(sampler).getAnisotropy();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_TextureSampler_nSetAnisotropy(JNIEnv *env, jclass type,
|
||||
jint sampler_, jfloat anisotropy) {
|
||||
TextureSampler &sampler = reinterpret_cast<TextureSampler &>(sampler_);
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_TextureSampler_nSetAnisotropy(JNIEnv *, jclass, jlong sampler_, jfloat anisotropy) {
|
||||
TextureSampler sampler{from_long(sampler_)};
|
||||
sampler.setAnisotropy(anisotropy);
|
||||
return sampler.getSamplerParams().u;
|
||||
return to_long(sampler);
|
||||
}
|
||||
|
||||
@@ -47,6 +47,11 @@ Java_com_google_android_filament_ToneMapper_nCreateFilmicToneMapper(JNIEnv*, jcl
|
||||
return (jlong) new FilmicToneMapper();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nCreateAgxToneMapper(JNIEnv*, jclass, jint look) {
|
||||
return (jlong) new AgxToneMapper(AgxToneMapper::AgxLook(look));
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_com_google_android_filament_ToneMapper_nCreateGenericToneMapper(JNIEnv*, jclass,
|
||||
jfloat contrast, jfloat midGrayIn, jfloat midGrayOut, jfloat hdrMax) {
|
||||
|
||||
@@ -282,7 +282,7 @@ Java_com_google_android_filament_View_nSetSSCTOptions(JNIEnv *, jclass, jlong na
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetBloomOptions(JNIEnv*, jclass,
|
||||
jlong nativeView, jlong nativeTexture,
|
||||
jfloat dirtStrength, jfloat strength, jint resolution, jfloat anamorphism, jint levels,
|
||||
jfloat dirtStrength, jfloat strength, jint resolution, jint levels,
|
||||
jint blendMode, jboolean threshold, jboolean enabled, jfloat highlight,
|
||||
jboolean lensFlare, jboolean starburst, jfloat chromaticAberration, jint ghostCount,
|
||||
jfloat ghostSpacing, jfloat ghostThreshold, jfloat haloThickness, jfloat haloRadius,
|
||||
@@ -294,7 +294,6 @@ Java_com_google_android_filament_View_nSetBloomOptions(JNIEnv*, jclass,
|
||||
.dirtStrength = dirtStrength,
|
||||
.strength = strength,
|
||||
.resolution = (uint32_t)resolution,
|
||||
.anamorphism = anamorphism,
|
||||
.levels = (uint8_t)levels,
|
||||
.blendMode = (View::BloomOptions::BlendMode)blendMode,
|
||||
.threshold = (bool)threshold,
|
||||
@@ -315,12 +314,14 @@ Java_com_google_android_filament_View_nSetBloomOptions(JNIEnv*, jclass,
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetFogOptions(JNIEnv *, jclass , jlong nativeView,
|
||||
jfloat distance, jfloat maximumOpacity, jfloat height, jfloat heightFalloff, jfloat r,
|
||||
jfloat g, jfloat b, jfloat density, jfloat inScatteringStart,
|
||||
jfloat inScatteringSize, jboolean fogColorFromIbl, jboolean enabled) {
|
||||
jfloat distance, jfloat maximumOpacity, jfloat height, jfloat heightFalloff, jfloat cutOffDistance,
|
||||
jfloat r, jfloat g, jfloat b, jfloat density, jfloat inScatteringStart,
|
||||
jfloat inScatteringSize, jboolean fogColorFromIbl, jlong skyColorNativeObject, jboolean enabled) {
|
||||
View* view = (View*) nativeView;
|
||||
Texture* skyColor = (Texture*) skyColorNativeObject;
|
||||
View::FogOptions options = {
|
||||
.distance = distance,
|
||||
.cutOffDistance = cutOffDistance,
|
||||
.maximumOpacity = maximumOpacity,
|
||||
.height = height,
|
||||
.heightFalloff = heightFalloff,
|
||||
@@ -329,6 +330,7 @@ Java_com_google_android_filament_View_nSetFogOptions(JNIEnv *, jclass , jlong na
|
||||
.inScatteringStart = inScatteringStart,
|
||||
.inScatteringSize = inScatteringSize,
|
||||
.fogColorFromIbl = (bool)fogColorFromIbl,
|
||||
.skyColor = skyColor,
|
||||
.enabled = (bool)enabled
|
||||
};
|
||||
view->setFogOptions(options);
|
||||
@@ -478,6 +480,17 @@ Java_com_google_android_filament_View_nIsStencilBufferEnabled(JNIEnv *, jclass,
|
||||
return view->isStencilBufferEnabled();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetStereoscopicOptions(JNIEnv *, jclass, jlong nativeView,
|
||||
jboolean enabled) {
|
||||
View* view = (View*) nativeView;
|
||||
View::StereoscopicOptions options {
|
||||
.enabled = (bool) enabled
|
||||
};
|
||||
view->setStereoscopicOptions(options);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetGuardBandOptions(JNIEnv *, jclass,
|
||||
@@ -485,3 +498,30 @@ Java_com_google_android_filament_View_nSetGuardBandOptions(JNIEnv *, jclass,
|
||||
View* view = (View*) nativeView;
|
||||
view->setGuardBandOptions({ .enabled = (bool)enabled });
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nSetMaterialGlobal(JNIEnv * , jclass, jlong nativeView,
|
||||
jint index, jfloat x, jfloat y, jfloat z, jfloat w) {
|
||||
View *view = (View *) nativeView;
|
||||
view->setMaterialGlobal((uint32_t)index, { x, y, z, w });
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_View_nGetMaterialGlobal(JNIEnv *env, jclass clazz,
|
||||
jlong nativeView, jint index, jfloatArray out_) {
|
||||
jfloat* out = env->GetFloatArrayElements(out_, nullptr);
|
||||
View *view = (View *) nativeView;
|
||||
auto result = view->getMaterialGlobal(index);
|
||||
std::copy_n(result.v, 4, out);
|
||||
env->ReleaseFloatArrayElements(out_, out, 0);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT int JNICALL
|
||||
Java_com_google_android_filament_View_nGetFogEntity(JNIEnv *env, jclass clazz,
|
||||
jlong nativeView) {
|
||||
View *view = (View *) nativeView;
|
||||
return (jint)view->getFogEntity().getId();
|
||||
}
|
||||
|
||||
@@ -118,6 +118,7 @@ public class ColorGrading {
|
||||
*
|
||||
* @deprecated Use {@link ColorGrading.Builder#toneMapper(ToneMapper)}
|
||||
*/
|
||||
@Deprecated
|
||||
public enum ToneMapping {
|
||||
/** Linear tone mapping (i.e. no tone mapping). */
|
||||
LINEAR,
|
||||
@@ -231,6 +232,7 @@ public class ColorGrading {
|
||||
*
|
||||
* @deprecated Use {@link #toneMapper(ToneMapper)}
|
||||
*/
|
||||
@Deprecated
|
||||
public Builder toneMapping(ToneMapping toneMapping) {
|
||||
nBuilderToneMapping(mNativeBuilder, toneMapping.ordinal());
|
||||
return this;
|
||||
|
||||
@@ -111,6 +111,8 @@ public class Engine {
|
||||
|
||||
private long mNativeObject;
|
||||
|
||||
private Config mConfig;
|
||||
|
||||
@NonNull private final TransformManager mTransformManager;
|
||||
@NonNull private final LightManager mLightManager;
|
||||
@NonNull private final RenderableManager mRenderableManager;
|
||||
@@ -150,16 +152,219 @@ public class Engine {
|
||||
FEATURE_LEVEL_0,
|
||||
/** OpenGL ES 3.0 features (default) */
|
||||
FEATURE_LEVEL_1,
|
||||
/** OpenGL ES 3.1 features + 16 textures units + cubemap arrays */
|
||||
FEATURE_LEVEL_2,
|
||||
/** OpenGL ES 3.1 features + 31 textures units + cubemap arrays */
|
||||
FEATURE_LEVEL_2
|
||||
FEATURE_LEVEL_3,
|
||||
};
|
||||
|
||||
private Engine(long nativeEngine) {
|
||||
/**
|
||||
* Constructs <code>Engine</code> objects using a builder pattern.
|
||||
*/
|
||||
public static class Builder {
|
||||
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
|
||||
private final BuilderFinalizer mFinalizer;
|
||||
private final long mNativeBuilder;
|
||||
private Config mConfig;
|
||||
|
||||
public Builder() {
|
||||
mNativeBuilder = nCreateBuilder();
|
||||
mFinalizer = new BuilderFinalizer(mNativeBuilder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link Backend} for the Engine.
|
||||
*
|
||||
* @param backend Driver backend to use
|
||||
* @return A reference to this Builder for chaining calls.
|
||||
*/
|
||||
public Builder backend(Backend backend) {
|
||||
nSetBuilderBackend(mNativeBuilder, backend.ordinal());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a sharedContext for the Engine.
|
||||
*
|
||||
* @param sharedContext A platform-dependant OpenGL context used as a shared context
|
||||
* when creating filament's internal context. On Android this parameter
|
||||
* <b>must be</b> an instance of {@link android.opengl.EGLContext}.
|
||||
* @return A reference to this Builder for chaining calls.
|
||||
*/
|
||||
public Builder sharedContext(Object sharedContext) {
|
||||
if (Platform.get().validateSharedContext(sharedContext)) {
|
||||
nSetBuilderSharedContext(mNativeBuilder,
|
||||
Platform.get().getSharedContextNativeHandle(sharedContext));
|
||||
return this;
|
||||
}
|
||||
throw new IllegalArgumentException("Invalid shared context " + sharedContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the Engine with custom parameters.
|
||||
*
|
||||
* @param config A {@link Config} object
|
||||
* @return A reference to this Builder for chaining calls.
|
||||
*/
|
||||
public Builder config(Config config) {
|
||||
mConfig = config;
|
||||
nSetBuilderConfig(mNativeBuilder, config.commandBufferSizeMB,
|
||||
config.perRenderPassArenaSizeMB, config.driverHandleArenaSizeMB,
|
||||
config.minCommandBufferSizeMB, config.perFrameCommandsSizeMB,
|
||||
config.jobSystemThreadCount, config.stereoscopicEyeCount);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the initial featureLevel for the Engine.
|
||||
*
|
||||
* @param featureLevel The feature level at which initialize Filament.
|
||||
* @return A reference to this Builder for chaining calls.
|
||||
*/
|
||||
public Builder featureLevel(FeatureLevel featureLevel) {
|
||||
nSetBuilderFeatureLevel(mNativeBuilder, featureLevel.ordinal());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of Engine
|
||||
*
|
||||
* @return A newly created <code>Engine</code>, or <code>null</code> if the GPU driver couldn't
|
||||
* be initialized, for instance if it doesn't support the right version of OpenGL or
|
||||
* OpenGL ES.
|
||||
*
|
||||
* @exception IllegalStateException can be thrown if there isn't enough memory to
|
||||
* allocate the command buffer.
|
||||
*/
|
||||
public Engine build() {
|
||||
long nativeEngine = nBuilderBuild(mNativeBuilder);
|
||||
if (nativeEngine == 0) throw new IllegalStateException("Couldn't create Engine");
|
||||
return new Engine(nativeEngine, mConfig);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters for customizing the initialization of {@link Engine}.
|
||||
*/
|
||||
public static class Config {
|
||||
|
||||
// #defines in Engine.h
|
||||
private static final long FILAMENT_PER_RENDER_PASS_ARENA_SIZE_IN_MB = 3;
|
||||
private static final long FILAMENT_PER_FRAME_COMMANDS_SIZE_IN_MB = 2;
|
||||
private static final long FILAMENT_MIN_COMMAND_BUFFERS_SIZE_IN_MB = 1;
|
||||
private static final long FILAMENT_COMMAND_BUFFER_SIZE_IN_MB =
|
||||
FILAMENT_MIN_COMMAND_BUFFERS_SIZE_IN_MB * 3;
|
||||
|
||||
/**
|
||||
* Size in MiB of the low-level command buffer arena.
|
||||
*
|
||||
* Each new command buffer is allocated from here. If this buffer is too small the program
|
||||
* might terminate or rendering errors might occur.
|
||||
*
|
||||
* This is typically set to minCommandBufferSizeMB * 3, so that up to 3 frames can be
|
||||
* batched-up at once.
|
||||
*
|
||||
* This value affects the application's memory usage.
|
||||
*/
|
||||
public long commandBufferSizeMB = FILAMENT_COMMAND_BUFFER_SIZE_IN_MB;
|
||||
|
||||
/**
|
||||
* Size in MiB of the per-frame data arena.
|
||||
*
|
||||
* This is the main arena used for allocations when preparing a frame.
|
||||
* e.g.: Froxel data and high-level commands are allocated from this arena.
|
||||
*
|
||||
* If this size is too small, the program will abort on debug builds and have undefined
|
||||
* behavior otherwise.
|
||||
*
|
||||
* This value affects the application's memory usage.
|
||||
*/
|
||||
public long perRenderPassArenaSizeMB = FILAMENT_PER_RENDER_PASS_ARENA_SIZE_IN_MB;
|
||||
|
||||
/**
|
||||
* Size in MiB of the backend's handle arena.
|
||||
*
|
||||
* Backends will fallback to slower heap-based allocations when running out of space and
|
||||
* log this condition.
|
||||
*
|
||||
* If 0, then the default value for the given platform is used
|
||||
*
|
||||
* This value affects the application's memory usage.
|
||||
*/
|
||||
public long driverHandleArenaSizeMB = 0;
|
||||
|
||||
/**
|
||||
* Minimum size in MiB of a low-level command buffer.
|
||||
*
|
||||
* This is how much space is guaranteed to be available for low-level commands when a new
|
||||
* buffer is allocated. If this is too small, the engine might have to stall to wait for
|
||||
* more space to become available, this situation is logged.
|
||||
*
|
||||
* This value does not affect the application's memory usage.
|
||||
*/
|
||||
public long minCommandBufferSizeMB = FILAMENT_MIN_COMMAND_BUFFERS_SIZE_IN_MB;
|
||||
|
||||
/**
|
||||
* Size in MiB of the per-frame high level command buffer.
|
||||
*
|
||||
* This buffer is related to the number of draw calls achievable within a frame, if it is
|
||||
* too small, the program will abort on debug builds and have undefined behavior otherwise.
|
||||
*
|
||||
* It is allocated from the 'per-render-pass arena' above. Make sure that at least 1 MiB is
|
||||
* left in the per-render-pass arena when deciding the size of this buffer.
|
||||
*
|
||||
* This value does not affect the application's memory usage.
|
||||
*/
|
||||
public long perFrameCommandsSizeMB = FILAMENT_PER_FRAME_COMMANDS_SIZE_IN_MB;
|
||||
|
||||
/**
|
||||
* Number of threads to use in Engine's JobSystem.
|
||||
*
|
||||
* Engine uses a utils::JobSystem to carry out paralleization of Engine workloads. This
|
||||
* value sets the number of threads allocated for JobSystem. Configuring this value can be
|
||||
* helpful in CPU-constrained environments where too many threads can cause contention of
|
||||
* CPU and reduce performance.
|
||||
*
|
||||
* The default value is 0, which implies that the Engine will use a heuristic to determine
|
||||
* the number of threads to use.
|
||||
*/
|
||||
public long jobSystemThreadCount = 0;
|
||||
|
||||
/**
|
||||
* The number of eyes to render when stereoscopic rendering is enabled. Supported values are
|
||||
* between 1 and Engine#getMaxStereoscopicEyes() (inclusive).
|
||||
*
|
||||
* @see View#setStereoscopicOptions
|
||||
* @see Engine#getMaxStereoscopicEyes
|
||||
*/
|
||||
public long stereoscopicEyeCount = 2;
|
||||
}
|
||||
|
||||
private Engine(long nativeEngine, Config config) {
|
||||
mNativeObject = nativeEngine;
|
||||
mTransformManager = new TransformManager(nGetTransformManager(nativeEngine));
|
||||
mLightManager = new LightManager(nGetLightManager(nativeEngine));
|
||||
mRenderableManager = new RenderableManager(nGetRenderableManager(nativeEngine));
|
||||
mEntityManager = new EntityManager(nGetEntityManager(nativeEngine));
|
||||
mConfig = config;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -177,9 +382,7 @@ public class Engine {
|
||||
*/
|
||||
@NonNull
|
||||
public static Engine create() {
|
||||
long nativeEngine = nCreateEngine(0, 0);
|
||||
if (nativeEngine == 0) throw new IllegalStateException("Couldn't create Engine");
|
||||
return new Engine(nativeEngine);
|
||||
return new Builder().build();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -199,9 +402,9 @@ public class Engine {
|
||||
*/
|
||||
@NonNull
|
||||
public static Engine create(@NonNull Backend backend) {
|
||||
long nativeEngine = nCreateEngine(backend.ordinal(), 0);
|
||||
if (nativeEngine == 0) throw new IllegalStateException("Couldn't create Engine");
|
||||
return new Engine(nativeEngine);
|
||||
return new Builder()
|
||||
.backend(backend)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -223,13 +426,9 @@ public class Engine {
|
||||
*/
|
||||
@NonNull
|
||||
public static Engine create(@NonNull Object sharedContext) {
|
||||
if (Platform.get().validateSharedContext(sharedContext)) {
|
||||
long nativeEngine = nCreateEngine(0,
|
||||
Platform.get().getSharedContextNativeHandle(sharedContext));
|
||||
if (nativeEngine == 0) throw new IllegalStateException("Couldn't create Engine");
|
||||
return new Engine(nativeEngine);
|
||||
}
|
||||
throw new IllegalArgumentException("Invalid shared context " + sharedContext);
|
||||
return new Builder()
|
||||
.sharedContext(sharedContext)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -296,17 +495,23 @@ public class Engine {
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate all features of a given feature level. By default FeatureLevel::FEATURE_LEVEL_1 is
|
||||
* active. The selected feature level must not be higher than the value returned by
|
||||
* getActiveFeatureLevel() and it's not possible lower the active feature level.
|
||||
* Activate all features of a given feature level. If an explicit feature level is not specified
|
||||
* at Engine initialization time via {@link Builder#featureLevel}, the default feature level is
|
||||
* {@link FeatureLevel#FEATURE_LEVEL_0} on devices not compatible with GLES 3.0; otherwise, the
|
||||
* default is {@link FeatureLevel::FEATURE_LEVEL_1}. The selected feature level must not be
|
||||
* higher than the value returned by {@link #getActiveFeatureLevel} and it's not possible lower
|
||||
* the active feature level. Additionally, it is not possible to modify the feature level at all
|
||||
* if the Engine was initialized at {@link FeatureLevel#FEATURE_LEVEL_0}.
|
||||
*
|
||||
* @param featureLevel the feature level to activate. If featureLevel is lower than
|
||||
* getActiveFeatureLevel(), the current (higher) feature level is kept.
|
||||
* If featureLevel is higher than getSupportedFeatureLevel(), an exception
|
||||
* is thrown, or the program is terminated if exceptions are disabled.
|
||||
* @param featureLevel the feature level to activate. If featureLevel is lower than {@link
|
||||
* #getActiveFeatureLevel}, the current (higher) feature level is kept. If
|
||||
* featureLevel is higher than {@link #getSupportedFeatureLevel}, or if the
|
||||
* engine was initialized at feature level 0, an exception is thrown, or the
|
||||
* program is terminated if exceptions are disabled.
|
||||
*
|
||||
* @return the active feature level.
|
||||
*
|
||||
* @see Builder#featureLevel
|
||||
* @see #getSupportedFeatureLevel
|
||||
* @see #getActiveFeatureLevel
|
||||
*/
|
||||
@@ -352,6 +557,37 @@ public class Engine {
|
||||
return nIsAutomaticInstancingEnabled(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the configuration settings of this {@link Engine}.
|
||||
*
|
||||
* This method returns the configuration object that was supplied to the Engine's {@link
|
||||
* Builder#config} method during the creation of this Engine. If the {@link Builder::config}
|
||||
* method was not explicitly called (or called with null), this method returns the default
|
||||
* configuration settings.
|
||||
*
|
||||
* @return a {@link Config} object with this Engine's configuration
|
||||
* @see Builder#config
|
||||
*/
|
||||
@NonNull
|
||||
public Config getConfig() {
|
||||
if (mConfig == null) {
|
||||
mConfig = new Config();
|
||||
}
|
||||
return mConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum number of stereoscopic eyes supported by Filament. The actual number of
|
||||
* eyes rendered is set at Engine creation time with the {@link
|
||||
* Engine#Config#stereoscopicEyeCount} setting.
|
||||
*
|
||||
* @return the max number of stereoscopic eyes supported
|
||||
* @see Engine#Config#stereoscopicEyeCount
|
||||
*/
|
||||
public long getMaxStereoscopicEyes() {
|
||||
return nGetMaxStereoscopicEyes(getNativeObject());
|
||||
}
|
||||
|
||||
|
||||
// SwapChain
|
||||
|
||||
@@ -449,6 +685,141 @@ public class Engine {
|
||||
swapChain.clearNativeObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the object is valid.
|
||||
* @param object Object to check for validity
|
||||
* @return returns true if the specified object is valid.
|
||||
*/
|
||||
public boolean isValidRenderer(@NonNull Renderer object) {
|
||||
return nIsValidRenderer(getNativeObject(), object.getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the object is valid.
|
||||
* @param object Object to check for validity
|
||||
* @return returns true if the specified object is valid.
|
||||
*/
|
||||
public boolean isValidView(@NonNull View object) {
|
||||
return nIsValidView(getNativeObject(), object.getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the object is valid.
|
||||
* @param object Object to check for validity
|
||||
* @return returns true if the specified object is valid.
|
||||
*/
|
||||
public boolean isValidScene(@NonNull Scene object) {
|
||||
return nIsValidScene(getNativeObject(), object.getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the object is valid.
|
||||
* @param object Object to check for validity
|
||||
* @return returns true if the specified object is valid.
|
||||
*/
|
||||
public boolean isValidFence(@NonNull Fence object) {
|
||||
return nIsValidFence(getNativeObject(), object.getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the object is valid.
|
||||
* @param object Object to check for validity
|
||||
* @return returns true if the specified object is valid.
|
||||
*/
|
||||
public boolean isValidStream(@NonNull Stream object) {
|
||||
return nIsValidStream(getNativeObject(), object.getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the object is valid.
|
||||
* @param object Object to check for validity
|
||||
* @return returns true if the specified object is valid.
|
||||
*/
|
||||
public boolean isValidIndexBuffer(@NonNull IndexBuffer object) {
|
||||
return nIsValidIndexBuffer(getNativeObject(), object.getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the object is valid.
|
||||
* @param object Object to check for validity
|
||||
* @return returns true if the specified object is valid.
|
||||
*/
|
||||
public boolean isValidVertexBuffer(@NonNull VertexBuffer object) {
|
||||
return nIsValidVertexBuffer(getNativeObject(), object.getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the object is valid.
|
||||
* @param object Object to check for validity
|
||||
* @return returns true if the specified object is valid.
|
||||
*/
|
||||
public boolean isValidSkinningBuffer(@NonNull SkinningBuffer object) {
|
||||
return nIsValidSkinningBuffer(getNativeObject(), object.getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the object is valid.
|
||||
* @param object Object to check for validity
|
||||
* @return returns true if the specified object is valid.
|
||||
*/
|
||||
public boolean isValidIndirectLight(@NonNull IndirectLight object) {
|
||||
return nIsValidIndirectLight(getNativeObject(), object.getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the object is valid.
|
||||
* @param object Object to check for validity
|
||||
* @return returns true if the specified object is valid.
|
||||
*/
|
||||
public boolean isValidMaterial(@NonNull Material object) {
|
||||
return nIsValidMaterial(getNativeObject(), object.getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the object is valid.
|
||||
* @param object Object to check for validity
|
||||
* @return returns true if the specified object is valid.
|
||||
*/
|
||||
public boolean isValidSkybox(@NonNull Skybox object) {
|
||||
return nIsValidSkybox(getNativeObject(), object.getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the object is valid.
|
||||
* @param object Object to check for validity
|
||||
* @return returns true if the specified object is valid.
|
||||
*/
|
||||
public boolean isValidColorGrading(@NonNull ColorGrading object) {
|
||||
return nIsValidColorGrading(getNativeObject(), object.getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the object is valid.
|
||||
* @param object Object to check for validity
|
||||
* @return returns true if the specified object is valid.
|
||||
*/
|
||||
public boolean isValidTexture(@NonNull Texture object) {
|
||||
return nIsValidTexture(getNativeObject(), object.getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the object is valid.
|
||||
* @param object Object to check for validity
|
||||
* @return returns true if the specified object is valid.
|
||||
*/
|
||||
public boolean isValidRenderTarget(@NonNull RenderTarget object) {
|
||||
return nIsValidRenderTarget(getNativeObject(), object.getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the object is valid.
|
||||
* @param object Object to check for validity
|
||||
* @return returns true if the specified object is valid.
|
||||
*/
|
||||
public boolean isValidSwapChain(@NonNull SwapChain object) {
|
||||
return nIsValidSwapChain(getNativeObject(), object.getNativeObject());
|
||||
}
|
||||
|
||||
// View
|
||||
|
||||
/**
|
||||
@@ -753,6 +1124,18 @@ public class Engine {
|
||||
nFlushAndWait(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Kicks the hardware thread (e.g. the OpenGL, Vulkan or Metal thread) but does not wait
|
||||
* for commands to be either executed or the hardware finished.
|
||||
*
|
||||
* <p>This is typically used after creating a lot of objects to start draining the command
|
||||
* queue which has a limited size.</p>
|
||||
*/
|
||||
public void flush() {
|
||||
nFlush(getNativeObject());
|
||||
}
|
||||
|
||||
|
||||
@UsedByReflection("TextureHelper.java")
|
||||
public long getNativeObject() {
|
||||
if (mNativeObject == 0) {
|
||||
@@ -779,23 +1162,22 @@ public class Engine {
|
||||
}
|
||||
}
|
||||
|
||||
private static native long nCreateEngine(long backend, long sharedContext);
|
||||
private static native void nDestroyEngine(long nativeEngine);
|
||||
private static native long nGetBackend(long nativeEngine);
|
||||
private static native long nCreateSwapChain(long nativeEngine, Object nativeWindow, long flags);
|
||||
private static native long nCreateSwapChainHeadless(long nativeEngine, int width, int height, long flags);
|
||||
private static native long nCreateSwapChainFromRawPointer(long nativeEngine, long pointer, long flags);
|
||||
private static native boolean nDestroySwapChain(long nativeEngine, long nativeSwapChain);
|
||||
private static native long nCreateView(long nativeEngine);
|
||||
private static native boolean nDestroyView(long nativeEngine, long nativeView);
|
||||
private static native long nCreateRenderer(long nativeEngine);
|
||||
private static native boolean nDestroyRenderer(long nativeEngine, long nativeRenderer);
|
||||
private static native long nCreateCamera(long nativeEngine, int entity);
|
||||
private static native long nGetCameraComponent(long nativeEngine, int entity);
|
||||
private static native void nDestroyCameraComponent(long nativeEngine, int entity);
|
||||
private static native long nCreateScene(long nativeEngine);
|
||||
private static native boolean nDestroyScene(long nativeEngine, long nativeScene);
|
||||
private static native long nCreateFence(long nativeEngine);
|
||||
|
||||
private static native boolean nDestroyRenderer(long nativeEngine, long nativeRenderer);
|
||||
private static native boolean nDestroyView(long nativeEngine, long nativeView);
|
||||
private static native boolean nDestroyScene(long nativeEngine, long nativeScene);
|
||||
private static native boolean nDestroyFence(long nativeEngine, long nativeFence);
|
||||
private static native boolean nDestroyStream(long nativeEngine, long nativeStream);
|
||||
private static native boolean nDestroyIndexBuffer(long nativeEngine, long nativeIndexBuffer);
|
||||
@@ -808,8 +1190,25 @@ public class Engine {
|
||||
private static native boolean nDestroyColorGrading(long nativeEngine, long nativeColorGrading);
|
||||
private static native boolean nDestroyTexture(long nativeEngine, long nativeTexture);
|
||||
private static native boolean nDestroyRenderTarget(long nativeEngine, long nativeTarget);
|
||||
private static native boolean nDestroySwapChain(long nativeEngine, long nativeSwapChain);
|
||||
private static native boolean nIsValidRenderer(long nativeEngine, long nativeRenderer);
|
||||
private static native boolean nIsValidView(long nativeEngine, long nativeView);
|
||||
private static native boolean nIsValidScene(long nativeEngine, long nativeScene);
|
||||
private static native boolean nIsValidFence(long nativeEngine, long nativeFence);
|
||||
private static native boolean nIsValidStream(long nativeEngine, long nativeStream);
|
||||
private static native boolean nIsValidIndexBuffer(long nativeEngine, long nativeIndexBuffer);
|
||||
private static native boolean nIsValidVertexBuffer(long nativeEngine, long nativeVertexBuffer);
|
||||
private static native boolean nIsValidSkinningBuffer(long nativeEngine, long nativeSkinningBuffer);
|
||||
private static native boolean nIsValidIndirectLight(long nativeEngine, long nativeIndirectLight);
|
||||
private static native boolean nIsValidMaterial(long nativeEngine, long nativeMaterial);
|
||||
private static native boolean nIsValidSkybox(long nativeEngine, long nativeSkybox);
|
||||
private static native boolean nIsValidColorGrading(long nativeEngine, long nativeColorGrading);
|
||||
private static native boolean nIsValidTexture(long nativeEngine, long nativeTexture);
|
||||
private static native boolean nIsValidRenderTarget(long nativeEngine, long nativeTarget);
|
||||
private static native boolean nIsValidSwapChain(long nativeEngine, long nativeSwapChain);
|
||||
private static native void nDestroyEntity(long nativeEngine, int entity);
|
||||
private static native void nFlushAndWait(long nativeEngine);
|
||||
private static native void nFlush(long nativeEngine);
|
||||
private static native long nGetTransformManager(long nativeEngine);
|
||||
private static native long nGetLightManager(long nativeEngine);
|
||||
private static native long nGetRenderableManager(long nativeEngine);
|
||||
@@ -817,7 +1216,19 @@ public class Engine {
|
||||
private static native long nGetEntityManager(long nativeEngine);
|
||||
private static native void nSetAutomaticInstancingEnabled(long nativeEngine, boolean enable);
|
||||
private static native boolean nIsAutomaticInstancingEnabled(long nativeEngine);
|
||||
private static native long nGetMaxStereoscopicEyes(long nativeEngine);
|
||||
private static native int nGetSupportedFeatureLevel(long nativeEngine);
|
||||
private static native int nSetActiveFeatureLevel(long nativeEngine, int ordinal);
|
||||
private static native int nGetActiveFeatureLevel(long nativeEngine);
|
||||
|
||||
private static native long nCreateBuilder();
|
||||
private static native void nDestroyBuilder(long nativeBuilder);
|
||||
private static native void nSetBuilderBackend(long nativeBuilder, long backend);
|
||||
private static native void nSetBuilderConfig(long nativeBuilder, long commandBufferSizeMB,
|
||||
long perRenderPassArenaSizeMB, long driverHandleArenaSizeMB,
|
||||
long minCommandBufferSizeMB, long perFrameCommandsSizeMB, long jobSystemThreadCount,
|
||||
long stereoscopicEyeCount);
|
||||
private static native void nSetBuilderFeatureLevel(long nativeBuilder, int ordinal);
|
||||
private static native void nSetBuilderSharedContext(long nativeBuilder, long sharedContext);
|
||||
private static native long nBuilderBuild(long nativeBuilder);
|
||||
}
|
||||
|
||||
@@ -258,6 +258,7 @@ public class LightManager {
|
||||
* shadows that are too far and wouldn't contribute to the scene much, improving
|
||||
* performance and quality. This value is always positive.
|
||||
* Use 0.0f to use the camera far distance.
|
||||
* This only affect directional lights.
|
||||
*/
|
||||
public float shadowFar = 0.0f;
|
||||
|
||||
@@ -368,6 +369,17 @@ public class LightManager {
|
||||
* enabled. (2cm by default).
|
||||
*/
|
||||
public float shadowBulbRadius = 0.02f;
|
||||
|
||||
/**
|
||||
* Transforms the shadow direction. Must be a unit quaternion.
|
||||
* The default is identity.
|
||||
* Ignored if the light type isn't directional. For artistic use. Use with caution.
|
||||
* The quaternion is stored as the imaginary part in the first 3 elements and the real
|
||||
* part in the last element of the transform array.
|
||||
*/
|
||||
@NonNull
|
||||
@Size(min = 4, max = 4)
|
||||
public float[] transform = { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
}
|
||||
|
||||
public static class ShadowCascades {
|
||||
@@ -506,7 +518,7 @@ public class LightManager {
|
||||
options.polygonOffsetConstant, options.polygonOffsetSlope,
|
||||
options.screenSpaceContactShadows,
|
||||
options.stepCount, options.maxShadowDistance,
|
||||
options.elvsm, options.blurWidth, options.shadowBulbRadius);
|
||||
options.elvsm, options.blurWidth, options.shadowBulbRadius, options.transform);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -1169,7 +1181,7 @@ public class LightManager {
|
||||
boolean stable, boolean lispsm,
|
||||
float polygonOffsetConstant, float polygonOffsetSlope,
|
||||
boolean screenSpaceContactShadows, int stepCount, float maxShadowDistance,
|
||||
boolean elvsm, float blurWidth, float shadowBulbRadius);
|
||||
boolean elvsm, float blurWidth, float shadowBulbRadius, float[] transform);
|
||||
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);
|
||||
|
||||
@@ -18,9 +18,11 @@ package com.google.android.filament;
|
||||
|
||||
import androidx.annotation.IntRange;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.Size;
|
||||
|
||||
import com.google.android.filament.proguard.UsedByNative;
|
||||
import com.google.android.filament.Engine.FeatureLevel;
|
||||
|
||||
import java.nio.Buffer;
|
||||
import java.util.ArrayList;
|
||||
@@ -46,6 +48,8 @@ public class Material {
|
||||
static final BlendingMode[] sBlendingModeValues = BlendingMode.values();
|
||||
static final RefractionMode[] sRefractionModeValues = RefractionMode.values();
|
||||
static final RefractionType[] sRefractionTypeValues = RefractionType.values();
|
||||
static final ReflectionMode[] sReflectionModeValues = ReflectionMode.values();
|
||||
static final FeatureLevel[] sFeatureLevelValues = FeatureLevel.values();
|
||||
static final VertexDomain[] sVertexDomainValues = VertexDomain.values();
|
||||
static final CullingMode[] sCullingModeValues = CullingMode.values();
|
||||
static final VertexBuffer.VertexAttribute[] sVertexAttributeValues =
|
||||
@@ -181,6 +185,18 @@ public class Material {
|
||||
THIN
|
||||
}
|
||||
|
||||
/**
|
||||
* Supported reflection modes
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/lighting:reflections">
|
||||
* Lighting: reflections</a>
|
||||
*/
|
||||
public enum ReflectionMode {
|
||||
DEFAULT,
|
||||
SCREEN_SPACE
|
||||
}
|
||||
|
||||
/**
|
||||
* Supported types of vertex domains
|
||||
*
|
||||
@@ -223,6 +239,31 @@ public class Material {
|
||||
FRONT_AND_BACK
|
||||
}
|
||||
|
||||
public enum CompilerPriorityQueue {
|
||||
HIGH,
|
||||
LOW
|
||||
}
|
||||
|
||||
public static class UserVariantFilterBit {
|
||||
/** Directional lighting */
|
||||
public static int DIRECTIONAL_LIGHTING = 0x01;
|
||||
/** Dynamic lighting */
|
||||
public static int DYNAMIC_LIGHTING = 0x02;
|
||||
/** Shadow receiver */
|
||||
public static int SHADOW_RECEIVER = 0x04;
|
||||
/** Skinning */
|
||||
public static int SKINNING = 0x08;
|
||||
/** Fog */
|
||||
public static int FOG = 0x10;
|
||||
/** Variance shadow maps */
|
||||
public static int VSM = 0x20;
|
||||
/** Screen-space reflections */
|
||||
public static int SSR = 0x40;
|
||||
/** Instanced stereo rendering */
|
||||
public static int STE = 0x80;
|
||||
public static int ALL = 0xFF;
|
||||
}
|
||||
|
||||
@UsedByNative("Material.cpp")
|
||||
public static class Parameter {
|
||||
private static final Type[] sTypeValues = Type.values();
|
||||
@@ -337,6 +378,55 @@ public class Material {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Asynchronously ensures that a subset of this Material's variants are compiled. After issuing
|
||||
* several compile() calls in a row, it is recommended to call {@link Engine#flush}
|
||||
* such that the backend can start the compilation work as soon as possible.
|
||||
* The provided callback is guaranteed to be called on the main thread after all specified
|
||||
* variants of the material are compiled. This can take hundreds of milliseconds.
|
||||
*<p>
|
||||
* If all the material's variants are already compiled, the callback will be scheduled as
|
||||
* soon as possible, but this might take a few dozen millisecond, corresponding to how
|
||||
* many previous frames are enqueued in the backend. This also varies by backend. Therefore,
|
||||
* it is recommended to only call this method once per material shortly after creation.
|
||||
*</p>
|
||||
*<p>
|
||||
* If the same variant is scheduled for compilation multiple times, the first scheduling
|
||||
* takes precedence; later scheduling are ignored.
|
||||
*</p>
|
||||
*<p>
|
||||
* caveat: A consequence is that if a variant is scheduled on the low priority queue and later
|
||||
* scheduled again on the high priority queue, the later scheduling is ignored.
|
||||
* Therefore, the second callback could be called before the variant is compiled.
|
||||
* However, the first callback, if specified, will trigger as expected.
|
||||
*</p>
|
||||
*<p>
|
||||
* The callback is guaranteed to be called. If the engine is destroyed while some material
|
||||
* variants are still compiling or in the queue, these will be discarded and the corresponding
|
||||
* callback will be called. In that case however the Material pointer passed to the callback
|
||||
* is guaranteed to be invalid (either because it's been destroyed by the user already, or,
|
||||
* because it's been cleaned-up by the Engine).
|
||||
*</p>
|
||||
*<p>
|
||||
* {@link UserVariantFilterBit#ALL} should be used with caution. Only variants that an application
|
||||
* needs should be included in the variants argument. For example, the STE variant is only used
|
||||
* for stereoscopic rendering. If an application is not planning to render in stereo, this bit
|
||||
* should be turned off to avoid unnecessary material compilations.
|
||||
*</p>
|
||||
* @param priority Which priority queue to use, LOW or HIGH.
|
||||
* @param variants Variants to include to the compile command.
|
||||
* @param handler An {@link java.util.concurrent.Executor Executor}. On Android this can also be a {@link android.os.Handler Handler}.
|
||||
* @param callback callback called on the main thread when the compilation is done on
|
||||
* by backend.
|
||||
*/
|
||||
public void compile(@NonNull CompilerPriorityQueue priority,
|
||||
int variants,
|
||||
@Nullable Object handler,
|
||||
@Nullable Runnable callback) {
|
||||
nCompile(getNativeObject(), priority.ordinal(), variants, handler, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of this material. Material instances should be freed using
|
||||
* {@link Engine#destroyMaterialInstance(MaterialInstance)}.
|
||||
@@ -437,6 +527,28 @@ public class Material {
|
||||
return EnumCache.sRefractionTypeValues[nGetRefractionType(getNativeObject())];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the reflection mode of this material.
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/lighting:reflections">
|
||||
* Lighting: reflections</a>
|
||||
*/
|
||||
public ReflectionMode getReflectionMode() {
|
||||
return EnumCache.sReflectionModeValues[nGetReflectionMode(getNativeObject())];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the minimum required feature level for this material.
|
||||
*
|
||||
* @see
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/general:featurelevel">
|
||||
* General: featureLevel</a>
|
||||
*/
|
||||
public FeatureLevel getFeatureLevel() {
|
||||
return EnumCache.sFeatureLevelValues[nGetFeatureLevel(getNativeObject())];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the vertex domain of this material.
|
||||
*
|
||||
@@ -916,6 +1028,7 @@ public class Material {
|
||||
private static native long nCreateInstanceWithName(long nativeMaterial, @NonNull String name);
|
||||
private static native long nGetDefaultInstance(long nativeMaterial);
|
||||
|
||||
private static native void nCompile(long nativeMaterial, int priority, int variants, Object handler, Runnable runnable);
|
||||
private static native String nGetName(long nativeMaterial);
|
||||
private static native int nGetShading(long nativeMaterial);
|
||||
private static native int nGetInterpolation(long nativeMaterial);
|
||||
@@ -932,6 +1045,8 @@ public class Material {
|
||||
private static native float nGetSpecularAntiAliasingThreshold(long nativeMaterial);
|
||||
private static native int nGetRefractionMode(long nativeMaterial);
|
||||
private static native int nGetRefractionType(long nativeMaterial);
|
||||
private static native int nGetReflectionMode(long nativeMaterial);
|
||||
private static native int nGetFeatureLevel(long nativeMaterial);
|
||||
|
||||
|
||||
private static native int nGetParameterCount(long nativeMaterial);
|
||||
|
||||
@@ -625,6 +625,15 @@ public class MaterialInstance {
|
||||
nSetDepthCulling(getNativeObject(), enable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the depth comparison function (default is {@link TextureSampler.CompareFunction#GE}).
|
||||
*
|
||||
* @param func the depth comparison function
|
||||
*/
|
||||
public void setDepthFunc(TextureSampler.CompareFunction func) {
|
||||
nSetDepthFunc(getNativeObject(), func.ordinal());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether depth culling is enabled.
|
||||
*/
|
||||
@@ -632,6 +641,13 @@ public class MaterialInstance {
|
||||
return nIsDepthCullingEnabled(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the depth comparison function.
|
||||
*/
|
||||
public TextureSampler.CompareFunction getDepthFunc() {
|
||||
return TextureSampler.EnumCache.sCompareFunctionValues[nGetDepthFunc(getNativeObject())];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the stencil comparison function (default is {@link TextureSampler.CompareFunction#ALWAYS}).
|
||||
*
|
||||
@@ -884,7 +900,7 @@ public class MaterialInstance {
|
||||
@IntRange(from = 0) int offset, @IntRange(from = 1) int count);
|
||||
|
||||
private static native void nSetParameterTexture(long nativeMaterialInstance,
|
||||
@NonNull String name, long nativeTexture, int sampler);
|
||||
@NonNull String name, long nativeTexture, long sampler);
|
||||
|
||||
private static native void nSetScissor(long nativeMaterialInstance,
|
||||
@IntRange(from = 0) int left, @IntRange(from = 0) int bottom,
|
||||
@@ -908,6 +924,7 @@ public class MaterialInstance {
|
||||
private static native void nSetDepthWrite(long nativeMaterialInstance, boolean enable);
|
||||
private static native void nSetStencilWrite(long nativeMaterialInstance, boolean enable);
|
||||
private static native void nSetDepthCulling(long nativeMaterialInstance, boolean enable);
|
||||
private static native void nSetDepthFunc(long nativeMaterialInstance, long function);
|
||||
|
||||
private static native void nSetStencilCompareFunction(long nativeMaterialInstance,
|
||||
long function, long face);
|
||||
@@ -939,4 +956,5 @@ public class MaterialInstance {
|
||||
private static native boolean nIsDepthWriteEnabled(long nativeMaterialInstance);
|
||||
private static native boolean nIsStencilWriteEnabled(long nativeMaterialInstance);
|
||||
private static native boolean nIsDepthCullingEnabled(long nativeMaterialInstance);
|
||||
private static native int nGetDepthFunc(long nativeMaterialInstance);
|
||||
}
|
||||
|
||||
@@ -81,8 +81,6 @@ public class RenderTarget {
|
||||
/**
|
||||
* Sets a texture to a given attachment point.
|
||||
*
|
||||
* <p>All RenderTargets must have a non-null <code>COLOR</code> attachment.</p>
|
||||
*
|
||||
* @param attachment The attachment point of the texture.
|
||||
* @param texture The associated texture object.
|
||||
* @return A reference to this Builder for chaining calls.
|
||||
|
||||
@@ -356,16 +356,16 @@ public class RenderableManager {
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* the maximum number of instances allowed is 32767. 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.
|
||||
* @param instanceCount the number of instances silently clamped between 1 and 32767.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder instances(@IntRange(from = 1, to = 65535) int instanceCount) {
|
||||
public Builder instances(@IntRange(from = 1, to = 32767) int instanceCount) {
|
||||
nBuilderInstances(mNativeBuilder, instanceCount);
|
||||
return this;
|
||||
}
|
||||
@@ -417,7 +417,19 @@ public class RenderableManager {
|
||||
*/
|
||||
@NonNull
|
||||
public Builder enableSkinningBuffers(boolean enabled) {
|
||||
nEnableSkinningBuffers(mNativeBuilder, enabled);
|
||||
nBuilderEnableSkinningBuffers(mNativeBuilder, enabled);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls if this renderable is affected by the large-scale fog.
|
||||
* @param enabled If true, enables large-scale fog on this object. Disables it otherwise.
|
||||
* True by default.
|
||||
* @return this <code>Builder</code> object for chaining calls
|
||||
*/
|
||||
@NonNull
|
||||
public Builder fog(boolean enabled) {
|
||||
nBuilderFog(mNativeBuilder, enabled);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -729,6 +741,23 @@ public class RenderableManager {
|
||||
nSetCulling(mNativeObject, i, enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes whether or not the large-scale fog is applied to this renderable
|
||||
* @see Builder#fog
|
||||
*/
|
||||
public void setFogEnabled(@EntityInstance int i, boolean enabled) {
|
||||
nSetFogEnabled(mNativeObject, i, enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether large-scale fog is enabled for this renderable.
|
||||
* @return True if fog is enabled for this renderable.
|
||||
* @see Builder#fog
|
||||
*/
|
||||
public boolean getFogEnabled(@EntityInstance int i) {
|
||||
return nGetFogEnabled(mNativeObject, i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables a light channel.
|
||||
* Light channel 0 is enabled by default.
|
||||
@@ -951,7 +980,8 @@ public class RenderableManager {
|
||||
private static native void nBuilderSkinningBuffer(long nativeBuilder, long nativeSkinningBuffer, int boneCount, int offset);
|
||||
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 nBuilderEnableSkinningBuffers(long nativeBuilder, boolean enabled);
|
||||
private static native void nBuilderFog(long nativeBuilder, boolean enabled);
|
||||
private static native void nBuilderLightChannel(long nativeRenderableManager, int channel, boolean enable);
|
||||
private static native void nBuilderInstances(long nativeRenderableManager, int instances);
|
||||
|
||||
@@ -966,6 +996,8 @@ public class RenderableManager {
|
||||
private static native void nSetPriority(long nativeRenderableManager, int i, int priority);
|
||||
private static native void nSetChannel(long nativeRenderableManager, int i, int channel);
|
||||
private static native void nSetCulling(long nativeRenderableManager, int i, boolean enabled);
|
||||
private static native void nSetFogEnabled(long nativeRenderableManager, int i, boolean enabled);
|
||||
private static native boolean nGetFogEnabled(long nativeRenderableManager, int i);
|
||||
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);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.google.android.filament;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
/**
|
||||
@@ -146,18 +147,29 @@ public class Scene {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of {@link RenderableManager} components in the <code>Scene</code>.
|
||||
* Returns the total number of Entities in the <code>Scene</code>, whether alive or not.
|
||||
*
|
||||
* @return number of {@link RenderableManager} components in the <code>Scene</code>..
|
||||
* @return the total number of Entities in the <code>Scene</code>.
|
||||
*/
|
||||
public int getEntityCount() {
|
||||
return nGetEntityCount(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of active (alive) {@link RenderableManager} components in the
|
||||
* <code>Scene</code>.
|
||||
*
|
||||
* @return number of {@link RenderableManager} components in the <code>Scene</code>.
|
||||
*/
|
||||
public int getRenderableCount() {
|
||||
return nGetRenderableCount(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of {@link LightManager} components in the <code>Scene</code>.
|
||||
* Returns the number of active (alive) {@link LightManager} components in the
|
||||
* <code>Scene</code>.
|
||||
*
|
||||
* @return number of {@link LightManager} components in the <code>Scene</code>..
|
||||
* @return number of {@link LightManager} components in the <code>Scene</code>.
|
||||
*/
|
||||
public int getLightCount() {
|
||||
return nGetLightCount(getNativeObject());
|
||||
@@ -179,6 +191,52 @@ public class Scene {
|
||||
return mNativeObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of all entities in the Scene. If outArray is provided and large enough,
|
||||
* it is used to store the list and returned, otherwise a new array is allocated and returned.
|
||||
* @param outArray an array to store the list of entities in the scene.
|
||||
* @return outArray if it was used or a newly allocated array.
|
||||
* @see #getEntityCount
|
||||
*/
|
||||
public int[] getEntities(@Nullable int[] outArray) {
|
||||
int c = getEntityCount();
|
||||
if (outArray == null || outArray.length < c) {
|
||||
outArray = new int[c];
|
||||
}
|
||||
boolean success = nGetEntities(getNativeObject(), outArray, outArray.length);
|
||||
if (!success) {
|
||||
throw new IllegalStateException("Error retriving Scene's entities");
|
||||
}
|
||||
return outArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of all entities in the Scene in a newly allocated array.
|
||||
* @return an array containing the list of all entities in the scene.
|
||||
* @see #getEntityCount
|
||||
*/
|
||||
public int[] getEntities() {
|
||||
return getEntities(null);
|
||||
}
|
||||
|
||||
public interface EntityProcessor {
|
||||
void process(@Entity int entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes user functor on each entity in the scene.
|
||||
*
|
||||
* It is not allowed to add or remove an entity from the scene within the functor.
|
||||
*
|
||||
* @param entityProcessor User provided functor called for each entity in the scene
|
||||
*/
|
||||
public void forEach(@NonNull EntityProcessor entityProcessor) {
|
||||
int[] entities = getEntities(null);
|
||||
for (int entity : entities) {
|
||||
entityProcessor.process(entity);
|
||||
}
|
||||
}
|
||||
|
||||
void clearNativeObject() {
|
||||
mNativeObject = 0;
|
||||
}
|
||||
@@ -189,7 +247,9 @@ public class Scene {
|
||||
private static native void nAddEntities(long nativeScene, int[] entities);
|
||||
private static native void nRemove(long nativeScene, int entity);
|
||||
private static native void nRemoveEntities(long nativeScene, int[] entities);
|
||||
private static native int nGetEntityCount(long nativeScene);
|
||||
private static native int nGetRenderableCount(long nativeScene);
|
||||
private static native int nGetLightCount(long nativeScene);
|
||||
private static native boolean nHasEntity(long nativeScene, int entity);
|
||||
private static native boolean nGetEntities(long nativeScene, int[] outArray, int length);
|
||||
}
|
||||
|
||||
@@ -103,6 +103,31 @@ public class SwapChain {
|
||||
*/
|
||||
public static final long CONFIG_SRGB_COLORSPACE = 0x10;
|
||||
|
||||
/**
|
||||
* Indicates that this SwapChain should allocate a stencil buffer in addition to a depth buffer.
|
||||
*
|
||||
* This flag is necessary when using View::setStencilBufferEnabled and rendering directly into
|
||||
* the SwapChain (when post-processing is disabled).
|
||||
*
|
||||
* The specific format of the stencil buffer depends on platform support. The following pixel
|
||||
* formats are tried, in order of preference:
|
||||
*
|
||||
* Depth only (without CONFIG_HAS_STENCIL_BUFFER):
|
||||
* - DEPTH32F
|
||||
* - DEPTH24
|
||||
*
|
||||
* Depth + stencil (with CONFIG_HAS_STENCIL_BUFFER):
|
||||
* - DEPTH32F_STENCIL8
|
||||
* - DEPTH24F_STENCIL8
|
||||
*
|
||||
* Note that enabling the stencil buffer may hinder depth precision and should only be used if
|
||||
* necessary.
|
||||
*
|
||||
* @see View#setStencilBufferEnabled
|
||||
* @see View#setPostProcessingEnabled
|
||||
*/
|
||||
public static final long CONFIG_HAS_STENCIL_BUFFER = 0x20;
|
||||
|
||||
SwapChain(long nativeSwapChain, Object surface) {
|
||||
mNativeObject = nativeSwapChain;
|
||||
mSurface = surface;
|
||||
@@ -137,10 +162,6 @@ public class SwapChain {
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* The FrameCompletedCallback is guaranteed to be called on the main Filament thread.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Warning: Only Filament's Metal backend supports frame callbacks. Other backends ignore the
|
||||
* callback (which will never be called) and proceed normally.
|
||||
* </p>
|
||||
|
||||
@@ -849,6 +849,10 @@ public class Texture {
|
||||
public static final int SAMPLEABLE = 0x10;
|
||||
/** Texture can be used as a subpass input */
|
||||
public static final int SUBPASS_INPUT = 0x20;
|
||||
/** Texture can be used the source of a blit() */
|
||||
public static final int BLIT_SRC = 0x40;
|
||||
/** Texture can be used the destination of a blit() */
|
||||
public static final int BLIT_DST = 0x80;
|
||||
/** by default textures are <code>UPLOADABLE</code> and <code>SAMPLEABLE</code>*/
|
||||
public static final int DEFAULT = UPLOADABLE | SAMPLEABLE;
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ public class TextureSampler {
|
||||
NEVER
|
||||
}
|
||||
|
||||
int mSampler = 0; // bit field used by native
|
||||
long mSampler = 0; // bit field used by native
|
||||
|
||||
/**
|
||||
* Initializes the <code>TextureSampler</code> with default values.
|
||||
@@ -342,26 +342,26 @@ public class TextureSampler {
|
||||
}
|
||||
}
|
||||
|
||||
private static native int nCreateSampler(int min, int max, int s, int t, int r);
|
||||
private static native int nCreateCompareSampler(int mode, int function);
|
||||
private static native long nCreateSampler(int min, int max, int s, int t, int r);
|
||||
private static native long nCreateCompareSampler(int mode, int function);
|
||||
|
||||
private static native int nGetMinFilter(int sampler);
|
||||
private static native int nSetMinFilter(int sampler, int filter);
|
||||
private static native int nGetMagFilter(int sampler);
|
||||
private static native int nSetMagFilter(int sampler, int filter);
|
||||
private static native int nGetMinFilter(long sampler);
|
||||
private static native long nSetMinFilter(long sampler, int filter);
|
||||
private static native int nGetMagFilter(long sampler);
|
||||
private static native long nSetMagFilter(long sampler, int filter);
|
||||
|
||||
private static native int nGetWrapModeS(int sampler);
|
||||
private static native int nSetWrapModeS(int sampler, int mode);
|
||||
private static native int nGetWrapModeT(int sampler);
|
||||
private static native int nSetWrapModeT(int sampler, int mode);
|
||||
private static native int nGetWrapModeR(int sampler);
|
||||
private static native int nSetWrapModeR(int sampler, int mode);
|
||||
private static native int nGetWrapModeS(long sampler);
|
||||
private static native long nSetWrapModeS(long sampler, int mode);
|
||||
private static native int nGetWrapModeT(long sampler);
|
||||
private static native long nSetWrapModeT(long sampler, int mode);
|
||||
private static native int nGetWrapModeR(long sampler);
|
||||
private static native long nSetWrapModeR(long sampler, int mode);
|
||||
|
||||
private static native int nGetCompareMode(int sampler);
|
||||
private static native int nSetCompareMode(int sampler, int mode);
|
||||
private static native int nGetCompareFunction(int sampler);
|
||||
private static native int nSetCompareFunction(int sampler, int function);
|
||||
private static native int nGetCompareMode(long sampler);
|
||||
private static native long nSetCompareMode(long sampler, int mode);
|
||||
private static native int nGetCompareFunction(long sampler);
|
||||
private static native long nSetCompareFunction(long sampler, int function);
|
||||
|
||||
private static native float nGetAnisotropy(int sampler);
|
||||
private static native int nSetAnisotropy(int sampler, float anisotropy);
|
||||
private static native float nGetAnisotropy(long sampler);
|
||||
private static native long nSetAnisotropy(long sampler, float anisotropy);
|
||||
}
|
||||
|
||||
@@ -100,6 +100,45 @@ public class ToneMapper {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AgX tone mapping operator.
|
||||
*/
|
||||
public static class Agx extends ToneMapper {
|
||||
|
||||
public enum AgxLook {
|
||||
/**
|
||||
* Base contrast with no look applied
|
||||
*/
|
||||
NONE,
|
||||
|
||||
/**
|
||||
* A punchy and more chroma laden look for sRGB displays
|
||||
*/
|
||||
PUNCHY,
|
||||
|
||||
/**
|
||||
* A golden tinted, slightly washed look for BT.1886 displays
|
||||
*/
|
||||
GOLDEN
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a new AgX tone mapper with no look applied.
|
||||
*/
|
||||
public Agx() {
|
||||
this(AgxLook.NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a new AgX tone mapper.
|
||||
*
|
||||
* @param look: an optional creative adjustment to contrast and saturation
|
||||
*/
|
||||
public Agx(AgxLook look) {
|
||||
super(nCreateAgxToneMapper(look.ordinal()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic tone mapping operator that gives control over the tone mapping
|
||||
* curve. This operator can be used to control the aesthetics of the final
|
||||
@@ -194,6 +233,7 @@ public class ToneMapper {
|
||||
private static native long nCreateACESToneMapper();
|
||||
private static native long nCreateACESLegacyToneMapper();
|
||||
private static native long nCreateFilmicToneMapper();
|
||||
private static native long nCreateAgxToneMapper(int look);
|
||||
private static native long nCreateGenericToneMapper(
|
||||
float contrast, float midGrayIn, float midGrayOut, float hdrMax);
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@ import static com.google.android.filament.Asserts.assertFloat3In;
|
||||
import static com.google.android.filament.Asserts.assertFloat4In;
|
||||
import static com.google.android.filament.Colors.LinearColor;
|
||||
|
||||
import com.google.android.filament.proguard.UsedByNative;
|
||||
|
||||
/**
|
||||
* Encompasses all the state needed for rendering a {@link Scene}.
|
||||
*
|
||||
@@ -73,6 +75,7 @@ public class View {
|
||||
private AmbientOcclusionOptions mAmbientOcclusionOptions;
|
||||
private BloomOptions mBloomOptions;
|
||||
private FogOptions mFogOptions;
|
||||
private StereoscopicOptions mStereoscopicOptions;
|
||||
private RenderTarget mRenderTarget;
|
||||
private BlendMode mBlendMode;
|
||||
private DepthOfFieldOptions mDepthOfFieldOptions;
|
||||
@@ -902,7 +905,7 @@ public class View {
|
||||
mBloomOptions = options;
|
||||
nSetBloomOptions(getNativeObject(), options.dirt != null ? options.dirt.getNativeObject() : 0,
|
||||
options.dirtStrength, options.strength, options.resolution,
|
||||
options.anamorphism, options.levels, options.blendMode.ordinal(),
|
||||
options.levels, options.blendMode.ordinal(),
|
||||
options.threshold, options.enabled, options.highlight,
|
||||
options.lensFlare, options.starburst, options.chromaticAberration,
|
||||
options.ghostCount, options.ghostSpacing, options.ghostThreshold,
|
||||
@@ -962,9 +965,11 @@ public class View {
|
||||
assertFloat3In(options.color);
|
||||
mFogOptions = options;
|
||||
nSetFogOptions(getNativeObject(), options.distance, options.maximumOpacity, options.height,
|
||||
options.heightFalloff, options.color[0], options.color[1], options.color[2],
|
||||
options.heightFalloff, options.cutOffDistance,
|
||||
options.color[0], options.color[1], options.color[2],
|
||||
options.density, options.inScatteringStart, options.inScatteringSize,
|
||||
options.fogColorFromIbl,
|
||||
options.skyColor == null ? 0 : options.skyColor.getNativeObject(),
|
||||
options.enabled);
|
||||
}
|
||||
|
||||
@@ -1028,7 +1033,8 @@ public class View {
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Post-processing must be enabled in order to use the stencil buffer.
|
||||
* If post-processing is disabled, then the SwapChain must have the CONFIG_HAS_STENCIL_BUFFER
|
||||
* flag set in order to use the stencil buffer.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
@@ -1050,6 +1056,51 @@ public class View {
|
||||
return nIsStencilBufferEnabled(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the stereoscopic rendering options for this view.
|
||||
*
|
||||
* <p>
|
||||
* Currently, only one type of stereoscopic rendering is supported: side-by-side.
|
||||
* Side-by-side stereo rendering splits the viewport into two halves: a left and right half.
|
||||
* Eye 0 will render to the left half, while Eye 1 will render into the right half.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Currently, the following features are not supported with stereoscopic rendering:
|
||||
* - post-processing
|
||||
* - shadowing
|
||||
* - punctual lights
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Stereo rendering depends on device and platform support. To check if stereo rendering is
|
||||
* supported, use {@link Engine#isStereoSupported()}. If stereo rendering is not supported, then
|
||||
* the stereoscopic options have no effect.
|
||||
* </p>
|
||||
*
|
||||
* @param options The stereoscopic options to use on this view
|
||||
* @see #getStereoscopicOptions
|
||||
*/
|
||||
public void setStereoscopicOptions(@NonNull StereoscopicOptions options) {
|
||||
mStereoscopicOptions = options;
|
||||
nSetStereoscopicOptions(getNativeObject(), options.enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the stereoscopic options.
|
||||
*
|
||||
* @return options Stereoscopic options currently set.
|
||||
* @see #setStereoscopicOptions
|
||||
*/
|
||||
@NonNull
|
||||
public StereoscopicOptions getStereoscopicOptions() {
|
||||
if (mStereoscopicOptions == null) {
|
||||
mStereoscopicOptions = new StereoscopicOptions();
|
||||
}
|
||||
return mStereoscopicOptions;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A class containing the result of a picking query
|
||||
*/
|
||||
@@ -1094,10 +1145,29 @@ public class View {
|
||||
nPick(getNativeObject(), x, y, handler, internalCallback);
|
||||
}
|
||||
|
||||
@UsedByNative("View.cpp")
|
||||
private static class InternalOnPickCallback implements Runnable {
|
||||
private final OnPickCallback mUserCallback;
|
||||
private final PickingQueryResult mPickingQueryResult = new PickingQueryResult();
|
||||
|
||||
@UsedByNative("View.cpp")
|
||||
@Entity
|
||||
int mRenderable;
|
||||
|
||||
@UsedByNative("View.cpp")
|
||||
float mDepth;
|
||||
|
||||
@UsedByNative("View.cpp")
|
||||
float mFragCoordsX;
|
||||
@UsedByNative("View.cpp")
|
||||
float mFragCoordsY;
|
||||
@UsedByNative("View.cpp")
|
||||
float mFragCoordsZ;
|
||||
|
||||
public InternalOnPickCallback(OnPickCallback mUserCallback) {
|
||||
this.mUserCallback = mUserCallback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
mPickingQueryResult.renderable = mRenderable;
|
||||
@@ -1107,13 +1177,51 @@ public class View {
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value of material global variables. There are up-to four such variable each of
|
||||
* type float4. These variables can be read in a user Material with
|
||||
* `getMaterialGlobal{0|1|2|3}()`. All variable start with a default value of { 0, 0, 0, 1 }
|
||||
*
|
||||
* @param index index of the variable to set between 0 and 3.
|
||||
* @param value new value for the variable.
|
||||
* @see #getMaterialGlobal
|
||||
*/
|
||||
public void setMaterialGlobal(int index, @NonNull @Size(min = 4) float[] value) {
|
||||
Asserts.assertFloat4In(value);
|
||||
nSetMaterialGlobal(getNativeObject(), index, value[0], value[1], value[2], value[3]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the material global variables.
|
||||
* All variable start with a default value of { 0, 0, 0, 1 }
|
||||
*
|
||||
* @param index index of the variable to set between 0 and 3.
|
||||
* @param out A 4-float array where the value will be stored, or null in which case the array is
|
||||
* allocated.
|
||||
* @return A 4-float array containing the current value of the variable.
|
||||
* @see #setMaterialGlobal
|
||||
*/
|
||||
@NonNull @Size(min = 4)
|
||||
public float[] getMaterialGlobal(int index, @Nullable @Size(min = 4) float[] out) {
|
||||
out = Asserts.assertFloat4(out);
|
||||
nGetMaterialGlobal(getNativeObject(), index, out);
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an Entity representing the large scale fog object.
|
||||
* This entity is always inherited by the View's Scene.
|
||||
*
|
||||
* It is for example possible to create a TransformManager component with this
|
||||
* Entity and apply a transformation globally on the fog.
|
||||
*
|
||||
* @return an Entity representing the large scale fog object.
|
||||
*/
|
||||
@Entity
|
||||
public int getFogEntity() {
|
||||
return nGetFogEntity(getNativeObject());
|
||||
}
|
||||
|
||||
public long getNativeObject() {
|
||||
@@ -1155,9 +1263,10 @@ public class View {
|
||||
private static native int nGetAmbientOcclusion(long nativeView);
|
||||
private static native void nSetAmbientOcclusionOptions(long nativeView, float radius, float bias, float power, float resolution, float intensity, 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,
|
||||
private static native void nSetBloomOptions(long nativeView, long dirtNativeObject, float dirtStrength, float strength, int resolution, int levels, int blendMode, boolean threshold, boolean enabled, float highlight,
|
||||
boolean lensFlare, boolean starburst, float chromaticAberration, int ghostCount, float ghostSpacing, float ghostThreshold, float haloThickness, float haloRadius, float haloThreshold);
|
||||
private static native void nSetFogOptions(long nativeView, float distance, float maximumOpacity, float height, float heightFalloff, float v, float v1, float v2, float density, float inScatteringStart, float inScatteringSize, boolean fogColorFromIbl, boolean enabled);
|
||||
private static native void nSetFogOptions(long nativeView, float distance, float maximumOpacity, float height, float heightFalloff, float cutOffDistance, float v, float v1, float v2, float density, float inScatteringStart, float inScatteringSize, boolean fogColorFromIbl, long skyColorNativeObject, boolean enabled);
|
||||
private static native void nSetStereoscopicOptions(long nativeView, boolean enabled);
|
||||
private static native void nSetBlendMode(long nativeView, int blendMode);
|
||||
private static native void nSetDepthOfFieldOptions(long nativeView, float cocScale, float maxApertureDiameter, boolean enabled, int filter,
|
||||
boolean nativeResolution, int foregroundRingCount, int backgroundRingCount, int fastGatherRingCount, int maxForegroundCOC, int maxBackgroundCOC);
|
||||
@@ -1172,6 +1281,10 @@ public class View {
|
||||
private static native void nPick(long nativeView, int x, int y, Object handler, InternalOnPickCallback internalCallback);
|
||||
private static native void nSetStencilBufferEnabled(long nativeView, boolean enabled);
|
||||
private static native boolean nIsStencilBufferEnabled(long nativeView);
|
||||
private static native void nSetMaterialGlobal(long nativeView, int index, float x, float y, float z, float w);
|
||||
private static native void nGetMaterialGlobal(long nativeView, int index, float[] out);
|
||||
private static native int nGetFogEntity(long nativeView);
|
||||
|
||||
|
||||
/**
|
||||
* List of available ambient occlusion techniques.
|
||||
@@ -1288,8 +1401,6 @@ public class View {
|
||||
* blendMode: Whether the bloom effect is purely additive (false) or mixed with the original
|
||||
* image (true).
|
||||
*
|
||||
* anamorphism: Bloom's aspect ratio (x/y), for artistic purposes.
|
||||
*
|
||||
* threshold: When enabled, a threshold at 1.0 is applied on the source image, this is
|
||||
* useful for artistic reasons and is usually needed when a dirt texture is used.
|
||||
*
|
||||
@@ -1327,13 +1438,9 @@ public class View {
|
||||
/**
|
||||
* resolution of vertical axis (2^levels to 2048)
|
||||
*/
|
||||
public int resolution = 360;
|
||||
public int resolution = 384;
|
||||
/**
|
||||
* bloom x/y aspect-ratio (1/32 to 32)
|
||||
*/
|
||||
public float anamorphism = 1.0f;
|
||||
/**
|
||||
* number of blur levels (3 to 11)
|
||||
* number of blur levels (1 to 11)
|
||||
*/
|
||||
public int levels = 6;
|
||||
/**
|
||||
@@ -1353,6 +1460,17 @@ public class View {
|
||||
* limit highlights to this value before bloom [10, +inf]
|
||||
*/
|
||||
public float highlight = 1000.0f;
|
||||
/**
|
||||
* Bloom quality level.
|
||||
* LOW (default): use a more optimized down-sampling filter, however there can be artifacts
|
||||
* with dynamic resolution, this can be alleviated by using the homogenous mode.
|
||||
* MEDIUM: Good balance between quality and performance.
|
||||
* HIGH: In this mode the bloom resolution is automatically increased to avoid artifacts.
|
||||
* This mode can be significantly slower on mobile, especially at high resolution.
|
||||
* This mode greatly improves the anamorphic bloom.
|
||||
*/
|
||||
@NonNull
|
||||
public QualityLevel quality = QualityLevel.LOW;
|
||||
/**
|
||||
* enable screen-space lens flare
|
||||
*/
|
||||
@@ -1392,48 +1510,109 @@ public class View {
|
||||
}
|
||||
|
||||
/**
|
||||
* Options to control fog in the scene
|
||||
* Options to control large-scale fog in the scene
|
||||
*/
|
||||
public static class FogOptions {
|
||||
/**
|
||||
* distance in world units from the camera where the fog starts ( >= 0.0 )
|
||||
* Distance in world units [m] from the camera to where the fog starts ( >= 0.0 )
|
||||
*/
|
||||
public float distance = 0.0f;
|
||||
/**
|
||||
* Distance in world units [m] after which the fog calculation is disabled.
|
||||
* This can be used to exclude the skybox, which is desirable if it already contains clouds or
|
||||
* fog. The default value is +infinity which applies the fog to everything.
|
||||
*
|
||||
* Note: The SkyBox is typically at a distance of 1e19 in world space (depending on the near
|
||||
* plane distance and projection used though).
|
||||
*/
|
||||
public float cutOffDistance = Float.POSITIVE_INFINITY;
|
||||
/**
|
||||
* fog's maximum opacity between 0 and 1
|
||||
*/
|
||||
public float maximumOpacity = 1.0f;
|
||||
/**
|
||||
* fog's floor in world units
|
||||
* Fog's floor in world units [m]. This sets the "sea level".
|
||||
*/
|
||||
public float height = 0.0f;
|
||||
/**
|
||||
* how fast fog dissipates with altitude
|
||||
* How fast the fog dissipates with altitude. heightFalloff has a unit of [1/m].
|
||||
* It can be expressed as 1/H, where H is the altitude change in world units [m] that causes a
|
||||
* factor 2.78 (e) change in fog density.
|
||||
*
|
||||
* A falloff of 0 means the fog density is constant everywhere and may result is slightly
|
||||
* faster computations.
|
||||
*/
|
||||
public float heightFalloff = 1.0f;
|
||||
/**
|
||||
* fog's color (linear), see fogColorFromIbl
|
||||
* Fog's color is used for ambient light in-scattering, a good value is
|
||||
* to use the average of the ambient light, possibly tinted towards blue
|
||||
* for outdoors environments. Color component's values should be between 0 and 1, values
|
||||
* above one are allowed but could create a non energy-conservative fog (this is dependant
|
||||
* on the IBL's intensity as well).
|
||||
*
|
||||
* We assume that our fog has no absorption and therefore all the light it scatters out
|
||||
* becomes ambient light in-scattering and has lost all directionality, i.e.: scattering is
|
||||
* isotropic. This somewhat simulates Rayleigh scattering.
|
||||
*
|
||||
* This value is used as a tint instead, when fogColorFromIbl is enabled.
|
||||
*
|
||||
* @see fogColorFromIbl
|
||||
*/
|
||||
@NonNull @Size(min = 3)
|
||||
public float[] color = {0.5f, 0.5f, 0.5f};
|
||||
public float[] color = {1.0f, 1.0f, 1.0f};
|
||||
/**
|
||||
* fog's density at altitude given by 'height'
|
||||
* Extinction factor in [1/m] at altitude 'height'. The extinction factor controls how much
|
||||
* light is absorbed and out-scattered per unit of distance. Each unit of extinction reduces
|
||||
* the incoming light to 37% of its original value.
|
||||
*
|
||||
* Note: The extinction factor is related to the fog density, it's usually some constant K times
|
||||
* the density at sea level (more specifically at fog height). The constant K depends on
|
||||
* the composition of the fog/atmosphere.
|
||||
*
|
||||
* For historical reason this parameter is called `density`.
|
||||
*/
|
||||
public float density = 0.1f;
|
||||
/**
|
||||
* distance in world units from the camera where in-scattering starts
|
||||
* Distance in world units [m] from the camera where the Sun in-scattering starts.
|
||||
*/
|
||||
public float inScatteringStart = 0.0f;
|
||||
/**
|
||||
* size of in-scattering (>0 to activate). Good values are >> 1 (e.g. ~10 - 100).
|
||||
* Very inaccurately simulates the Sun's in-scattering. That is, the light from the sun that
|
||||
* is scattered (by the fog) towards the camera.
|
||||
* Size of the Sun in-scattering (>0 to activate). Good values are >> 1 (e.g. ~10 - 100).
|
||||
* Smaller values result is a larger scattering size.
|
||||
*/
|
||||
public float inScatteringSize = -1.0f;
|
||||
/**
|
||||
* Fog color will be modulated by the IBL color in the view direction.
|
||||
* The fog color will be sampled from the IBL in the view direction and tinted by `color`.
|
||||
* Depending on the scene this can produce very convincing results.
|
||||
*
|
||||
* This simulates a more anisotropic phase-function.
|
||||
*
|
||||
* `fogColorFromIbl` is ignored when skyTexture is specified.
|
||||
*
|
||||
* @see skyColor
|
||||
*/
|
||||
public boolean fogColorFromIbl = false;
|
||||
/**
|
||||
* enable or disable fog
|
||||
* skyTexture must be a mipmapped cubemap. When provided, the fog color will be sampled from
|
||||
* this texture, higher resolution mip levels will be used for objects at the far clip plane,
|
||||
* and lower resolution mip levels for objects closer to the camera. The skyTexture should
|
||||
* typically be heavily blurred; a typical way to produce this texture is to blur the base
|
||||
* level with a strong gaussian filter or even an irradiance filter and then generate mip
|
||||
* levels as usual. How blurred the base level is somewhat of an artistic decision.
|
||||
*
|
||||
* This simulates a more anisotropic phase-function.
|
||||
*
|
||||
* `fogColorFromIbl` is ignored when skyTexture is specified.
|
||||
*
|
||||
* @see Texture
|
||||
* @see fogColorFromIbl
|
||||
*/
|
||||
@Nullable
|
||||
public Texture skyColor = null;
|
||||
/**
|
||||
* Enable or disable large-scale fog
|
||||
*/
|
||||
public boolean enabled = false;
|
||||
}
|
||||
@@ -1458,6 +1637,10 @@ public class View {
|
||||
* circle of confusion scale factor (amount of blur)
|
||||
*/
|
||||
public float cocScale = 1.0f;
|
||||
/**
|
||||
* width/height aspect ratio of the circle of confusion (simulate anamorphic lenses)
|
||||
*/
|
||||
public float cocAspectRatio = 1.0f;
|
||||
/**
|
||||
* maximum aperture diameter in meters (zero to disable rotation)
|
||||
*/
|
||||
@@ -1673,7 +1856,7 @@ public class View {
|
||||
}
|
||||
|
||||
/**
|
||||
* Options for Temporal Multi-Sample Anti-aliasing (MSAA)
|
||||
* Options for Multi-Sample Anti-aliasing (MSAA)
|
||||
* @see setMultiSampleAntiAliasingOptions()
|
||||
*/
|
||||
public static class MultiSampleAntiAliasingOptions {
|
||||
@@ -1697,21 +1880,111 @@ public class View {
|
||||
|
||||
/**
|
||||
* Options for Temporal Anti-aliasing (TAA)
|
||||
* Most TAA parameters are extremely costly to change, as they will trigger the TAA post-process
|
||||
* shaders to be recompiled. These options should be changed or set during initialization.
|
||||
* `filterWidth`, `feedback` and `jitterPattern`, however, can be changed at any time.
|
||||
*
|
||||
* `feedback` of 0.1 effectively accumulates a maximum of 19 samples in steady state.
|
||||
* see "A Survey of Temporal Antialiasing Techniques" by Lei Yang and all for more information.
|
||||
*
|
||||
* @see setTemporalAntiAliasingOptions()
|
||||
*/
|
||||
public static class TemporalAntiAliasingOptions {
|
||||
public enum BoxType {
|
||||
/**
|
||||
* use an AABB neighborhood
|
||||
*/
|
||||
AABB,
|
||||
/**
|
||||
* use the variance of the neighborhood (not recommended)
|
||||
*/
|
||||
VARIANCE,
|
||||
/**
|
||||
* use both AABB and variance
|
||||
*/
|
||||
AABB_VARIANCE,
|
||||
}
|
||||
|
||||
public enum BoxClipping {
|
||||
/**
|
||||
* Accurate box clipping
|
||||
*/
|
||||
ACCURATE,
|
||||
/**
|
||||
* clamping
|
||||
*/
|
||||
CLAMP,
|
||||
/**
|
||||
* no rejections (use for debugging)
|
||||
*/
|
||||
NONE,
|
||||
}
|
||||
|
||||
public enum JitterPattern {
|
||||
RGSS_X4,
|
||||
UNIFORM_HELIX_X4,
|
||||
HALTON_23_X8,
|
||||
HALTON_23_X16,
|
||||
HALTON_23_X32,
|
||||
}
|
||||
|
||||
/**
|
||||
* reconstruction filter width typically between 0 (sharper, aliased) and 1 (smoother)
|
||||
* reconstruction filter width typically between 0.2 (sharper, aliased) and 1.5 (smoother)
|
||||
*/
|
||||
public float filterWidth = 1.0f;
|
||||
/**
|
||||
* history feedback, between 0 (maximum temporal AA) and 1 (no temporal AA).
|
||||
*/
|
||||
public float feedback = 0.04f;
|
||||
public float feedback = 0.12f;
|
||||
/**
|
||||
* texturing lod bias (typically -1 or -2)
|
||||
*/
|
||||
public float lodBias = -1.0f;
|
||||
/**
|
||||
* post-TAA sharpen, especially useful when upscaling is true.
|
||||
*/
|
||||
public float sharpness = 0.0f;
|
||||
/**
|
||||
* enables or disables temporal anti-aliasing
|
||||
*/
|
||||
public boolean enabled = false;
|
||||
/**
|
||||
* 4x TAA upscaling. Disables Dynamic Resolution. [BETA]
|
||||
*/
|
||||
public boolean upscaling = false;
|
||||
/**
|
||||
* whether to filter the history buffer
|
||||
*/
|
||||
public boolean filterHistory = true;
|
||||
/**
|
||||
* whether to apply the reconstruction filter to the input
|
||||
*/
|
||||
public boolean filterInput = true;
|
||||
/**
|
||||
* whether to use the YcoCg color-space for history rejection
|
||||
*/
|
||||
public boolean useYCoCg = false;
|
||||
/**
|
||||
* type of color gamut box
|
||||
*/
|
||||
@NonNull
|
||||
public TemporalAntiAliasingOptions.BoxType boxType = TemporalAntiAliasingOptions.BoxType.AABB;
|
||||
/**
|
||||
* clipping algorithm
|
||||
*/
|
||||
@NonNull
|
||||
public TemporalAntiAliasingOptions.BoxClipping boxClipping = TemporalAntiAliasingOptions.BoxClipping.ACCURATE;
|
||||
@NonNull
|
||||
public TemporalAntiAliasingOptions.JitterPattern jitterPattern = TemporalAntiAliasingOptions.JitterPattern.HALTON_23_X16;
|
||||
public float varianceGamma = 1.0f;
|
||||
/**
|
||||
* adjust the feedback dynamically to reduce flickering
|
||||
*/
|
||||
public boolean preventFlickering = false;
|
||||
/**
|
||||
* whether to apply history reprojection (debug option)
|
||||
*/
|
||||
public boolean historyReprojection = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1798,6 +2071,7 @@ public class View {
|
||||
* PCF with soft shadows and contact hardening
|
||||
*/
|
||||
PCSS,
|
||||
PCFd,
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1860,4 +2134,11 @@ public class View {
|
||||
*/
|
||||
public float penumbraRatioScale = 1.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Options for stereoscopic (multi-eye) rendering.
|
||||
*/
|
||||
public static class StereoscopicOptions {
|
||||
public boolean enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.android;
|
||||
|
||||
import com.google.android.filament.Engine;
|
||||
import com.google.android.filament.Fence;
|
||||
|
||||
public class FilamentHelper {
|
||||
|
||||
/**
|
||||
* Wait for all pending frames to be processed before returning. This is to avoid a race
|
||||
* between the surface being resized before pending frames are rendered into it.
|
||||
* <p>
|
||||
* For {@link android.view.TextureView} this must be called before the texture's size is
|
||||
* reconfigured, which unfortunately is done by the Android framework before
|
||||
* {@link UiHelper} listeners are invoked. Therefore <code>synchronizePendingFrames</code>
|
||||
* cannot be called from
|
||||
* {@link android.view.TextureView.SurfaceTextureListener#onSurfaceTextureSizeChanged}; instead
|
||||
* a subclass of {@link android.view.TextureView} must be used in order to call it from
|
||||
* {@link android.view.TextureView#onSizeChanged}:
|
||||
* </p>
|
||||
* <pre>
|
||||
* public class MyTextureView extends TextureView {
|
||||
* private Engine engine;
|
||||
* protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
* FilamentHelper.synchronizePendingFrames(engine);
|
||||
* super.onSizeChanged(w, h, oldw, oldh);
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* Otherwise, this is typically called from {@link UiHelper.RendererCallback#onResized},
|
||||
* {@link android.view.SurfaceHolder.Callback#surfaceChanged}.
|
||||
*
|
||||
* @param engine Filament engine to synchronize
|
||||
*
|
||||
* @see UiHelper.RendererCallback#onResized
|
||||
* @see android.view.SurfaceHolder.Callback#surfaceChanged
|
||||
* @see android.view.TextureView#onSizeChanged
|
||||
*/
|
||||
static public void synchronizePendingFrames(Engine engine) {
|
||||
Fence fence = engine.createFence();
|
||||
fence.wait(Fence.Mode.FLUSH, Fence.WAIT_FOR_EVER);
|
||||
engine.destroyFence(fence);
|
||||
}
|
||||
}
|
||||
@@ -84,6 +84,14 @@ import com.google.android.filament.SwapChain;
|
||||
* // The native surface has changed size. This is always called at least once
|
||||
* // after the surface is created (after onNativeWindowChanged() is invoked).
|
||||
* public void onResized(int width, int height) {
|
||||
*
|
||||
* // Wait for all pending frames to be processed before returning. This is to
|
||||
* // avoid a race between the surface being resized before pending frames are
|
||||
* // rendered into it.
|
||||
* Fence fence = mEngine.createFence();
|
||||
* fence.wait(Fence.Mode.FLUSH, Fence.WAIT_FOR_EVER);
|
||||
* mEngine.destroyFence(fence);
|
||||
*
|
||||
* // Compute camera projection and set the viewport on the view
|
||||
* }
|
||||
* });
|
||||
@@ -174,28 +182,85 @@ public class UiHelper {
|
||||
void detach();
|
||||
}
|
||||
|
||||
private static class SurfaceViewHandler implements RenderSurface {
|
||||
private SurfaceView mSurfaceView;
|
||||
private class SurfaceViewHandler implements RenderSurface, SurfaceHolder.Callback {
|
||||
@NonNull private final SurfaceView mSurfaceView;
|
||||
|
||||
SurfaceViewHandler(SurfaceView surface) {
|
||||
mSurfaceView = surface;
|
||||
SurfaceViewHandler(@NonNull SurfaceView surfaceView) {
|
||||
mSurfaceView = surfaceView;
|
||||
|
||||
@NonNull SurfaceHolder holder = surfaceView.getHolder();
|
||||
holder.addCallback(this);
|
||||
|
||||
if (mDesiredWidth > 0 && mDesiredHeight > 0) {
|
||||
holder.setFixedSize(mDesiredWidth, mDesiredHeight);
|
||||
}
|
||||
|
||||
// in case the SurfaceView's surface already existed
|
||||
final Surface surface = holder.getSurface();
|
||||
if (surface != null && surface.isValid()) {
|
||||
surfaceCreated(holder);
|
||||
// there is no way to retrieve the actual PixelFormat, since it is not used
|
||||
// in the callback, we can use whatever we want.
|
||||
surfaceChanged(holder, PixelFormat.RGBA_8888,
|
||||
holder.getSurfaceFrame().width(), holder.getSurfaceFrame().height());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resize(int width, int height) {
|
||||
mSurfaceView.getHolder().setFixedSize(width, height);
|
||||
@NonNull SurfaceHolder holder = mSurfaceView.getHolder();
|
||||
holder.setFixedSize(width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void detach() {
|
||||
@NonNull SurfaceHolder holder = mSurfaceView.getHolder();
|
||||
holder.removeCallback(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceCreated(@NonNull SurfaceHolder holder) {
|
||||
if (LOGGING) Log.d(LOG_TAG, "surfaceCreated()");
|
||||
createSwapChain(holder.getSurface());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(
|
||||
@NonNull SurfaceHolder holder, int format, int width, int height) {
|
||||
// Note: this is always called at least once after surfaceCreated()
|
||||
if (LOGGING) Log.d(LOG_TAG, "surfaceChanged(" + width + ", " + height + ")");
|
||||
if (mRenderCallback != null) {
|
||||
mRenderCallback.onResized(width, height);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
|
||||
if (LOGGING) Log.d(LOG_TAG, "surfaceDestroyed()");
|
||||
destroySwapChain();
|
||||
}
|
||||
}
|
||||
|
||||
private static class SurfaceHolderHandler implements RenderSurface {
|
||||
private SurfaceHolder mSurfaceHolder;
|
||||
private class SurfaceHolderHandler implements RenderSurface, SurfaceHolder.Callback {
|
||||
private final SurfaceHolder mSurfaceHolder;
|
||||
|
||||
SurfaceHolderHandler(SurfaceHolder surface) {
|
||||
mSurfaceHolder = surface;
|
||||
SurfaceHolderHandler(@NonNull SurfaceHolder holder) {
|
||||
mSurfaceHolder = holder;
|
||||
holder.addCallback(this);
|
||||
|
||||
if (mDesiredWidth > 0 && mDesiredHeight > 0) {
|
||||
holder.setFixedSize(mDesiredWidth, mDesiredHeight);
|
||||
}
|
||||
|
||||
// in case the SurfaceHolder's surface already existed
|
||||
final Surface surface = holder.getSurface();
|
||||
if (surface != null && surface.isValid()) {
|
||||
surfaceCreated(holder);
|
||||
// there is no way to retrieve the actual PixelFormat, since it is not used
|
||||
// in the callback, we can use whatever we want.
|
||||
surfaceChanged(holder, PixelFormat.RGBA_8888,
|
||||
holder.getSurfaceFrame().width(), holder.getSurfaceFrame().height());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -205,30 +270,127 @@ public class UiHelper {
|
||||
|
||||
@Override
|
||||
public void detach() {
|
||||
mSurfaceHolder.removeCallback(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceCreated(@NonNull SurfaceHolder holder) {
|
||||
if (LOGGING) Log.d(LOG_TAG, "surfaceCreated()");
|
||||
createSwapChain(holder.getSurface());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
|
||||
// Note: this is always called at least once after surfaceCreated()
|
||||
if (LOGGING) Log.d(LOG_TAG, "surfaceChanged(" + width + ", " + height + ")");
|
||||
if (mRenderCallback != null) {
|
||||
mRenderCallback.onResized(width, height);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {
|
||||
if (LOGGING) Log.d(LOG_TAG, "surfaceDestroyed()");
|
||||
destroySwapChain();
|
||||
}
|
||||
}
|
||||
|
||||
private class TextureViewHandler implements RenderSurface {
|
||||
private TextureView mTextureView;
|
||||
private class TextureViewHandler implements RenderSurface, TextureView.SurfaceTextureListener {
|
||||
private final TextureView mTextureView;
|
||||
private Surface mSurface;
|
||||
|
||||
TextureViewHandler(TextureView surface) { mTextureView = surface; }
|
||||
TextureViewHandler(@NonNull TextureView view) {
|
||||
mTextureView = view;
|
||||
mTextureView.setSurfaceTextureListener(this);
|
||||
// in case the View's SurfaceTexture already existed
|
||||
if (view.isAvailable()) {
|
||||
SurfaceTexture surfaceTexture = view.getSurfaceTexture();
|
||||
if (surfaceTexture != null) {
|
||||
this.onSurfaceTextureAvailable(surfaceTexture,
|
||||
mDesiredWidth, mDesiredHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resize(int width, int height) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
|
||||
mTextureView.getSurfaceTexture().setDefaultBufferSize(width, height);
|
||||
final SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
|
||||
if (surfaceTexture != null) {
|
||||
surfaceTexture.setDefaultBufferSize(width, height);
|
||||
}
|
||||
}
|
||||
if (mRenderCallback != null) {
|
||||
// the call above won't cause TextureView.onSurfaceTextureSizeChanged()
|
||||
mRenderCallback.onResized(width, height);
|
||||
}
|
||||
// the call above won't cause TextureView.onSurfaceTextureSizeChanged()
|
||||
mRenderCallback.onResized(width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void detach() {
|
||||
setSurface(null);
|
||||
mTextureView.setSurfaceTextureListener(null);
|
||||
}
|
||||
|
||||
void setSurface(Surface surface) {
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureAvailable(
|
||||
@NonNull SurfaceTexture surfaceTexture, int width, int height) {
|
||||
if (LOGGING) Log.d(LOG_TAG, "onSurfaceTextureAvailable()");
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
|
||||
if (mDesiredWidth > 0 && mDesiredHeight > 0) {
|
||||
surfaceTexture.setDefaultBufferSize(mDesiredWidth, mDesiredHeight);
|
||||
}
|
||||
}
|
||||
|
||||
final Surface surface = new Surface(surfaceTexture);
|
||||
setSurface(surface);
|
||||
createSwapChain(surface);
|
||||
|
||||
if (mRenderCallback != null) {
|
||||
// Call this the first time because onSurfaceTextureSizeChanged()
|
||||
// isn't called at initialization time
|
||||
mRenderCallback.onResized(width, height);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureSizeChanged(
|
||||
@NonNull SurfaceTexture surfaceTexture, int width, int height) {
|
||||
if (LOGGING) Log.d(LOG_TAG, "onSurfaceTextureSizeChanged()");
|
||||
if (mRenderCallback != null) {
|
||||
if (mDesiredWidth > 0 && mDesiredHeight > 0) {
|
||||
surfaceTexture.setDefaultBufferSize(mDesiredWidth, mDesiredHeight);
|
||||
mRenderCallback.onResized(mDesiredWidth, mDesiredHeight);
|
||||
} else {
|
||||
mRenderCallback.onResized(width, height);
|
||||
}
|
||||
// We must recreate the SwapChain to guarantee that it sees the new size.
|
||||
// More precisely, for an EGL client, the EGLSurface must be recreated. For
|
||||
// a Vulkan client, the SwapChain must be recreated. Calling
|
||||
// onNativeWindowChanged() will accomplish that.
|
||||
// This requirement comes from SurfaceTexture.setDefaultBufferSize()
|
||||
// documentation.
|
||||
final Surface surface = getSurface();
|
||||
if (surface != null) {
|
||||
mRenderCallback.onNativeWindowChanged(surface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surfaceTexture) {
|
||||
if (LOGGING) Log.d(LOG_TAG, "onSurfaceTextureDestroyed()");
|
||||
setSurface(null);
|
||||
destroySwapChain();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) { }
|
||||
|
||||
|
||||
private void setSurface(@Nullable Surface surface) {
|
||||
if (surface == null) {
|
||||
if (mSurface != null) {
|
||||
mSurface.release();
|
||||
@@ -236,6 +398,10 @@ public class UiHelper {
|
||||
}
|
||||
mSurface = surface;
|
||||
}
|
||||
|
||||
private Surface getSurface() {
|
||||
return mSurface;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -279,6 +445,9 @@ public class UiHelper {
|
||||
* {@link #attachTo(TextureView)}, or {@link #attachTo(SurfaceHolder)}.
|
||||
*/
|
||||
public void detach() {
|
||||
if (mRenderSurface != null) {
|
||||
mRenderSurface.detach();
|
||||
}
|
||||
destroySwapChain();
|
||||
mNativeWindow = null;
|
||||
mRenderSurface = null;
|
||||
@@ -286,7 +455,6 @@ public class UiHelper {
|
||||
|
||||
/**
|
||||
* Checks whether we are ready to render into the attached surface.
|
||||
*
|
||||
* Using OpenGL ES when this returns true, will result in drawing commands being lost,
|
||||
* HOWEVER, GLES state will be preserved. This is useful to initialize the engine.
|
||||
*
|
||||
@@ -331,7 +499,6 @@ public class UiHelper {
|
||||
/**
|
||||
* Controls whether the render target (SurfaceView or TextureView) is opaque or not.
|
||||
* The render target is considered opaque by default.
|
||||
*
|
||||
* Must be called before calling {@link #attachTo(SurfaceView)}, {@link #attachTo(TextureView)},
|
||||
* or {@link #attachTo(SurfaceHolder)}.
|
||||
*
|
||||
@@ -354,10 +521,8 @@ public class UiHelper {
|
||||
* positioned above other surfaces but below the activity's surface. This property
|
||||
* only has an effect when used in combination with {@link #setOpaque(boolean) setOpaque(false)}
|
||||
* and does not affect TextureView targets.
|
||||
*
|
||||
* Must be called before calling {@link #attachTo(SurfaceView)}
|
||||
* or {@link #attachTo(TextureView)}.
|
||||
*
|
||||
* Has no effect when using {@link #attachTo(SurfaceHolder)}.
|
||||
*
|
||||
* @param overlay Indicates whether the render target should be rendered below the activity's
|
||||
@@ -378,7 +543,6 @@ public class UiHelper {
|
||||
|
||||
/**
|
||||
* Associate UiHelper with a SurfaceView.
|
||||
*
|
||||
* As soon as SurfaceView is ready (i.e. has a Surface), we'll create the
|
||||
* EGL resources needed, and call user callbacks if needed.
|
||||
*/
|
||||
@@ -393,163 +557,32 @@ public class UiHelper {
|
||||
view.setZOrderOnTop(translucent);
|
||||
}
|
||||
|
||||
int format = isOpaque() ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT;
|
||||
view.getHolder().setFormat(format);
|
||||
|
||||
view.getHolder().setFormat(isOpaque() ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT);
|
||||
mRenderSurface = new SurfaceViewHandler(view);
|
||||
|
||||
final SurfaceHolder.Callback callback = new SurfaceHolder.Callback() {
|
||||
@Override
|
||||
public void surfaceCreated(SurfaceHolder holder) {
|
||||
if (LOGGING) Log.d(LOG_TAG, "surfaceCreated()");
|
||||
createSwapChain(holder.getSurface());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(
|
||||
SurfaceHolder holder, int format, int width, int height) {
|
||||
// Note: this is always called at least once after surfaceCreated()
|
||||
if (LOGGING) Log.d(LOG_TAG, "surfaceChanged(" + width + ", " + height + ")");
|
||||
mRenderCallback.onResized(width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||
if (LOGGING) Log.d(LOG_TAG, "surfaceDestroyed()");
|
||||
destroySwapChain();
|
||||
}
|
||||
};
|
||||
|
||||
SurfaceHolder holder = view.getHolder();
|
||||
holder.addCallback(callback);
|
||||
if (mDesiredWidth > 0 && mDesiredHeight > 0) {
|
||||
holder.setFixedSize(mDesiredWidth, mDesiredHeight);
|
||||
}
|
||||
|
||||
// in case the SurfaceView's surface already existed
|
||||
final Surface surface = holder.getSurface();
|
||||
if (surface != null && surface.isValid()) {
|
||||
callback.surfaceCreated(holder);
|
||||
callback.surfaceChanged(holder, format,
|
||||
holder.getSurfaceFrame().width(), holder.getSurfaceFrame().height());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate UiHelper with a TextureView.
|
||||
*
|
||||
* As soon as TextureView is ready (i.e. has a buffer), we'll create the
|
||||
* EGL resources needed, and call user callbacks if needed.
|
||||
*/
|
||||
public void attachTo(@NonNull TextureView view) {
|
||||
if (attach(view)) {
|
||||
view.setOpaque(isOpaque());
|
||||
|
||||
mRenderSurface = new TextureViewHandler(view);
|
||||
|
||||
TextureView.SurfaceTextureListener listener = new TextureView.SurfaceTextureListener() {
|
||||
@Override
|
||||
public void onSurfaceTextureAvailable(
|
||||
SurfaceTexture surfaceTexture, int width, int height) {
|
||||
if (LOGGING) Log.d(LOG_TAG, "onSurfaceTextureAvailable()");
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
|
||||
if (mDesiredWidth > 0 && mDesiredHeight > 0) {
|
||||
surfaceTexture.setDefaultBufferSize(mDesiredWidth, mDesiredHeight);
|
||||
}
|
||||
}
|
||||
|
||||
Surface surface = new Surface(surfaceTexture);
|
||||
TextureViewHandler textureViewHandler = (TextureViewHandler) mRenderSurface;
|
||||
textureViewHandler.setSurface(surface);
|
||||
|
||||
createSwapChain(surface);
|
||||
|
||||
// Call this the first time because onSurfaceTextureSizeChanged()
|
||||
// isn't called at initialization time
|
||||
mRenderCallback.onResized(width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureSizeChanged(
|
||||
SurfaceTexture surfaceTexture, int width, int height) {
|
||||
if (LOGGING) Log.d(LOG_TAG, "onSurfaceTextureSizeChanged()");
|
||||
if (mDesiredWidth > 0 && mDesiredHeight > 0) {
|
||||
surfaceTexture.setDefaultBufferSize(mDesiredWidth, mDesiredHeight);
|
||||
mRenderCallback.onResized(mDesiredWidth, mDesiredHeight);
|
||||
} else {
|
||||
mRenderCallback.onResized(width, height);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
|
||||
if (LOGGING) Log.d(LOG_TAG, "onSurfaceTextureDestroyed()");
|
||||
destroySwapChain();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureUpdated(SurfaceTexture surface) { }
|
||||
};
|
||||
|
||||
view.setSurfaceTextureListener(listener);
|
||||
|
||||
// in case the View's SurfaceTexture already existed
|
||||
if (view.isAvailable()) {
|
||||
SurfaceTexture surfaceTexture = view.getSurfaceTexture();
|
||||
listener.onSurfaceTextureAvailable(surfaceTexture, mDesiredWidth, mDesiredHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate UiHelper with a SurfaceHolder.
|
||||
*
|
||||
* As soon as a Surface is created, we'll create the
|
||||
* EGL resources needed, and call user callbacks if needed.
|
||||
*/
|
||||
public void attachTo(@NonNull SurfaceHolder holder) {
|
||||
if (attach(holder)) {
|
||||
int format = isOpaque() ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT;
|
||||
holder.setFormat(format);
|
||||
|
||||
holder.setFormat(isOpaque() ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT);
|
||||
mRenderSurface = new SurfaceHolderHandler(holder);
|
||||
|
||||
final SurfaceHolder.Callback callback = new SurfaceHolder.Callback() {
|
||||
@Override
|
||||
public void surfaceCreated(SurfaceHolder surfaceHolder) {
|
||||
if (LOGGING) Log.d(LOG_TAG, "surfaceCreated()");
|
||||
createSwapChain(holder.getSurface());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
||||
// Note: this is always called at least once after surfaceCreated()
|
||||
if (LOGGING) Log.d(LOG_TAG, "surfaceChanged(" + width + ", " + height + ")");
|
||||
mRenderCallback.onResized(width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
|
||||
if (LOGGING) Log.d(LOG_TAG, "surfaceDestroyed()");
|
||||
destroySwapChain();
|
||||
}
|
||||
};
|
||||
|
||||
holder.addCallback(callback);
|
||||
if (mDesiredWidth > 0 && mDesiredHeight > 0) {
|
||||
holder.setFixedSize(mDesiredWidth, mDesiredHeight);
|
||||
}
|
||||
|
||||
// in case the SurfaceHolder's surface already existed
|
||||
final Surface surface = holder.getSurface();
|
||||
if (surface != null && surface.isValid()) {
|
||||
callback.surfaceCreated(holder);
|
||||
callback.surfaceChanged(holder, format,
|
||||
holder.getSurfaceFrame().width(), holder.getSurfaceFrame().height());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -560,6 +593,10 @@ public class UiHelper {
|
||||
// nothing to do
|
||||
return false;
|
||||
}
|
||||
if (mRenderSurface != null) {
|
||||
mRenderSurface.detach();
|
||||
mRenderSurface = null;
|
||||
}
|
||||
destroySwapChain();
|
||||
}
|
||||
mNativeWindow = nativeWindow;
|
||||
@@ -567,15 +604,16 @@ public class UiHelper {
|
||||
}
|
||||
|
||||
private void createSwapChain(@NonNull Surface surface) {
|
||||
mRenderCallback.onNativeWindowChanged(surface);
|
||||
if (mRenderCallback != null) {
|
||||
mRenderCallback.onNativeWindowChanged(surface);
|
||||
}
|
||||
mHasSwapChain = true;
|
||||
}
|
||||
|
||||
private void destroySwapChain() {
|
||||
if (mRenderSurface != null) {
|
||||
mRenderSurface.detach();
|
||||
if (mRenderCallback != null) {
|
||||
mRenderCallback.onDetachedFromSurface();
|
||||
}
|
||||
mRenderCallback.onDetachedFromSurface();
|
||||
mHasSwapChain = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
apply plugin: 'kotlin-android'
|
||||
kotlin {
|
||||
jvmToolchain(versions.jdk)
|
||||
}
|
||||
|
||||
android {
|
||||
namespace 'com.google.android.filament.utils'
|
||||
@@ -9,9 +12,6 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
missingDimensionStrategy 'functionality', 'full'
|
||||
}
|
||||
packagingOptions {
|
||||
// No need to package up the following shared libs, which arise as a side effect of our
|
||||
// externalNativeBuild dependencies. When clients pick and choose from project-level gradle
|
||||
@@ -21,16 +21,11 @@ android {
|
||||
excludes += ['lib/*/libfilament-jni.so', 'lib/*/libgltfio-jni.so']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
configurations.all { config ->
|
||||
// Hack to preserve the version of the dependencies
|
||||
if (!config.name.endsWith('Publication')) {
|
||||
resolutionStrategy {
|
||||
dependencySubstitution {
|
||||
substitute(module("com.google.android.filament:gltfio-android:${VERSION_NAME}")).with(project(":gltfio-android"))
|
||||
substitute(module("com.google.android.filament:gltfio-android-lite:${VERSION_NAME}")).with(project(":gltfio-android"))
|
||||
}
|
||||
publishing {
|
||||
singleVariant("release") {
|
||||
withSourcesJar()
|
||||
withJavadocJar()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -43,7 +38,7 @@ dependencies {
|
||||
implementation deps.coroutines.android
|
||||
|
||||
api project(':filament-android')
|
||||
api module("com.google.android.filament:gltfio-android:${VERSION_NAME}")
|
||||
api project(':gltfio-android')
|
||||
}
|
||||
|
||||
apply from: rootProject.file('gradle/gradle-mvn-push.gradle')
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
@file:Suppress("unused")
|
||||
@file:Suppress("NOTHING_TO_INLINE", "unused")
|
||||
|
||||
package com.google.android.filament.utils
|
||||
|
||||
@@ -24,8 +24,16 @@ enum class MatrixColumn {
|
||||
X, Y, Z, W
|
||||
}
|
||||
|
||||
enum class RotationsOrder {
|
||||
XYZ, XZY, YXZ, YZX, ZXY, ZYX
|
||||
enum class RotationsOrder(
|
||||
val yaw: VectorComponent,
|
||||
val pitch: VectorComponent,
|
||||
val roll: VectorComponent) {
|
||||
XYZ(VectorComponent.X, VectorComponent.Y, VectorComponent.Z),
|
||||
XZY(VectorComponent.X, VectorComponent.Z, VectorComponent.Y),
|
||||
YXZ(VectorComponent.Y, VectorComponent.X, VectorComponent.Z),
|
||||
YZX(VectorComponent.Y, VectorComponent.Z, VectorComponent.X),
|
||||
ZXY(VectorComponent.Z, VectorComponent.X, VectorComponent.Y),
|
||||
ZYX(VectorComponent.Z, VectorComponent.Y, VectorComponent.X);
|
||||
}
|
||||
|
||||
data class Mat2(
|
||||
@@ -77,6 +85,12 @@ data class Mat2(
|
||||
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)
|
||||
inline fun compareTo(v: Float, delta: Float = 0.0f) = Mat2(
|
||||
x.compareTo(v, delta),
|
||||
y.compareTo(v, delta)
|
||||
)
|
||||
|
||||
inline fun equals(v: Float, delta: Float = 0.0f) = x.equals(v, delta) && y.equals(v, delta)
|
||||
|
||||
operator fun times(m: Mat2) = Mat2(
|
||||
Float2(
|
||||
@@ -89,12 +103,18 @@ data class Mat2(
|
||||
)
|
||||
)
|
||||
|
||||
inline fun compareTo(m: Mat2, delta: Float = 0.0f) = Mat2(
|
||||
x.compareTo(m.x, delta),
|
||||
y.compareTo(m.y, delta)
|
||||
)
|
||||
|
||||
inline fun equals(m: Mat2, delta: Float = 0.0f) = x.equals(m.x, delta) && y.equals(m.y, delta)
|
||||
|
||||
operator fun times(v: Float2) = Float2(
|
||||
x.x * v.x + y.x * v.y,
|
||||
x.y * v.x + y.y * v.y,
|
||||
)
|
||||
|
||||
|
||||
fun toFloatArray() = floatArrayOf(
|
||||
x.x, y.x,
|
||||
x.y, y.y
|
||||
@@ -106,7 +126,6 @@ data class Mat2(
|
||||
|${x.y} ${y.y}|
|
||||
""".trimIndent()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
data class Mat3(
|
||||
@@ -162,6 +181,14 @@ data class Mat3(
|
||||
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)
|
||||
inline fun compareTo(v: Float, delta: Float = 0.0f) = Mat3(
|
||||
x.compareTo(v, delta),
|
||||
y.compareTo(v, delta),
|
||||
z.compareTo(v, delta)
|
||||
)
|
||||
|
||||
inline fun equals(v: Float, delta: Float = 0.0f) =
|
||||
x.equals(v, delta) && y.equals(v, delta) && z.equals(v, delta)
|
||||
|
||||
operator fun times(m: Mat3) = Mat3(
|
||||
Float3(
|
||||
@@ -181,6 +208,15 @@ data class Mat3(
|
||||
)
|
||||
)
|
||||
|
||||
inline fun compareTo(m: Mat3, delta: Float = 0.0f) = Mat3(
|
||||
x.compareTo(m.x, delta),
|
||||
y.compareTo(m.y, delta),
|
||||
z.compareTo(m.z, delta)
|
||||
)
|
||||
|
||||
inline fun equals(m: Mat3, delta: Float = 0.0f) =
|
||||
x.equals(m.x, delta) && y.equals(m.y, delta) && z.equals(m.z, delta)
|
||||
|
||||
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,
|
||||
@@ -212,6 +248,7 @@ data class Mat4(
|
||||
constructor(m: Mat4) : this(m.x.copy(), m.y.copy(), m.z.copy(), m.w.copy())
|
||||
|
||||
companion object {
|
||||
|
||||
fun of(vararg a: Float): Mat4 {
|
||||
require(a.size >= 16)
|
||||
return Mat4(
|
||||
@@ -302,6 +339,15 @@ data class Mat4(
|
||||
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)
|
||||
inline fun compareTo(v: Float, delta: Float = 0.0f) = Mat4(
|
||||
x.compareTo(v, delta),
|
||||
y.compareTo(v, delta),
|
||||
z.compareTo(v, delta),
|
||||
w.compareTo(v, delta)
|
||||
)
|
||||
|
||||
inline fun equals(v: Float, delta: Float = 0.0f) =
|
||||
x.equals(v, delta) && y.equals(v, delta) && z.equals(v, delta) && w.equals(v, delta)
|
||||
|
||||
operator fun times(m: Mat4) = Mat4(
|
||||
Float4(
|
||||
@@ -330,6 +376,16 @@ data class Mat4(
|
||||
)
|
||||
)
|
||||
|
||||
inline fun compareTo(m: Mat4, delta: Float = 0.0f) = Mat4(
|
||||
x.compareTo(m.x, delta),
|
||||
y.compareTo(m.y, delta),
|
||||
z.compareTo(m.z, delta),
|
||||
w.compareTo(m.w, delta)
|
||||
)
|
||||
|
||||
inline fun equals(m: Mat4, delta: Float = 0.0f) =
|
||||
x.equals(m.x, delta) && y.equals(m.y, delta) && z.equals(m.z, delta) && w.equals(m.w, delta)
|
||||
|
||||
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,
|
||||
@@ -337,6 +393,26 @@ data class Mat4(
|
||||
x.w * v.x + y.w * v.y + z.w * v.z+ w.w * v.w
|
||||
)
|
||||
|
||||
/**
|
||||
* Get the Euler angles in degrees from this rotation Matrix
|
||||
*
|
||||
* Don't forget to extract the rotation with [rotation] if this is a transposed matrix
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @see eulerAngles
|
||||
*/
|
||||
fun toEulerAngles(order: RotationsOrder = RotationsOrder.ZYX) = eulerAngles(this, order)
|
||||
|
||||
/**
|
||||
* Get the [Quaternion] from this rotation Matrix
|
||||
*
|
||||
* Don't forget to extract the rotation with [rotation] if this is a transposed matrix
|
||||
*
|
||||
* @see quaternion
|
||||
*/
|
||||
fun toQuaternion() = quaternion(this)
|
||||
|
||||
fun toFloatArray() = floatArrayOf(
|
||||
@@ -356,6 +432,78 @@ data class Mat4(
|
||||
}
|
||||
}
|
||||
|
||||
inline fun equal(a: Mat2, b: Float, delta: Float = 0.0f) = Bool2(
|
||||
a.x.equals(b, delta),
|
||||
a.y.equals(b, delta)
|
||||
)
|
||||
|
||||
inline fun equal(a: Mat2, b: Mat2, delta: Float = 0.0f) = Bool2(
|
||||
a.x.equals(b.x, delta),
|
||||
a.y.equals(b.y, delta)
|
||||
)
|
||||
|
||||
inline fun notEqual(a: Mat2, b: Float, delta: Float = 0.0f) = Bool2(
|
||||
!a.x.equals(b, delta),
|
||||
!a.y.equals(b, delta)
|
||||
)
|
||||
|
||||
inline fun notEqual(a: Mat2, b: Mat2, delta: Float = 0.0f) = Bool2(
|
||||
!a.x.equals(b.x, delta),
|
||||
!a.y.equals(b.y, delta)
|
||||
)
|
||||
|
||||
inline fun equal(a: Mat3, b: Float, delta: Float = 0.0f) = Bool3(
|
||||
a.x.equals(b, delta),
|
||||
a.y.equals(b, delta),
|
||||
a.z.equals(b, delta)
|
||||
)
|
||||
|
||||
inline fun equal(a: Mat3, b: Mat3, delta: Float = 0.0f) = Bool3(
|
||||
a.x.equals(b.x, delta),
|
||||
a.y.equals(b.y, delta),
|
||||
a.z.equals(b.z, delta)
|
||||
)
|
||||
|
||||
inline fun notEqual(a: Mat3, b: Float, delta: Float = 0.0f) = Bool3(
|
||||
!a.x.equals(b, delta),
|
||||
!a.y.equals(b, delta),
|
||||
!a.z.equals(b, delta)
|
||||
)
|
||||
|
||||
inline fun notEqual(a: Mat3, b: Mat3, delta: Float = 0.0f) = Bool3(
|
||||
!a.x.equals(b.x, delta),
|
||||
!a.y.equals(b.y, delta),
|
||||
!a.z.equals(b.z, delta)
|
||||
)
|
||||
|
||||
inline fun equal(a: Mat4, b: Float, delta: Float = 0.0f) = Bool4(
|
||||
a.x.equals(b, delta),
|
||||
a.y.equals(b, delta),
|
||||
a.z.equals(b, delta),
|
||||
a.w.equals(b, delta)
|
||||
)
|
||||
|
||||
inline fun equal(a: Mat4, b: Mat4, delta: Float = 0.0f) = Bool4(
|
||||
a.x.equals(b.x, delta),
|
||||
a.y.equals(b.y, delta),
|
||||
a.z.equals(b.z, delta),
|
||||
a.w.equals(b.w, delta)
|
||||
)
|
||||
|
||||
inline fun notEqual(a: Mat4, b: Float, delta: Float = 0.0f) = Bool4(
|
||||
!a.x.equals(b, delta),
|
||||
!a.y.equals(b, delta),
|
||||
!a.z.equals(b, delta),
|
||||
!a.w.equals(b, delta)
|
||||
)
|
||||
|
||||
inline fun notEqual(a: Mat4, b: Mat4, delta: Float = 0.0f) = Bool4(
|
||||
!a.x.equals(b.x, delta),
|
||||
!a.y.equals(b.y, delta),
|
||||
!a.z.equals(b.z, delta),
|
||||
!a.w.equals(b.w, delta)
|
||||
)
|
||||
|
||||
fun transpose(m: Mat2) = Mat2(
|
||||
Float2(m.x.x, m.y.x),
|
||||
Float2(m.x.y, m.y.y)
|
||||
@@ -494,14 +642,7 @@ fun rotation(m: Mat4) = Mat4(normalize(m.right), normalize(m.up), normalize(m.fo
|
||||
*/
|
||||
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)
|
||||
}
|
||||
return rotation(r[order.yaw], r[order.pitch], r[order.roll], order)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -599,13 +740,93 @@ fun rotation(quaternion: Quaternion): Mat4 {
|
||||
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),
|
||||
1.0f - 2.0f * (n.x * n.x + n.y * n.y)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract Quaternion rotation from a Matrix
|
||||
* Get the Euler angles in degrees from a rotation Matrix
|
||||
*
|
||||
* @param m The rotation matrix.
|
||||
* Don't forget to extract the rotation with [rotation] if it's transposed
|
||||
* @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.
|
||||
*/
|
||||
fun eulerAngles(m: Mat4, order: RotationsOrder = RotationsOrder.ZYX): Float3 {
|
||||
// We need to more simplify this with RotationsOrder VectorComponents mapped to MatrixColumn
|
||||
return transform(Float3().apply {
|
||||
when (order) {
|
||||
RotationsOrder.XYZ -> {
|
||||
this[order.pitch] = asin(clamp(m.z.x, -1.0f, 1.0f))
|
||||
if (abs(m.z.x) < 0.9999999f) {
|
||||
this[order.yaw] = atan2(-m.z.y, m.z.z)
|
||||
this[order.roll] = atan2(-m.y.x, m.x.x)
|
||||
} else {
|
||||
this[order.yaw] = atan2(m.y.z, m.y.y)
|
||||
this[order.roll] = 0.0f
|
||||
}
|
||||
}
|
||||
RotationsOrder.XZY -> {
|
||||
this[order.pitch] = asin(-clamp(m.y.x, -1.0f, 1.0f))
|
||||
if (abs(m.y.x) < 0.9999999f) {
|
||||
this[order.yaw] = atan2(m.y.z, m.y.y)
|
||||
this[order.roll] = atan2(m.z.x, m.x.x)
|
||||
} else {
|
||||
this[order.yaw] = atan2(-m.z.y, m.z.z)
|
||||
this[order.roll] = 0.0f
|
||||
}
|
||||
}
|
||||
RotationsOrder.YXZ -> {
|
||||
this[order.pitch] = asin(-clamp(m.z.y, -1.0f, 1.0f))
|
||||
if (abs(m.z.y) < 0.9999999f) {
|
||||
this[order.yaw] = atan2(m.z.x, m.z.z)
|
||||
this[order.roll] = atan2(m.x.y, m.y.y)
|
||||
} else {
|
||||
this[order.yaw] = atan2(-m.x.z, m.x.x)
|
||||
this[order.roll] = 0.0f
|
||||
}
|
||||
}
|
||||
RotationsOrder.YZX -> {
|
||||
this[order.pitch] = asin(clamp(m.x.y, -1.0f, 1.0f))
|
||||
if (abs(m.x.y) < 0.9999999f) {
|
||||
this[order.roll] = atan2(-m.z.y, m.y.y)
|
||||
this[order.yaw] = atan2(-m.x.z, m.x.x)
|
||||
} else {
|
||||
this[order.roll] = 0.0f
|
||||
this[order.yaw] = atan2(m.z.x, m.z.z)
|
||||
}
|
||||
}
|
||||
RotationsOrder.ZXY -> {
|
||||
this[order.pitch] = asin(clamp(m.y.z, -1.0f, 1.0f))
|
||||
if (abs(m.y.z) < 0.9999999f) {
|
||||
this[order.roll] = atan2(-m.x.z, m.z.z)
|
||||
this[order.yaw] = atan2(-m.y.x, m.y.y)
|
||||
} else {
|
||||
this[order.roll] = 0.0f
|
||||
this[order.yaw] = atan2(m.x.y, m.x.x)
|
||||
}
|
||||
}
|
||||
RotationsOrder.ZYX -> {
|
||||
this[order.pitch] = asin(-clamp(m.x.z, -1.0f, 1.0f))
|
||||
if (abs(m.x.z) < 0.9999999f) {
|
||||
this[order.roll] = atan2(m.y.z, m.z.z)
|
||||
this[order.yaw] = atan2(m.x.y, m.x.x)
|
||||
} else {
|
||||
this[order.roll] = 0.0f
|
||||
this[order.yaw] = atan2(-m.y.x, m.y.y)
|
||||
}
|
||||
}
|
||||
}
|
||||
}, ::degrees)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the [Quaternion] from a rotation Matrix
|
||||
*
|
||||
* @param m The rotation matrix.
|
||||
* Don't forget to extract the rotation with [rotation] if it's transposed
|
||||
*/
|
||||
fun quaternion(m: Mat4): Quaternion {
|
||||
val trace = m.x.x + m.y.y + m.z.z
|
||||
@@ -673,9 +894,14 @@ fun perspective(fov: Float, ratio: Float, near: Float, far: Float): Mat4 {
|
||||
}
|
||||
|
||||
fun ortho(l: Float, r: Float, b: Float, t: Float, n: Float, f: Float) = Mat4(
|
||||
Float4(x = 2.0f / (r - 1.0f)),
|
||||
Float4(y = 2.0f / (t - b)),
|
||||
Float4(z = -2.0f / (f - n)),
|
||||
Float4(-(r + l) / (r - l), -(t + b) / (t - b), -(f + n) / (f - n), 1.0f)
|
||||
Float4(x = 2.0f / (r - l)),
|
||||
Float4(y = 2.0f / (t - b)),
|
||||
Float4(z = -2.0f / (f - n)),
|
||||
Float4(
|
||||
-(r + l) / (r - l),
|
||||
-(t + b) / (t - b),
|
||||
-(f + n) / (f - n),
|
||||
1.0f
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -191,7 +191,7 @@ class ModelViewer(
|
||||
asset = assetLoader.createAsset(buffer)
|
||||
asset?.let { asset ->
|
||||
resourceLoader.asyncBeginLoad(asset)
|
||||
animator = asset.getInstance().animator
|
||||
animator = asset.instance.animator
|
||||
asset.releaseSourceData()
|
||||
}
|
||||
}
|
||||
@@ -214,7 +214,7 @@ class ModelViewer(
|
||||
resourceLoader.addResourceData(uri, resourceBuffer)
|
||||
}
|
||||
resourceLoader.asyncBeginLoad(asset)
|
||||
animator = asset.getInstance().animator
|
||||
animator = asset.instance.animator
|
||||
asset.releaseSourceData()
|
||||
}
|
||||
}
|
||||
@@ -311,7 +311,7 @@ class ModelViewer(
|
||||
var count = 0
|
||||
val popRenderables = { count = asset.popRenderables(readyRenderables); count != 0 }
|
||||
while (popRenderables()) {
|
||||
for (i in 0..count - 1) {
|
||||
for (i in 0 until count) {
|
||||
val ri = rcm.getInstance(readyRenderables[i])
|
||||
rcm.setScreenSpaceContactShadows(ri, true)
|
||||
}
|
||||
@@ -371,7 +371,7 @@ class ModelViewer(
|
||||
resourceLoader.addResourceData(uri, buffer)
|
||||
}
|
||||
resourceLoader.asyncBeginLoad(asset)
|
||||
animator = asset.getInstance().animator
|
||||
animator = asset.instance.animator
|
||||
asset.releaseSourceData()
|
||||
}
|
||||
}
|
||||
@@ -405,9 +405,19 @@ class ModelViewer(
|
||||
view.viewport = Viewport(0, 0, width, height)
|
||||
cameraManipulator.setViewport(width, height)
|
||||
updateCameraProjection()
|
||||
synchronizePendingFrames(engine)
|
||||
}
|
||||
}
|
||||
|
||||
private fun synchronizePendingFrames(engine: Engine) {
|
||||
// Wait for all pending frames to be processed before returning. This is to
|
||||
// avoid a race between the surface being resized before pending frames are
|
||||
// rendered into it.
|
||||
val fence = engine.createFence()
|
||||
fence.wait(Fence.Mode.FLUSH, Fence.WAIT_FOR_EVER)
|
||||
engine.destroyFence(fence)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val kDefaultObjectPosition = Float3(0.0f, 0.0f, -4.0f)
|
||||
}
|
||||
|
||||
@@ -33,9 +33,9 @@ data class Quaternion(
|
||||
var x: Float = 0.0f,
|
||||
var y: Float = 0.0f,
|
||||
var z: Float = 0.0f,
|
||||
var w: Float = 0.0f) {
|
||||
var w: Float = 1.0f) {
|
||||
|
||||
constructor(v: Float3, w: Float = 0.0f) : this(v.x, v.y, v.z, w)
|
||||
constructor(v: Float3, w: Float = 1.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)
|
||||
|
||||
@@ -52,42 +52,84 @@ data class Quaternion(
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a Quaternion from Euler angles using YPR around ZYX respectively
|
||||
* Construct a Quaternion from Euler angles using YPR around a specified order
|
||||
*
|
||||
* 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).
|
||||
* 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.
|
||||
*/
|
||||
fun fromEuler(d: Float3): Quaternion {
|
||||
fun fromEuler(d: Float3, order: RotationsOrder = RotationsOrder.ZYX): Quaternion {
|
||||
val r = transform(d, ::radians)
|
||||
return fromEulerZYX(r.z, r.y, r.x)
|
||||
return fromEuler(r[order.yaw], r[order.pitch], r[order.roll], order)
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a Quaternion from Euler angles using YPR around ZYX respectively
|
||||
* Construct a Quaternion from Euler yaw, pitch, roll around a specified order.
|
||||
*
|
||||
* 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
|
||||
* @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.
|
||||
*/
|
||||
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
|
||||
)
|
||||
fun fromEuler(
|
||||
yaw: Float = 0.0f,
|
||||
pitch: Float = 0.0f,
|
||||
roll: Float = 0.0f,
|
||||
order: RotationsOrder = RotationsOrder.ZYX
|
||||
): Quaternion {
|
||||
val c1 = cos(yaw * 0.5f)
|
||||
val s1 = sin(yaw * 0.5f)
|
||||
val c2 = cos(pitch * 0.5f)
|
||||
val s2 = sin(pitch * 0.5f)
|
||||
val c3 = cos(roll * 0.5f)
|
||||
val s3 = sin(roll * 0.5f)
|
||||
return when (order) {
|
||||
RotationsOrder.XZY -> Quaternion(
|
||||
s1 * c2 * c3 - c1 * s2 * s3,
|
||||
c1 * c2 * s3 - s1 * s2 * c3,
|
||||
s1 * c2 * s3 + c1 * s2 * c3,
|
||||
s1 * s2 * s3 + c1 * c2 * c3)
|
||||
RotationsOrder.XYZ -> Quaternion(
|
||||
s1 * c2 * c3 + s2 * s3 * c1,
|
||||
s2 * c1 * c3 - s1 * s3 * c2,
|
||||
s1 * s2 * c3 + s3 * c1 * c2,
|
||||
c1 * c2 * c3 - s1 * s2 * s3
|
||||
)
|
||||
RotationsOrder.YXZ -> Quaternion(
|
||||
s1 * c2 * s3 + c1 * s2 * c3,
|
||||
s1 * c2 * c3 - c1 * s2 * s3,
|
||||
c1 * c2 * s3 - s1 * s2 * c3,
|
||||
s1 * s2 * s3 + c1 * c2 * c3
|
||||
)
|
||||
RotationsOrder.YZX -> Quaternion(
|
||||
s1 * s2 * c3 + c1 * c2 * s3,
|
||||
s1 * c2 * c3 + c1 * s2 * s3,
|
||||
c1 * s2 * c3 - s1 * c2 * s3,
|
||||
c1 * c2 * c3 - s1 * s2 * s3
|
||||
)
|
||||
RotationsOrder.ZYX -> Quaternion(
|
||||
c1 * c2 * s3 - s1 * s2 * c3,
|
||||
s1 * c2 * s3 + c1 * s2 * c3,
|
||||
s1 * c2 * c3 - c1 * s2 * s3,
|
||||
s1 * s2 * s3 + c1 * c2 * c3
|
||||
)
|
||||
RotationsOrder.ZXY -> Quaternion(
|
||||
c1 * s2 * c3 - s1 * c2 * s3,
|
||||
s1 * s2 * c3 + c1 * c2 * s3,
|
||||
s1 * c2 * c3 + c1 * s2 * s3,
|
||||
c1 * c2 * c3 - s1 * s2 * s3
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,16 +264,44 @@ data class Quaternion(
|
||||
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 fun compareTo(v: Float, delta: Float = 0.0f) = Float4(
|
||||
x.compareTo(v, delta),
|
||||
y.compareTo(v, delta),
|
||||
z.compareTo(v, delta),
|
||||
w.compareTo(v, delta)
|
||||
)
|
||||
|
||||
inline fun equals(v: Float, delta: Float = 0.0f) = Bool4(
|
||||
x.equals(v, delta),
|
||||
y.equals(v, delta),
|
||||
z.equals(v, delta),
|
||||
w.equals(v, delta)
|
||||
)
|
||||
|
||||
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)
|
||||
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 compareTo(v: Float4, delta: Float = 0.0f) = Float4(
|
||||
x.compareTo(v.x, delta),
|
||||
y.compareTo(v.y, delta),
|
||||
z.compareTo(v.z, delta),
|
||||
w.compareTo(v.w, delta)
|
||||
)
|
||||
|
||||
inline fun equals(v: Float4, delta: Float = 0.0f) = Bool4(
|
||||
x.equals(v.x, delta),
|
||||
y.equals(v.y, delta),
|
||||
z.equals(v.z, delta),
|
||||
w.equals(v.w, delta)
|
||||
)
|
||||
|
||||
inline fun transform(block: (Float) -> Float): Quaternion {
|
||||
x = block(x)
|
||||
@@ -253,6 +323,103 @@ inline operator fun Float.minus(q: Quaternion) = Quaternion(this - q.x, this - q
|
||||
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 lessThan(a: Quaternion, b: Float) = Bool4(
|
||||
a.x < b,
|
||||
a.y < b,
|
||||
a.z < b,
|
||||
a.w < b
|
||||
)
|
||||
|
||||
inline fun lessThan(a: Quaternion, b: Quaternion) = Bool4(
|
||||
a.x < b.x,
|
||||
a.y < b.y,
|
||||
a.z < b.z,
|
||||
a.w < b.w
|
||||
)
|
||||
|
||||
inline fun lessThanEqual(a: Quaternion, b: Float) = Bool4(
|
||||
a.x <= b,
|
||||
a.y <= b,
|
||||
a.z <= b,
|
||||
a.w <= b
|
||||
)
|
||||
|
||||
inline fun lessThanEqual(a: Quaternion, b: Quaternion) = Bool4(
|
||||
a.x <= b.x,
|
||||
a.y <= b.y,
|
||||
a.z <= b.z,
|
||||
a.w <= b.w
|
||||
)
|
||||
|
||||
inline fun greaterThan(a: Quaternion, b: Float) = Bool4(
|
||||
a.x > b,
|
||||
a.y > b,
|
||||
a.z > b,
|
||||
a.w > b
|
||||
)
|
||||
|
||||
inline fun greaterThan(a: Quaternion, b: Quaternion) = Bool4(
|
||||
a.x > b.y,
|
||||
a.y > b.y,
|
||||
a.z > b.z,
|
||||
a.w > b.w
|
||||
)
|
||||
|
||||
inline fun greaterThanEqual(a: Quaternion, b: Float) = Bool4(
|
||||
a.x >= b,
|
||||
a.y >= b,
|
||||
a.z >= b,
|
||||
a.w >= b
|
||||
)
|
||||
|
||||
inline fun greaterThanEqual(a: Quaternion, b: Quaternion) = Bool4(
|
||||
a.x >= b.x,
|
||||
a.y >= b.y,
|
||||
a.z >= b.z,
|
||||
a.w >= b.w
|
||||
)
|
||||
|
||||
inline fun equal(a: Quaternion, b: Float, delta: Float = 0.0f) = Bool4(
|
||||
a.x.equals(b, delta),
|
||||
a.y.equals(b, delta),
|
||||
a.z.equals(b, delta),
|
||||
a.w.equals(b, delta)
|
||||
)
|
||||
|
||||
inline fun equal(a: Quaternion, b: Quaternion, delta: Float = 0.0f) = Bool4(
|
||||
a.x.equals(b.x, delta),
|
||||
a.y.equals(b.y, delta),
|
||||
a.z.equals(b.z, delta),
|
||||
a.w.equals(b.w, delta)
|
||||
)
|
||||
|
||||
inline fun notEqual(a: Quaternion, b: Float, delta: Float = 0.0f) = Bool4(
|
||||
!a.x.equals(b, delta),
|
||||
!a.y.equals(b, delta),
|
||||
!a.z.equals(b, delta),
|
||||
!a.w.equals(b, delta)
|
||||
)
|
||||
|
||||
inline fun notEqual(a: Quaternion, b: Quaternion, delta: Float = 0.0f) = Bool4(
|
||||
!a.x.equals(b.x, delta),
|
||||
!a.y.equals(b.y, delta),
|
||||
!a.z.equals(b.z, delta),
|
||||
!a.w.equals(b.w, delta)
|
||||
)
|
||||
|
||||
inline infix fun Quaternion.lt(b: Float) = Bool4(x < b, y < b, z < b, w < b)
|
||||
inline infix fun Quaternion.lt(b: Float4) = Bool4(x < b.x, y < b.y, z < b.z, w < b.w)
|
||||
inline infix fun Quaternion.lte(b: Float) = Bool4(x <= b, y <= b, z <= b, w <= b)
|
||||
inline infix fun Quaternion.lte(b: Float4) = Bool4(x <= b.x, y <= b.y, z <= b.z, w <= b.w)
|
||||
inline infix fun Quaternion.gt(b: Float) = Bool4(x > b, y > b, z > b, w > b)
|
||||
inline infix fun Quaternion.gt(b: Float4) = Bool4(x > b.x, y > b.y, z > b.z, w > b.w)
|
||||
inline infix fun Quaternion.gte(b: Float) = Bool4(x >= b, y >= b, z >= b, w >= b)
|
||||
inline infix fun Quaternion.gte(b: Float4) = Bool4(x >= b.x, y >= b.y, z >= b.z, w >= b.w)
|
||||
inline infix fun Quaternion.eq(b: Float) = Bool4(x == b, y == b, z == b, w == b)
|
||||
inline infix fun Quaternion.eq(b: Float4) = Bool4(x == b.x, y == b.y, z == b.z, w == b.w)
|
||||
inline infix fun Quaternion.neq(b: Float) = Bool4(x != b, y != b, z != b, w != b)
|
||||
inline infix fun Quaternion.neq(b: Float4) = Bool4(x != b.x, y != b.y, z != b.z, w != b.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
|
||||
@@ -278,6 +445,10 @@ fun cross(a: Quaternion, b: Quaternion): Quaternion {
|
||||
return Quaternion(m.x, m.y, m.z, 0.0f)
|
||||
}
|
||||
|
||||
fun angle(a: Quaternion, b: Quaternion): Float {
|
||||
return 2.0f * acos(abs(clamp(dot(a, b), -1.0f, 1.0f)))
|
||||
}
|
||||
|
||||
/**
|
||||
* Spherical linear interpolation between two given orientations
|
||||
*
|
||||
@@ -287,36 +458,38 @@ fun cross(a: Quaternion, b: Quaternion): Quaternion {
|
||||
* @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.
|
||||
* @param dotThreshold If the quaternion dot product is greater than this value
|
||||
* (i.e. the quaternions are very close to each other), then the quaternions are
|
||||
* linearly interpolated instead of spherically interpolated.
|
||||
*
|
||||
* @return Interpolated value between the two floats
|
||||
*/
|
||||
fun slerp(a: Quaternion, b: Quaternion, t: Float, valueEps: Float = 0.0000000001f): Quaternion {
|
||||
fun slerp(a: Quaternion, b: Quaternion, t: Float, dotThreshold: Float = 0.9995f): Quaternion {
|
||||
// could also be computed as: pow(q * inverse(p), t) * p;
|
||||
val d = dot(a, b)
|
||||
val absd = abs(d)
|
||||
var dot = dot(a, b)
|
||||
var b1 = b
|
||||
|
||||
// If the dot product is negative, then the interpolation won't follow the shortest angular path
|
||||
// between the two quaterions. In this case, invert the end quaternion to produce an equivalent
|
||||
// rotation that will give us the path we want.
|
||||
if (dot < 0.0f) {
|
||||
dot = -dot
|
||||
b1 = -b
|
||||
}
|
||||
|
||||
// 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))
|
||||
return if (dot < dotThreshold) {
|
||||
val angle = acos(dot)
|
||||
val s = sin(angle)
|
||||
a * sin((1.0f - t) * angle) / s + b1 * sin(t * angle) / s
|
||||
} else {
|
||||
// If the angle is too small, use linear interpolation
|
||||
nlerp(a, b1, 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)
|
||||
return ((1.0f - t) * a) + (t * b)
|
||||
}
|
||||
|
||||
fun nlerp(a: Quaternion, b: Quaternion, t: Float): Quaternion {
|
||||
@@ -324,19 +497,12 @@ fun nlerp(a: Quaternion, b: Quaternion, t: Float): Quaternion {
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a Quaternion to Euler angles using YPR around ZYX respectively
|
||||
* Convert a Quaternion to Euler angles
|
||||
*
|
||||
* The Euler angles are applied in 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.
|
||||
*/
|
||||
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)))
|
||||
fun eulerAngles(q: Quaternion, order: RotationsOrder = RotationsOrder.ZYX): Float3 {
|
||||
return eulerAngles(rotation(q), order)
|
||||
}
|
||||
|
||||
@@ -28,12 +28,21 @@ const val INV_PI = 1.0f / FPI
|
||||
const val INV_TWO_PI = INV_PI * 0.5f
|
||||
const val INV_FOUR_PI = INV_PI * 0.25f
|
||||
|
||||
inline fun clamp(x: Float, min: Float, max: Float)= if (x < min) min else (if (x > max) max else x)
|
||||
val HALF_ONE = Half(0x3c00.toUShort())
|
||||
val HALF_TWO = Half(0x4000.toUShort())
|
||||
|
||||
inline fun clamp(x: Float, min: Float, max: Float) = if (x < min) min else (if (x > max) max else x)
|
||||
|
||||
inline fun clamp(x: Half, min: Half, max: Half) = if (x < min) min else (if (x > max) max else x)
|
||||
|
||||
inline fun saturate(x: Float) = clamp(x, 0.0f, 1.0f)
|
||||
|
||||
inline fun saturate(x: Half) = clamp(x, Half.POSITIVE_ZERO, HALF_ONE)
|
||||
|
||||
inline fun mix(a: Float, b: Float, x: Float) = a * (1.0f - x) + b * x
|
||||
|
||||
inline fun mix(a: Half, b: Half, x: Half) = a * (HALF_ONE - x) + b * x
|
||||
|
||||
inline fun degrees(v: Float) = v * (180.0f * INV_PI)
|
||||
|
||||
inline fun radians(v: Float) = v * (FPI / 180.0f)
|
||||
@@ -42,4 +51,6 @@ inline fun fract(v: Float) = v % 1
|
||||
|
||||
inline fun sqr(v: Float) = v * v
|
||||
|
||||
inline fun sqr(v: Half) = v * v
|
||||
|
||||
inline fun pow(x: Float, y: Float) = (x.toDouble().pow(y.toDouble())).toFloat()
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.android.filament.textured
|
||||
package com.google.android.filament.utils
|
||||
|
||||
import android.content.res.Resources
|
||||
import android.graphics.Bitmap
|
||||
|
||||
@@ -22,6 +22,8 @@ import kotlin.math.abs
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
import kotlin.math.sqrt
|
||||
import kotlin.math.acos
|
||||
import kotlin.math.absoluteValue
|
||||
|
||||
enum class VectorComponent {
|
||||
X, Y, Z, W,
|
||||
@@ -124,11 +126,23 @@ data class Float2(var x: Float = 0.0f, var y: Float = 0.0f) {
|
||||
inline operator fun minus(v: Float) = Float2(x - v, y - v)
|
||||
inline operator fun times(v: Float) = Float2(x * v, y * v)
|
||||
inline operator fun div(v: Float) = Float2(x / v, y / v)
|
||||
inline fun compareTo(v: Float, delta: Float = 0.0f) = Float2(
|
||||
x.compareTo(v, delta),
|
||||
y.compareTo(v, delta)
|
||||
)
|
||||
|
||||
inline fun equals(v: Float, delta: Float = 0.0f) = x.equals(v, delta) && y.equals(v, delta)
|
||||
|
||||
inline operator fun plus(v: Float2) = Float2(x + v.x, y + v.y)
|
||||
inline operator fun minus(v: Float2) = Float2(x - v.x, y - v.y)
|
||||
inline operator fun times(v: Float2) = Float2(x * v.x, y * v.y)
|
||||
inline operator fun div(v: Float2) = Float2(x / v.x, y / v.y)
|
||||
inline fun compareTo(v: Float2, delta: Float = 0.0f) = Float2(
|
||||
x.compareTo(v.x, delta),
|
||||
y.compareTo(v.y, delta)
|
||||
)
|
||||
|
||||
inline fun equals(v: Float2, delta: Float = 0.0f) = x.equals(v.x, delta) && y.equals(v.y, delta)
|
||||
|
||||
inline fun transform(block: (Float) -> Float): Float2 {
|
||||
x = block(x)
|
||||
@@ -291,6 +305,14 @@ data class Float3(var x: Float = 0.0f, var y: Float = 0.0f, var z: Float = 0.0f)
|
||||
inline operator fun minus(v: Float) = Float3(x - v, y - v, z - v)
|
||||
inline operator fun times(v: Float) = Float3(x * v, y * v, z * v)
|
||||
inline operator fun div(v: Float) = Float3(x / v, y / v, z / v)
|
||||
inline fun compareTo(v: Float, delta: Float = 0.0f) = Float3(
|
||||
x.compareTo(v, delta),
|
||||
y.compareTo(v, delta),
|
||||
z.compareTo(v, delta)
|
||||
)
|
||||
|
||||
inline fun equals(v: Float, delta: Float = 0.0f) =
|
||||
x.equals(v, delta) && y.equals(v, delta) && z.equals(v, delta)
|
||||
|
||||
inline operator fun plus(v: Float2) = Float3(x + v.x, y + v.y, z)
|
||||
inline operator fun minus(v: Float2) = Float3(x - v.x, y - v.y, z)
|
||||
@@ -301,6 +323,14 @@ data class Float3(var x: Float = 0.0f, var y: Float = 0.0f, var z: Float = 0.0f)
|
||||
inline operator fun minus(v: Float3) = Float3(x - v.x, y - v.y, z - v.z)
|
||||
inline operator fun times(v: Float3) = Float3(x * v.x, y * v.y, z * v.z)
|
||||
inline operator fun div(v: Float3) = Float3(x / v.x, y / v.y, z / v.z)
|
||||
inline fun compareTo(v: Float3, delta: Float = 0.0f) = Float3(
|
||||
x.compareTo(v.x, delta),
|
||||
y.compareTo(v.y, delta),
|
||||
z.compareTo(v.z, delta)
|
||||
)
|
||||
|
||||
inline fun equals(v: Float3, delta: Float = 0.0f) =
|
||||
x.equals(v.x, delta) && y.equals(v.y, delta) && z.equals(v.z, delta)
|
||||
|
||||
inline fun transform(block: (Float) -> Float): Float3 {
|
||||
x = block(x)
|
||||
@@ -534,6 +564,15 @@ data class Float4(
|
||||
inline operator fun minus(v: Float) = Float4(x - v, y - v, z - v, w - v)
|
||||
inline operator fun times(v: Float) = Float4(x * v, y * v, z * v, w * v)
|
||||
inline operator fun div(v: Float) = Float4(x / v, y / v, z / v, w / v)
|
||||
inline fun compareTo(v: Float, delta: Float = 0.0f) = Float4(
|
||||
x.compareTo(v, delta),
|
||||
y.compareTo(v, delta),
|
||||
z.compareTo(v, delta),
|
||||
w.compareTo(v, delta)
|
||||
)
|
||||
|
||||
inline fun equals(v: Float, delta: Float = 0.0f) =
|
||||
x.equals(v, delta) && y.equals(v, delta) && z.equals(v, delta) && w.equals(v, delta)
|
||||
|
||||
inline operator fun plus(v: Float2) = Float4(x + v.x, y + v.y, z, w)
|
||||
inline operator fun minus(v: Float2) = Float4(x - v.x, y - v.y, z, w)
|
||||
@@ -549,6 +588,15 @@ data class Float4(
|
||||
inline operator fun minus(v: Float4) = Float4(x - v.x, y - v.y, z - v.z, w - v.w)
|
||||
inline operator fun times(v: Float4) = Float4(x * v.x, y * v.y, z * v.z, w * v.w)
|
||||
inline operator fun div(v: Float4) = Float4(x / v.x, y / v.y, z / v.z, w / v.w)
|
||||
inline fun compareTo(v: Float4, delta: Float = 0.0f) = Float4(
|
||||
x.compareTo(v.x, delta),
|
||||
y.compareTo(v.y, delta),
|
||||
z.compareTo(v.z, delta),
|
||||
w.compareTo(v.w, delta)
|
||||
)
|
||||
|
||||
inline fun equals(v: Float4, delta: Float = 0.0f) =
|
||||
x.equals(v.x, delta) && y.equals(v.y, delta) && z.equals(v.z, delta) && w.equals(v.w, delta)
|
||||
|
||||
inline fun transform(block: (Float) -> Float): Float4 {
|
||||
x = block(x)
|
||||
@@ -566,6 +614,12 @@ inline operator fun Float.minus(v: Float2) = Float2(this - v.x, this - v.y)
|
||||
inline operator fun Float.times(v: Float2) = Float2(this * v.x, this * v.y)
|
||||
inline operator fun Float.div(v: Float2) = Float2(this / v.x, this / v.y)
|
||||
|
||||
inline fun Float.compareTo(v: Float, delta: Float): Float = when {
|
||||
equals(v, delta) -> 0.0f
|
||||
else -> compareTo(v).toFloat()
|
||||
}
|
||||
|
||||
inline fun Float.equals(v: Float, delta: Float) = (this - v).absoluteValue < delta
|
||||
inline fun abs(v: Float2) = Float2(abs(v.x), abs(v.y))
|
||||
inline fun length(v: Float2) = sqrt(v.x * v.x + v.y * v.y)
|
||||
inline fun length2(v: Float2) = v.x * v.x + v.y * v.y
|
||||
@@ -583,6 +637,11 @@ fun refract(i: Float2, n: Float2, eta: Float): Float2 {
|
||||
return if (k < 0.0f) Float2(0.0f) else eta * i - (eta * d + sqrt(k)) * n
|
||||
}
|
||||
|
||||
inline fun angle(a: Float2, b: Float2): Float {
|
||||
val l = length(a) * length(b)
|
||||
return if (l == 0.0f) 0.0f else acos(clamp(dot(a, b) / l, -1.0f, 1.0f))
|
||||
}
|
||||
|
||||
inline fun clamp(v: Float2, min: Float, max: Float): Float2 {
|
||||
return Float2(
|
||||
clamp(v.x, min, max),
|
||||
@@ -626,10 +685,25 @@ inline fun greaterThan(a: Float2, b: Float) = Bool2(a.x > b, a.y > b)
|
||||
inline fun greaterThan(a: Float2, b: Float2) = Bool2(a.x > b.y, a.y > b.y)
|
||||
inline fun greaterThanEqual(a: Float2, b: Float) = Bool2(a.x >= b, a.y >= b)
|
||||
inline fun greaterThanEqual(a: Float2, b: Float2) = Bool2(a.x >= b.x, a.y >= b.y)
|
||||
inline fun equal(a: Float2, b: Float) = Bool2(a.x == b, a.y == b)
|
||||
inline fun equal(a: Float2, b: Float2) = Bool2(a.x == b.x, a.y == b.y)
|
||||
inline fun notEqual(a: Float2, b: Float) = Bool2(a.x != b, a.y != b)
|
||||
inline fun notEqual(a: Float2, b: Float2) = Bool2(a.x != b.x, a.y != b.y)
|
||||
inline fun equal(a: Float2, b: Float, delta: Float = 0.0f) = Bool2(
|
||||
a.x.equals(b, delta),
|
||||
a.y.equals(b, delta)
|
||||
)
|
||||
|
||||
inline fun equal(a: Float2, b: Float2, delta: Float = 0.0f) = Bool2(
|
||||
a.x.equals(b.x, delta),
|
||||
a.y.equals(b.y, delta)
|
||||
)
|
||||
|
||||
inline fun notEqual(a: Float2, b: Float, delta: Float = 0.0f) = Bool2(
|
||||
!a.x.equals(b, delta),
|
||||
!a.y.equals(b, delta)
|
||||
)
|
||||
|
||||
inline fun notEqual(a: Float2, b: Float2, delta: Float = 0.0f) = Bool2(
|
||||
!a.x.equals(b.x, delta),
|
||||
!a.y.equals(b.y, delta)
|
||||
)
|
||||
|
||||
inline infix fun Float2.lt(b: Float) = Bool2(x < b, y < b)
|
||||
inline infix fun Float2.lt(b: Float2) = Bool2(x < b.x, y < b.y)
|
||||
@@ -675,6 +749,11 @@ fun refract(i: Float3, n: Float3, eta: Float): Float3 {
|
||||
return if (k < 0.0f) Float3(0.0f) else eta * i - (eta * d + sqrt(k)) * n
|
||||
}
|
||||
|
||||
inline fun angle(a: Float3, b: Float3): Float {
|
||||
val l = length(a) * length(b)
|
||||
return if (l == 0.0f) 0.0f else acos(clamp(dot(a, b) / l, -1.0f, 1.0f))
|
||||
}
|
||||
|
||||
inline fun clamp(v: Float3, min: Float, max: Float): Float3 {
|
||||
return Float3(
|
||||
clamp(v.x, min, max),
|
||||
@@ -722,10 +801,29 @@ inline fun greaterThan(a: Float3, b: Float) = Bool3(a.x > b, a.y > b, a.z > b)
|
||||
inline fun greaterThan(a: Float3, b: Float3) = Bool3(a.x > b.y, a.y > b.y, a.z > b.z)
|
||||
inline fun greaterThanEqual(a: Float3, b: Float) = Bool3(a.x >= b, a.y >= b, a.z >= b)
|
||||
inline fun greaterThanEqual(a: Float3, b: Float3) = Bool3(a.x >= b.x, a.y >= b.y, a.z >= b.z)
|
||||
inline fun equal(a: Float3, b: Float) = Bool3(a.x == b, a.y == b, a.z == b)
|
||||
inline fun equal(a: Float3, b: Float3) = Bool3(a.x == b.x, a.y == b.y, a.z == b.z)
|
||||
inline fun notEqual(a: Float3, b: Float) = Bool3(a.x != b, a.y != b, a.z != b)
|
||||
inline fun notEqual(a: Float3, b: Float3) = Bool3(a.x != b.x, a.y != b.y, a.z != b.z)
|
||||
inline fun equal(a: Float3, b: Float, delta: Float = 0.0f) = Bool3(
|
||||
a.x.equals(b, delta),
|
||||
a.y.equals(b, delta),
|
||||
a.z.equals(b, delta)
|
||||
)
|
||||
|
||||
inline fun equal(a: Float3, b: Float3, delta: Float = 0.0f) = Bool3(
|
||||
a.x.equals(b.x, delta),
|
||||
a.y.equals(b.y, delta),
|
||||
a.z.equals(b.z, delta)
|
||||
)
|
||||
|
||||
inline fun notEqual(a: Float3, b: Float, delta: Float = 0.0f) = Bool3(
|
||||
!a.x.equals(b, delta),
|
||||
!a.y.equals(b, delta),
|
||||
!a.z.equals(b, delta)
|
||||
)
|
||||
|
||||
inline fun notEqual(a: Float3, b: Float3, delta: Float = 0.0f) = Bool3(
|
||||
!a.x.equals(b.x, delta),
|
||||
!a.y.equals(b.y, delta),
|
||||
!a.z.equals(b.z, delta)
|
||||
)
|
||||
|
||||
inline infix fun Float3.lt(b: Float) = Bool3(x < b, y < b, z < b)
|
||||
inline infix fun Float3.lt(b: Float3) = Bool3(x < b.x, y < b.y, z < b.z)
|
||||
@@ -807,17 +905,44 @@ inline fun transform(v: Float4, block: (Float) -> Float) = v.copy().transform(bl
|
||||
inline fun lessThan(a: Float4, b: Float) = Bool4(a.x < b, a.y < b, a.z < b, a.w < b)
|
||||
inline fun lessThan(a: Float4, b: Float4) = Bool4(a.x < b.x, a.y < b.y, a.z < b.z, a.w < b.w)
|
||||
inline fun lessThanEqual(a: Float4, b: Float) = Bool4(a.x <= b, a.y <= b, a.z <= b, a.w <= b)
|
||||
inline fun lessThanEqual(a: Float4, b: Float4) = Bool4(a.x <= b.x, a.y <= b.y, a.z <= b.z, a.w <= b.w)
|
||||
inline fun lessThanEqual(a: Float4, b: Float4) =
|
||||
Bool4(a.x <= b.x, a.y <= b.y, a.z <= b.z, a.w <= b.w)
|
||||
|
||||
inline fun greaterThan(a: Float4, b: Float) = Bool4(a.x > b, a.y > b, a.z > b, a.w > b)
|
||||
inline fun greaterThan(a: Float4, b: Float4) = Bool4(a.x > b.y, a.y > b.y, a.z > b.z, a.w > b.w)
|
||||
inline fun greaterThanEqual(a: Float4, b: Float) = Bool4(a.x >= b, a.y >= b, a.z >= b, a.w >= b)
|
||||
inline fun greaterThanEqual(a: Float4, b: Float4) = Bool4(a.x >= b.x, a.y >= b.y, a.z >= b.z, a.w >= b.w)
|
||||
inline fun equal(a: Float4, b: Float) = Bool4(a.x == b, a.y == b, a.z == b, a.w == b)
|
||||
inline fun equal(a: Float4, b: Float4) = Bool4(a.x == b.x, a.y == b.y, a.z == b.z, a.w == b.w)
|
||||
inline fun notEqual(a: Float4, b: Float) = Bool4(a.x != b, a.y != b, a.z != b, a.w != b)
|
||||
inline fun notEqual(a: Float4, b: Float4) = Bool4(a.x != b.x, a.y != b.y, a.z != b.z, a.w != b.w)
|
||||
inline fun greaterThanEqual(a: Float4, b: Float4) =
|
||||
Bool4(a.x >= b.x, a.y >= b.y, a.z >= b.z, a.w >= b.w)
|
||||
|
||||
inline infix fun Float4.lt(b: Float) = Bool4(x < b, y < b, z < b, a < b)
|
||||
inline fun equal(a: Float4, b: Float, delta: Float = 0.0f) = Bool4(
|
||||
a.x.equals(b, delta),
|
||||
a.y.equals(b, delta),
|
||||
a.z.equals(b, delta),
|
||||
a.w.equals(b, delta)
|
||||
)
|
||||
|
||||
inline fun equal(a: Float4, b: Float4, delta: Float = 0.0f) = Bool4(
|
||||
a.x.equals(b.x, delta),
|
||||
a.y.equals(b.y, delta),
|
||||
a.z.equals(b.z, delta),
|
||||
a.w.equals(b.w, delta)
|
||||
)
|
||||
|
||||
inline fun notEqual(a: Float4, b: Float, delta: Float = 0.0f) = Bool4(
|
||||
!a.x.equals(b, delta),
|
||||
!a.y.equals(b, delta),
|
||||
!a.z.equals(b, delta),
|
||||
!a.w.equals(b, delta)
|
||||
)
|
||||
|
||||
inline fun notEqual(a: Float4, b: Float4, delta: Float = 0.0f) = Bool4(
|
||||
!a.x.equals(b.x, delta),
|
||||
!a.y.equals(b.y, delta),
|
||||
!a.z.equals(b.z, delta),
|
||||
!a.w.equals(b.w, delta)
|
||||
)
|
||||
|
||||
inline infix fun Float4.lt(b: Float) = Bool4(x < b, y < b, z < b, w < b)
|
||||
inline infix fun Float4.lt(b: Float4) = Bool4(x < b.x, y < b.y, z < b.z, w < b.w)
|
||||
inline infix fun Float4.lte(b: Float) = Bool4(x <= b, y <= b, z <= b, w <= b)
|
||||
inline infix fun Float4.lte(b: Float4) = Bool4(x <= b.x, y <= b.y, z <= b.z, w <= b.w)
|
||||
@@ -1277,3 +1402,753 @@ data class Bool4(
|
||||
set(index4, v)
|
||||
}
|
||||
}
|
||||
|
||||
data class Half2(var x: Half = Half.POSITIVE_ZERO, var y: Half = Half.POSITIVE_ZERO) {
|
||||
constructor(v: Half) : this(v, v)
|
||||
constructor(v: Half2) : this(v.x, v.y)
|
||||
|
||||
inline var r: Half
|
||||
get() = x
|
||||
set(value) {
|
||||
x = value
|
||||
}
|
||||
inline var g: Half
|
||||
get() = y
|
||||
set(value) {
|
||||
y = value
|
||||
}
|
||||
|
||||
inline var s: Half
|
||||
get() = x
|
||||
set(value) {
|
||||
x = value
|
||||
}
|
||||
inline var t: Half
|
||||
get() = y
|
||||
set(value) {
|
||||
y = value
|
||||
}
|
||||
|
||||
inline var xy: Half2
|
||||
get() = Half2(x, y)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
}
|
||||
inline var rg: Half2
|
||||
get() = Half2(x, y)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
}
|
||||
inline var st: Half2
|
||||
get() = Half2(x, y)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
}
|
||||
|
||||
operator fun get(index: VectorComponent) = when (index) {
|
||||
VectorComponent.X, VectorComponent.R, VectorComponent.S -> x
|
||||
VectorComponent.Y, VectorComponent.G, VectorComponent.T -> y
|
||||
else -> throw IllegalArgumentException("index must be X, Y, R, G, S or T")
|
||||
}
|
||||
|
||||
operator fun get(index1: VectorComponent, index2: VectorComponent): Half2 {
|
||||
return Half2(get(index1), get(index2))
|
||||
}
|
||||
|
||||
operator fun get(index: Int) = when (index) {
|
||||
0 -> x
|
||||
1 -> y
|
||||
else -> throw IllegalArgumentException("index must be in 0..1")
|
||||
}
|
||||
|
||||
operator fun get(index1: Int, index2: Int) = Half2(get(index1), get(index2))
|
||||
|
||||
inline operator fun invoke(index: Int) = get(index - 1)
|
||||
|
||||
operator fun set(index: Int, v: Half) = when (index) {
|
||||
0 -> x = v
|
||||
1 -> y = v
|
||||
else -> throw IllegalArgumentException("index must be in 0..1")
|
||||
}
|
||||
|
||||
operator fun set(index1: Int, index2: Int, v: Half) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
}
|
||||
|
||||
operator fun set(index: VectorComponent, v: Half) = when (index) {
|
||||
VectorComponent.X, VectorComponent.R, VectorComponent.S -> x = v
|
||||
VectorComponent.Y, VectorComponent.G, VectorComponent.T -> y = v
|
||||
else -> throw IllegalArgumentException("index must be X, Y, R, G, S or T")
|
||||
}
|
||||
|
||||
operator fun set(index1: VectorComponent, index2: VectorComponent, v: Half) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
}
|
||||
|
||||
operator fun unaryMinus() = Half2(-x, -y)
|
||||
operator fun inc() = Half2(x++, y++)
|
||||
operator fun dec() = Half2(x--, y--)
|
||||
|
||||
inline operator fun plus(v: Half) = Half2(x + v, y + v)
|
||||
inline operator fun minus(v: Half) = Half2(x - v, y - v)
|
||||
inline operator fun times(v: Half) = Half2(x * v, y * v)
|
||||
inline operator fun div(v: Half) = Half2(x / v, y / v)
|
||||
|
||||
inline operator fun plus(v: Half2) = Half2(x + v.x, y + v.y)
|
||||
inline operator fun minus(v: Half2) = Half2(x - v.x, y - v.y)
|
||||
inline operator fun times(v: Half2) = Half2(x * v.x, y * v.y)
|
||||
inline operator fun div(v: Half2) = Half2(x / v.x, y / v.y)
|
||||
|
||||
inline fun transform(block: (Half) -> Half): Half2 {
|
||||
x = block(x)
|
||||
y = block(y)
|
||||
return this
|
||||
}
|
||||
|
||||
fun toFloatArray() = floatArrayOf(x.toFloat(), y.toFloat())
|
||||
}
|
||||
|
||||
data class Half3(
|
||||
var x: Half = Half.POSITIVE_ZERO,
|
||||
var y: Half = Half.POSITIVE_ZERO,
|
||||
var z: Half = Half.POSITIVE_ZERO
|
||||
) {
|
||||
constructor(v: Half) : this(v, v, v)
|
||||
constructor(v: Half2, z: Half = Half.POSITIVE_ZERO) : this(v.x, v.y, z)
|
||||
constructor(v: Half3) : this(v.x, v.y, v.z)
|
||||
|
||||
inline var r: Half
|
||||
get() = x
|
||||
set(value) {
|
||||
x = value
|
||||
}
|
||||
inline var g: Half
|
||||
get() = y
|
||||
set(value) {
|
||||
y = value
|
||||
}
|
||||
inline var b: Half
|
||||
get() = z
|
||||
set(value) {
|
||||
z = value
|
||||
}
|
||||
|
||||
inline var s: Half
|
||||
get() = x
|
||||
set(value) {
|
||||
x = value
|
||||
}
|
||||
inline var t: Half
|
||||
get() = y
|
||||
set(value) {
|
||||
y = value
|
||||
}
|
||||
inline var p: Half
|
||||
get() = z
|
||||
set(value) {
|
||||
z = value
|
||||
}
|
||||
|
||||
inline var xy: Half2
|
||||
get() = Half2(x, y)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
}
|
||||
inline var rg: Half2
|
||||
get() = Half2(x, y)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
}
|
||||
inline var st: Half2
|
||||
get() = Half2(x, y)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
}
|
||||
|
||||
inline var rgb: Half3
|
||||
get() = Half3(x, y, z)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
z = value.z
|
||||
}
|
||||
inline var xyz: Half3
|
||||
get() = Half3(x, y, z)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
z = value.z
|
||||
}
|
||||
inline var stp: Half3
|
||||
get() = Half3(x, y, z)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
z = value.z
|
||||
}
|
||||
|
||||
operator fun get(index: VectorComponent) = when (index) {
|
||||
VectorComponent.X, VectorComponent.R, VectorComponent.S -> x
|
||||
VectorComponent.Y, VectorComponent.G, VectorComponent.T -> y
|
||||
VectorComponent.Z, VectorComponent.B, VectorComponent.P -> z
|
||||
else -> throw IllegalArgumentException("index must be X, Y, Z, R, G, B, S, T or P")
|
||||
}
|
||||
|
||||
operator fun get(index1: VectorComponent, index2: VectorComponent): Half2 {
|
||||
return Half2(get(index1), get(index2))
|
||||
}
|
||||
operator fun get(
|
||||
index1: VectorComponent, index2: VectorComponent, index3: VectorComponent): Half3 {
|
||||
return Half3(get(index1), get(index2), get(index3))
|
||||
}
|
||||
|
||||
operator fun get(index: Int) = when (index) {
|
||||
0 -> x
|
||||
1 -> y
|
||||
2 -> z
|
||||
else -> throw IllegalArgumentException("index must be in 0..2")
|
||||
}
|
||||
|
||||
operator fun get(index1: Int, index2: Int) = Half2(get(index1), get(index2))
|
||||
operator fun get(index1: Int, index2: Int, index3: Int): Half3 {
|
||||
return Half3(get(index1), get(index2), get(index3))
|
||||
}
|
||||
|
||||
inline operator fun invoke(index: Int) = get(index - 1)
|
||||
|
||||
operator fun set(index: Int, v: Half) = when (index) {
|
||||
0 -> x = v
|
||||
1 -> y = v
|
||||
2 -> z = v
|
||||
else -> throw IllegalArgumentException("index must be in 0..2")
|
||||
}
|
||||
|
||||
operator fun set(index1: Int, index2: Int, v: Half) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
}
|
||||
|
||||
operator fun set(index1: Int, index2: Int, index3: Int, v: Half) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
set(index3, v)
|
||||
}
|
||||
|
||||
operator fun set(index: VectorComponent, v: Half) = when (index) {
|
||||
VectorComponent.X, VectorComponent.R, VectorComponent.S -> x = v
|
||||
VectorComponent.Y, VectorComponent.G, VectorComponent.T -> y = v
|
||||
VectorComponent.Z, VectorComponent.B, VectorComponent.P -> z = v
|
||||
else -> throw IllegalArgumentException("index must be X, Y, Z, R, G, B, S, T or P")
|
||||
}
|
||||
|
||||
operator fun set(index1: VectorComponent, index2: VectorComponent, v: Half) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
}
|
||||
|
||||
operator fun set(
|
||||
index1: VectorComponent, index2: VectorComponent, index3: VectorComponent, v: Half) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
set(index3, v)
|
||||
}
|
||||
|
||||
operator fun unaryMinus() = Half3(-x, -y, -z)
|
||||
operator fun inc() = Half3(x++, y++, z++)
|
||||
operator fun dec() = Half3(x--, y--, z--)
|
||||
|
||||
inline operator fun plus(v: Half) = Half3(x + v, y + v, z + v)
|
||||
inline operator fun minus(v: Half) = Half3(x - v, y - v, z - v)
|
||||
inline operator fun times(v: Half) = Half3(x * v, y * v, z * v)
|
||||
inline operator fun div(v: Half) = Half3(x / v, y / v, z / v)
|
||||
|
||||
inline operator fun plus(v: Half2) = Half3(x + v.x, y + v.y, z)
|
||||
inline operator fun minus(v: Half2) = Half3(x - v.x, y - v.y, z)
|
||||
inline operator fun times(v: Half2) = Half3(x * v.x, y * v.y, z)
|
||||
inline operator fun div(v: Half2) = Half3(x / v.x, y / v.y, z)
|
||||
|
||||
inline operator fun plus(v: Half3) = Half3(x + v.x, y + v.y, z + v.z)
|
||||
inline operator fun minus(v: Half3) = Half3(x - v.x, y - v.y, z - v.z)
|
||||
inline operator fun times(v: Half3) = Half3(x * v.x, y * v.y, z * v.z)
|
||||
inline operator fun div(v: Half3) = Half3(x / v.x, y / v.y, z / v.z)
|
||||
|
||||
inline fun transform(block: (Half) -> Half): Half3 {
|
||||
x = block(x)
|
||||
y = block(y)
|
||||
z = block(z)
|
||||
return this
|
||||
}
|
||||
|
||||
fun toFloatArray() = floatArrayOf(x.toFloat(), y.toFloat(), z.toFloat())
|
||||
}
|
||||
|
||||
data class Half4(
|
||||
var x: Half = Half.POSITIVE_ZERO,
|
||||
var y: Half = Half.POSITIVE_ZERO,
|
||||
var z: Half = Half.POSITIVE_ZERO,
|
||||
var w: Half = Half.POSITIVE_ZERO
|
||||
) {
|
||||
constructor(v: Half) : this(v, v, v, v)
|
||||
constructor(v: Half2, z: Half = Half.POSITIVE_ZERO, w: Half = Half.POSITIVE_ZERO) : this(v.x, v.y, z, w)
|
||||
constructor(v: Half3, w: Half = Half.POSITIVE_ZERO) : this(v.x, v.y, v.z, w)
|
||||
constructor(v: Half4) : this(v.x, v.y, v.z, v.w)
|
||||
|
||||
inline var r: Half
|
||||
get() = x
|
||||
set(value) {
|
||||
x = value
|
||||
}
|
||||
inline var g: Half
|
||||
get() = y
|
||||
set(value) {
|
||||
y = value
|
||||
}
|
||||
inline var b: Half
|
||||
get() = z
|
||||
set(value) {
|
||||
z = value
|
||||
}
|
||||
inline var a: Half
|
||||
get() = w
|
||||
set(value) {
|
||||
w = value
|
||||
}
|
||||
|
||||
inline var s: Half
|
||||
get() = x
|
||||
set(value) {
|
||||
x = value
|
||||
}
|
||||
inline var t: Half
|
||||
get() = y
|
||||
set(value) {
|
||||
y = value
|
||||
}
|
||||
inline var p: Half
|
||||
get() = z
|
||||
set(value) {
|
||||
z = value
|
||||
}
|
||||
inline var q: Half
|
||||
get() = w
|
||||
set(value) {
|
||||
w = value
|
||||
}
|
||||
|
||||
inline var xy: Half2
|
||||
get() = Half2(x, y)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
}
|
||||
inline var rg: Half2
|
||||
get() = Half2(x, y)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
}
|
||||
inline var st: Half2
|
||||
get() = Half2(x, y)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
}
|
||||
|
||||
inline var rgb: Half3
|
||||
get() = Half3(x, y, z)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
z = value.z
|
||||
}
|
||||
inline var xyz: Half3
|
||||
get() = Half3(x, y, z)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
z = value.z
|
||||
}
|
||||
inline var stp: Half3
|
||||
get() = Half3(x, y, z)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
z = value.z
|
||||
}
|
||||
|
||||
inline var rgba: Half4
|
||||
get() = Half4(x, y, z, w)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
z = value.z
|
||||
w = value.w
|
||||
}
|
||||
inline var xyzw: Half4
|
||||
get() = Half4(x, y, z, w)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
z = value.z
|
||||
w = value.w
|
||||
}
|
||||
inline var stpq: Half4
|
||||
get() = Half4(x, y, z, w)
|
||||
set(value) {
|
||||
x = value.x
|
||||
y = value.y
|
||||
z = value.z
|
||||
w = value.w
|
||||
}
|
||||
|
||||
operator fun get(index: VectorComponent) = when (index) {
|
||||
VectorComponent.X, VectorComponent.R, VectorComponent.S -> x
|
||||
VectorComponent.Y, VectorComponent.G, VectorComponent.T -> y
|
||||
VectorComponent.Z, VectorComponent.B, VectorComponent.P -> z
|
||||
VectorComponent.W, VectorComponent.A, VectorComponent.Q -> w
|
||||
}
|
||||
|
||||
operator fun get(index1: VectorComponent, index2: VectorComponent): Half2 {
|
||||
return Half2(get(index1), get(index2))
|
||||
}
|
||||
operator fun get(
|
||||
index1: VectorComponent,
|
||||
index2: VectorComponent,
|
||||
index3: VectorComponent): Half3 {
|
||||
return Half3(get(index1), get(index2), get(index3))
|
||||
}
|
||||
operator fun get(
|
||||
index1: VectorComponent,
|
||||
index2: VectorComponent,
|
||||
index3: VectorComponent,
|
||||
index4: VectorComponent): Half4 {
|
||||
return Half4(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) = Half2(get(index1), get(index2))
|
||||
operator fun get(index1: Int, index2: Int, index3: Int): Half3 {
|
||||
return Half3(get(index1), get(index2), get(index3))
|
||||
}
|
||||
operator fun get(index1: Int, index2: Int, index3: Int, index4: Int): Half4 {
|
||||
return Half4(get(index1), get(index2), get(index3), get(index4))
|
||||
}
|
||||
|
||||
inline operator fun invoke(index: Int) = get(index - 1)
|
||||
|
||||
operator fun set(index: Int, v: Half) = 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: Half) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
}
|
||||
|
||||
operator fun set(index1: Int, index2: Int, index3: Int, v: Half) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
set(index3, v)
|
||||
}
|
||||
|
||||
operator fun set(index1: Int, index2: Int, index3: Int, index4: Int, v: Half) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
set(index3, v)
|
||||
set(index4, v)
|
||||
}
|
||||
|
||||
operator fun set(index: VectorComponent, v: Half) = when (index) {
|
||||
VectorComponent.X, VectorComponent.R, VectorComponent.S -> x = v
|
||||
VectorComponent.Y, VectorComponent.G, VectorComponent.T -> y = v
|
||||
VectorComponent.Z, VectorComponent.B, VectorComponent.P -> z = v
|
||||
VectorComponent.W, VectorComponent.A, VectorComponent.Q -> w = v
|
||||
}
|
||||
|
||||
operator fun set(index1: VectorComponent, index2: VectorComponent, v: Half) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
}
|
||||
|
||||
operator fun set(
|
||||
index1: VectorComponent, index2: VectorComponent, index3: VectorComponent, v: Half) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
set(index3, v)
|
||||
}
|
||||
|
||||
operator fun set(
|
||||
index1: VectorComponent, index2: VectorComponent,
|
||||
index3: VectorComponent, index4: VectorComponent, v: Half) {
|
||||
set(index1, v)
|
||||
set(index2, v)
|
||||
set(index3, v)
|
||||
set(index4, v)
|
||||
}
|
||||
|
||||
operator fun unaryMinus() = Half4(-x, -y, -z, -w)
|
||||
operator fun inc() = Half4(x++, y++, z++, w++)
|
||||
operator fun dec() = Half4(x--, y--, z--, w--)
|
||||
|
||||
inline operator fun plus(v: Half) = Half4(x + v, y + v, z + v, w + v)
|
||||
inline operator fun minus(v: Half) = Half4(x - v, y - v, z - v, w - v)
|
||||
inline operator fun times(v: Half) = Half4(x * v, y * v, z * v, w * v)
|
||||
inline operator fun div(v: Half) = Half4(x / v, y / v, z / v, w / v)
|
||||
|
||||
inline operator fun plus(v: Half2) = Half4(x + v.x, y + v.y, z, w)
|
||||
inline operator fun minus(v: Half2) = Half4(x - v.x, y - v.y, z, w)
|
||||
inline operator fun times(v: Half2) = Half4(x * v.x, y * v.y, z, w)
|
||||
inline operator fun div(v: Half2) = Half4(x / v.x, y / v.y, z, w)
|
||||
|
||||
inline operator fun plus(v: Half3) = Half4(x + v.x, y + v.y, z + v.z, w)
|
||||
inline operator fun minus(v: Half3) = Half4(x - v.x, y - v.y, z - v.z, w)
|
||||
inline operator fun times(v: Half3) = Half4(x * v.x, y * v.y, z * v.z, w)
|
||||
inline operator fun div(v: Half3) = Half4(x / v.x, y / v.y, z / v.z, w)
|
||||
|
||||
inline operator fun plus(v: Half4) = Half4(x + v.x, y + v.y, z + v.z, w + v.w)
|
||||
inline operator fun minus(v: Half4) = Half4(x - v.x, y - v.y, z - v.z, w - v.w)
|
||||
inline operator fun times(v: Half4) = Half4(x * v.x, y * v.y, z * v.z, w * v.w)
|
||||
inline operator fun div(v: Half4) = Half4(x / v.x, y / v.y, z / v.z, w / v.w)
|
||||
|
||||
inline fun transform(block: (Half) -> Half): Half4 {
|
||||
x = block(x)
|
||||
y = block(y)
|
||||
z = block(z)
|
||||
w = block(w)
|
||||
return this
|
||||
}
|
||||
|
||||
fun toFloatArray() = floatArrayOf(x.toFloat(), y.toFloat(), z.toFloat(), w.toFloat())
|
||||
}
|
||||
|
||||
inline fun min(v: Half2) = min(v.x, v.y)
|
||||
inline fun min(a: Half2, b: Half2) = Half2(min(a.x, b.x), min(a.y, b.y))
|
||||
inline fun max(v: Half2) = max(v.x, v.y)
|
||||
inline fun max(a: Half2, b: Half2) = Half2(max(a.x, b.x), max(a.y, b.y))
|
||||
|
||||
inline fun transform(v: Half2, block: (Half) -> Half) = v.copy().transform(block)
|
||||
|
||||
inline fun lessThan(a: Half2, b: Half) = Bool2(a.x < b, a.y < b)
|
||||
inline fun lessThan(a: Half2, b: Half2) = Bool2(a.x < b.x, a.y < b.y)
|
||||
inline fun lessThanEqual(a: Half2, b: Half) = Bool2(a.x <= b, a.y <= b)
|
||||
inline fun lessThanEqual(a: Half2, b: Half2) = Bool2(a.x <= b.x, a.y <= b.y)
|
||||
inline fun greaterThan(a: Half2, b: Half) = Bool2(a.x > b, a.y > b)
|
||||
inline fun greaterThan(a: Half2, b: Half2) = Bool2(a.x > b.y, a.y > b.y)
|
||||
inline fun greaterThanEqual(a: Half2, b: Half) = Bool2(a.x >= b, a.y >= b)
|
||||
inline fun greaterThanEqual(a: Half2, b: Half2) = Bool2(a.x >= b.x, a.y >= b.y)
|
||||
inline fun equal(a: Half2, b: Half) = Bool2(a.x == b, a.y == b)
|
||||
inline fun equal(a: Half2, b: Half2) = Bool2(a.x == b.x, a.y == b.y)
|
||||
inline fun notEqual(a: Half2, b: Half) = Bool2(a.x != b, a.y != b)
|
||||
inline fun notEqual(a: Half2, b: Half2) = Bool2(a.x != b.x, a.y != b.y)
|
||||
|
||||
inline infix fun Half2.lt(b: Half) = Bool2(x < b, y < b)
|
||||
inline infix fun Half2.lt(b: Half2) = Bool2(x < b.x, y < b.y)
|
||||
inline infix fun Half2.lte(b: Half) = Bool2(x <= b, y <= b)
|
||||
inline infix fun Half2.lte(b: Half2) = Bool2(x <= b.x, y <= b.y)
|
||||
inline infix fun Half2.gt(b: Half) = Bool2(x > b, y > b)
|
||||
inline infix fun Half2.gt(b: Half2) = Bool2(x > b.x, y > b.y)
|
||||
inline infix fun Half2.gte(b: Half) = Bool2(x >= b, y >= b)
|
||||
inline infix fun Half2.gte(b: Half2) = Bool2(x >= b.x, y >= b.y)
|
||||
inline infix fun Half2.eq(b: Half) = Bool2(x == b, y == b)
|
||||
inline infix fun Half2.eq(b: Half2) = Bool2(x == b.x, y == b.y)
|
||||
inline infix fun Half2.neq(b: Half) = Bool2(x != b, y != b)
|
||||
inline infix fun Half2.neq(b: Half2) = Bool2(x != b.x, y != b.y)
|
||||
|
||||
inline operator fun Half.plus(v: Half3) = Half3(this + v.x, this + v.y, this + v.z)
|
||||
inline operator fun Half.minus(v: Half3) = Half3(this - v.x, this - v.y, this - v.z)
|
||||
inline operator fun Half.times(v: Half3) = Half3(this * v.x, this * v.y, this * v.z)
|
||||
inline operator fun Half.div(v: Half3) = Half3(this / v.x, this / v.y, this / v.z)
|
||||
|
||||
inline fun abs(v: Half3) = Half3(abs(v.x), abs(v.y), abs(v.z))
|
||||
inline fun length(v: Half3) = sqrt(v.x * v.x + v.y * v.y + v.z * v.z)
|
||||
inline fun length2(v: Half3) = v.x * v.x + v.y * v.y + v.z * v.z
|
||||
inline fun distance(a: Half3, b: Half3) = length(a - b)
|
||||
inline fun dot(a: Half3, b: Half3) = a.x * b.x + a.y * b.y + a.z * b.z
|
||||
inline fun cross(a: Half3, b: Half3): Half3 {
|
||||
return Half3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x)
|
||||
}
|
||||
inline infix fun Half3.x(v: Half3): Half3 {
|
||||
return Half3(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x)
|
||||
}
|
||||
fun normalize(v: Half3): Half3 {
|
||||
val l = HALF_ONE / length(v)
|
||||
return Half3(v.x * l, v.y * l, v.z * l)
|
||||
}
|
||||
|
||||
inline fun reflect(i: Half3, n: Half3) = i - HALF_TWO * dot(n, i) * n
|
||||
fun refract(i: Half3, n: Half3, eta: Half): Half3 {
|
||||
val d = dot(n, i)
|
||||
val k = HALF_ONE - eta * eta * (HALF_ONE - sqr(d))
|
||||
return if (k < Half.POSITIVE_ZERO) Half3() else eta * i - (eta * d + sqrt(k)) * n
|
||||
}
|
||||
|
||||
inline fun clamp(v: Half3, min: Half, max: Half): Half3 {
|
||||
return Half3(
|
||||
clamp(v.x, min, max),
|
||||
clamp(v.y, min, max),
|
||||
clamp(v.z, min, max)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun clamp(v: Half3, min: Half3, max: Half3): Half3 {
|
||||
return Half3(
|
||||
clamp(v.x, min.x, max.x),
|
||||
clamp(v.y, min.y, max.y),
|
||||
clamp(v.z, min.z, max.z)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun mix(a: Half3, b: Half3, x: Half): Half3 {
|
||||
return Half3(
|
||||
mix(a.x, b.x, x),
|
||||
mix(a.y, b.y, x),
|
||||
mix(a.z, b.z, x)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun mix(a: Half3, b: Half3, x: Half3): Half3 {
|
||||
return Half3(
|
||||
mix(a.x, b.x, x.x),
|
||||
mix(a.y, b.y, x.y),
|
||||
mix(a.z, b.z, x.z)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun min(v: Half3) = min(v.x, min(v.y, v.z))
|
||||
inline fun min(a: Half3, b: Half3) = Half3(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z))
|
||||
inline fun max(v: Half3) = max(v.x, max(v.y, v.z))
|
||||
inline fun max(a: Half3, b: Half3) = Half3(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z))
|
||||
|
||||
inline fun transform(v: Half3, block: (Half) -> Half) = v.copy().transform(block)
|
||||
|
||||
inline fun lessThan(a: Half3, b: Half) = Bool3(a.x < b, a.y < b, a.z < b)
|
||||
inline fun lessThan(a: Half3, b: Half3) = Bool3(a.x < b.x, a.y < b.y, a.z < b.z)
|
||||
inline fun lessThanEqual(a: Half3, b: Half) = Bool3(a.x <= b, a.y <= b, a.z <= b)
|
||||
inline fun lessThanEqual(a: Half3, b: Half3) = Bool3(a.x <= b.x, a.y <= b.y, a.z <= b.z)
|
||||
inline fun greaterThan(a: Half3, b: Half) = Bool3(a.x > b, a.y > b, a.z > b)
|
||||
inline fun greaterThan(a: Half3, b: Half3) = Bool3(a.x > b.y, a.y > b.y, a.z > b.z)
|
||||
inline fun greaterThanEqual(a: Half3, b: Half) = Bool3(a.x >= b, a.y >= b, a.z >= b)
|
||||
inline fun greaterThanEqual(a: Half3, b: Half3) = Bool3(a.x >= b.x, a.y >= b.y, a.z >= b.z)
|
||||
inline fun equal(a: Half3, b: Half) = Bool3(a.x == b, a.y == b, a.z == b)
|
||||
inline fun equal(a: Half3, b: Half3) = Bool3(a.x == b.x, a.y == b.y, a.z == b.z)
|
||||
inline fun notEqual(a: Half3, b: Half) = Bool3(a.x != b, a.y != b, a.z != b)
|
||||
inline fun notEqual(a: Half3, b: Half3) = Bool3(a.x != b.x, a.y != b.y, a.z != b.z)
|
||||
|
||||
inline infix fun Half3.lt(b: Half) = Bool3(x < b, y < b, z < b)
|
||||
inline infix fun Half3.lt(b: Half3) = Bool3(x < b.x, y < b.y, z < b.z)
|
||||
inline infix fun Half3.lte(b: Half) = Bool3(x <= b, y <= b, z <= b)
|
||||
inline infix fun Half3.lte(b: Half3) = Bool3(x <= b.x, y <= b.y, z <= b.z)
|
||||
inline infix fun Half3.gt(b: Half) = Bool3(x > b, y > b, z > b)
|
||||
inline infix fun Half3.gt(b: Half3) = Bool3(x > b.x, y > b.y, z > b.z)
|
||||
inline infix fun Half3.gte(b: Half) = Bool3(x >= b, y >= b, z >= b)
|
||||
inline infix fun Half3.gte(b: Half3) = Bool3(x >= b.x, y >= b.y, z >= b.z)
|
||||
inline infix fun Half3.eq(b: Half) = Bool3(x == b, y == b, z == b)
|
||||
inline infix fun Half3.eq(b: Half3) = Bool3(x == b.x, y == b.y, z == b.z)
|
||||
inline infix fun Half3.neq(b: Half) = Bool3(x != b, y != b, z != b)
|
||||
inline infix fun Half3.neq(b: Half3) = Bool3(x != b.x, y != b.y, z != b.z)
|
||||
|
||||
inline operator fun Half.plus(v: Half4) = Half4(this + v.x, this + v.y, this + v.z, this + v.w)
|
||||
inline operator fun Half.minus(v: Half4) = Half4(this - v.x, this - v.y, this - v.z, this - v.w)
|
||||
inline operator fun Half.times(v: Half4) = Half4(this * v.x, this * v.y, this * v.z, this * v.w)
|
||||
inline operator fun Half.div(v: Half4) = Half4(this / v.x, this / v.y, this / v.z, this / v.w)
|
||||
|
||||
inline fun abs(v: Half4) = Half4(abs(v.x), abs(v.y), abs(v.z), abs(v.w))
|
||||
inline fun length(v: Half4) = sqrt(v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w)
|
||||
inline fun length2(v: Half4) = v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w
|
||||
inline fun distance(a: Half4, b: Half4) = length(a - b)
|
||||
inline fun dot(a: Half4, b: Half4) = a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w
|
||||
fun normalize(v: Half4): Half4 {
|
||||
val l = HALF_ONE / length(v)
|
||||
return Half4(v.x * l, v.y * l, v.z * l, v.w * l)
|
||||
}
|
||||
|
||||
inline fun clamp(v: Half4, min: Half, max: Half): Half4 {
|
||||
return Half4(
|
||||
clamp(v.x, min, max),
|
||||
clamp(v.y, min, max),
|
||||
clamp(v.z, min, max),
|
||||
clamp(v.w, min, max)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun clamp(v: Half4, min: Half4, max: Half4): Half4 {
|
||||
return Half4(
|
||||
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)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun mix(a: Half4, b: Half4, x: Half): Half4 {
|
||||
return Half4(
|
||||
mix(a.x, b.x, x),
|
||||
mix(a.y, b.y, x),
|
||||
mix(a.z, b.z, x),
|
||||
mix(a.w, b.w, x)
|
||||
)
|
||||
}
|
||||
|
||||
inline fun mix(a: Half4, b: Half4, x: Half4): Half4 {
|
||||
return Half4(
|
||||
mix(a.x, b.x, x.x),
|
||||
mix(a.y, b.y, x.y),
|
||||
mix(a.z, b.z, x.z),
|
||||
mix(a.w, b.w, x.w))
|
||||
}
|
||||
|
||||
inline fun min(v: Half4) = min(v.x, min(v.y, min(v.z, v.w)))
|
||||
inline fun min(a: Half4, b: Half4): Half4 {
|
||||
return Half4(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z), min(a.w, b.w))
|
||||
}
|
||||
inline fun max(v: Half4) = max(v.x, max(v.y, max(v.z, v.w)))
|
||||
inline fun max(a: Half4, b: Half4): Half4 {
|
||||
return Half4(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z), max(a.w, b.w))
|
||||
}
|
||||
|
||||
inline fun transform(v: Half4, block: (Half) -> Half) = v.copy().transform(block)
|
||||
|
||||
inline fun lessThan(a: Half4, b: Half) = Bool4(a.x < b, a.y < b, a.z < b, a.w < b)
|
||||
inline fun lessThan(a: Half4, b: Half4) = Bool4(a.x < b.x, a.y < b.y, a.z < b.z, a.w < b.w)
|
||||
inline fun lessThanEqual(a: Half4, b: Half) = Bool4(a.x <= b, a.y <= b, a.z <= b, a.w <= b)
|
||||
inline fun lessThanEqual(a: Half4, b: Half4) = Bool4(a.x <= b.x, a.y <= b.y, a.z <= b.z, a.w <= b.w)
|
||||
inline fun greaterThan(a: Half4, b: Half) = Bool4(a.x > b, a.y > b, a.z > b, a.w > b)
|
||||
inline fun greaterThan(a: Half4, b: Half4) = Bool4(a.x > b.y, a.y > b.y, a.z > b.z, a.w > b.w)
|
||||
inline fun greaterThanEqual(a: Half4, b: Half) = Bool4(a.x >= b, a.y >= b, a.z >= b, a.w >= b)
|
||||
inline fun greaterThanEqual(a: Half4, b: Half4) = Bool4(a.x >= b.x, a.y >= b.y, a.z >= b.z, a.w >= b.w)
|
||||
inline fun equal(a: Half4, b: Half) = Bool4(a.x == b, a.y == b, a.z == b, a.w == b)
|
||||
inline fun equal(a: Half4, b: Half4) = Bool4(a.x == b.x, a.y == b.y, a.z == b.z, a.w == b.w)
|
||||
inline fun notEqual(a: Half4, b: Half) = Bool4(a.x != b, a.y != b, a.z != b, a.w != b)
|
||||
inline fun notEqual(a: Half4, b: Half4) = Bool4(a.x != b.x, a.y != b.y, a.z != b.z, a.w != b.w)
|
||||
|
||||
inline infix fun Half4.lt(b: Half) = Bool4(x < b, y < b, z < b, a < b)
|
||||
inline infix fun Half4.lt(b: Half4) = Bool4(x < b.x, y < b.y, z < b.z, w < b.w)
|
||||
inline infix fun Half4.lte(b: Half) = Bool4(x <= b, y <= b, z <= b, w <= b)
|
||||
inline infix fun Half4.lte(b: Half4) = Bool4(x <= b.x, y <= b.y, z <= b.z, w <= b.w)
|
||||
inline infix fun Half4.gt(b: Half) = Bool4(x > b, y > b, z > b, w > b)
|
||||
inline infix fun Half4.gt(b: Half4) = Bool4(x > b.x, y > b.y, z > b.z, w > b.w)
|
||||
inline infix fun Half4.gte(b: Half) = Bool4(x >= b, y >= b, z >= b, w >= b)
|
||||
inline infix fun Half4.gte(b: Half4) = Bool4(x >= b.x, y >= b.y, z >= b.z, w >= b.w)
|
||||
inline infix fun Half4.eq(b: Half) = Bool4(x == b, y == b, z == b, w == b)
|
||||
inline infix fun Half4.eq(b: Half4) = Bool4(x == b.x, y == b.y, z == b.z, w == b.w)
|
||||
inline infix fun Half4.neq(b: Half) = Bool4(x != b, y != b, z != b, w != b)
|
||||
inline infix fun Half4.neq(b: Half4) = Bool4(x != b.x, y != b.y, z != b.z, w != b.w)
|
||||
|
||||
@@ -52,6 +52,7 @@ set(GLTFIO_SRCS
|
||||
${GLTFIO_DIR}/include/gltfio/FilamentInstance.h
|
||||
${GLTFIO_DIR}/include/gltfio/MaterialProvider.h
|
||||
${GLTFIO_DIR}/include/gltfio/NodeManager.h
|
||||
${GLTFIO_DIR}/include/gltfio/TrsTransformManager.h
|
||||
${GLTFIO_DIR}/include/gltfio/ResourceLoader.h
|
||||
${GLTFIO_DIR}/include/gltfio/TextureProvider.h
|
||||
${GLTFIO_DIR}/include/gltfio/math.h
|
||||
@@ -69,10 +70,12 @@ set(GLTFIO_SRCS
|
||||
${GLTFIO_DIR}/src/FilamentAsset.cpp
|
||||
${GLTFIO_DIR}/src/FilamentInstance.cpp
|
||||
${GLTFIO_DIR}/src/FNodeManager.h
|
||||
${GLTFIO_DIR}/src/FTrsTransformManager.h
|
||||
${GLTFIO_DIR}/src/GltfEnums.h
|
||||
${GLTFIO_DIR}/src/Ktx2Provider.cpp
|
||||
${GLTFIO_DIR}/src/MaterialProvider.cpp
|
||||
${GLTFIO_DIR}/src/NodeManager.cpp
|
||||
${GLTFIO_DIR}/src/TrsTransformManager.cpp
|
||||
${GLTFIO_DIR}/src/ResourceLoader.cpp
|
||||
${GLTFIO_DIR}/src/StbProvider.cpp
|
||||
${GLTFIO_DIR}/src/TangentsJob.cpp
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
android {
|
||||
namespace 'com.google.android.filament.gltfio'
|
||||
|
||||
flavorDimensions "functionality"
|
||||
productFlavors {
|
||||
full {
|
||||
dimension "functionality"
|
||||
}
|
||||
}
|
||||
packagingOptions {
|
||||
// No need to package up the following shared libs, which arise as a side effect of our
|
||||
// externalNativeBuild dependencies. When clients pick and choose from project-level gradle
|
||||
@@ -16,6 +10,13 @@ android {
|
||||
excludes += ['lib/*/libfilament-jni.so']
|
||||
}
|
||||
}
|
||||
|
||||
publishing {
|
||||
singleVariant("release") {
|
||||
withSourcesJar()
|
||||
withJavadocJar()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -29,9 +30,9 @@ apply from: rootProject.file('gradle/gradle-mvn-push.gradle')
|
||||
afterEvaluate { project ->
|
||||
publishing {
|
||||
publications {
|
||||
fullRelease(MavenPublication) {
|
||||
release(MavenPublication) {
|
||||
artifactId = POM_ARTIFACT_ID_FULL
|
||||
from components.fullRelease
|
||||
from components.release
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ public class FilamentInstance {
|
||||
*
|
||||
* Ignored if variantIndex is out of bounds.
|
||||
*/
|
||||
void applyMaterialVariant(@IntRange(from = 0) int variantIndex) {
|
||||
public void applyMaterialVariant(@IntRange(from = 0) int variantIndex) {
|
||||
nApplyMaterialVariant(mNativeObject, variantIndex);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
GROUP=com.google.android.filament
|
||||
VERSION_NAME=1.32.0
|
||||
VERSION_NAME=1.50.2
|
||||
|
||||
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
|
||||
|
||||
@@ -18,6 +18,9 @@ POM_DEVELOPER_NAME=Filament Team
|
||||
org.gradle.jvmargs=-Xmx1536m
|
||||
|
||||
android.useAndroidX=true
|
||||
android.defaults.buildfeatures.buildconfig=true
|
||||
android.nonTransitiveRClass=false
|
||||
android.nonFinalResIds=false
|
||||
|
||||
com.google.android.filament.tools-dir=../../../out/release/filament
|
||||
com.google.android.filament.dist-dir=../out/android-release/filament
|
||||
|
||||
@@ -86,63 +86,10 @@ afterEvaluate { project ->
|
||||
}
|
||||
}
|
||||
|
||||
if (project.getPlugins().hasPlugin('com.android.application') ||
|
||||
project.getPlugins().hasPlugin('com.android.library')) {
|
||||
|
||||
task androidJavadocs(type: Javadoc) {
|
||||
source = android.sourceSets.main.java.source
|
||||
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
|
||||
excludes = ['**/*.kt']
|
||||
}
|
||||
|
||||
task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {
|
||||
classifier = 'javadoc'
|
||||
from androidJavadocs.destinationDir
|
||||
}
|
||||
|
||||
task androidSourcesJar(type: Jar) {
|
||||
classifier = 'sources'
|
||||
from android.sourceSets.main.java.source
|
||||
}
|
||||
}
|
||||
|
||||
if (JavaVersion.current().isJava8Compatible()) {
|
||||
allprojects {
|
||||
tasks.withType(Javadoc) {
|
||||
options.addStringOption('Xdoclint:none', '-quiet')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (JavaVersion.current().isJava9Compatible()) {
|
||||
allprojects {
|
||||
tasks.withType(Javadoc) {
|
||||
options.addBooleanOption('html5', true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
artifacts {
|
||||
if (project.getPlugins().hasPlugin('com.android.application') ||
|
||||
project.getPlugins().hasPlugin('com.android.library')) {
|
||||
archives androidSourcesJar
|
||||
archives androidJavadocsJar
|
||||
}
|
||||
}
|
||||
|
||||
android.libraryVariants.all { variant ->
|
||||
tasks.androidJavadocs.doFirst {
|
||||
classpath += files(variant.javaCompileProvider.get().classpath.files.join(File.pathSeparator))
|
||||
}
|
||||
}
|
||||
|
||||
publishing.publications.all { publication ->
|
||||
publication.groupId = GROUP
|
||||
publication.version = VERSION_NAME
|
||||
|
||||
publication.artifact androidSourcesJar
|
||||
publication.artifact androidJavadocsJar
|
||||
|
||||
configurePom(publication.pom)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +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.5-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -87,9 +87,9 @@ compile Filament's native library and Filament's AAR for this project. The easie
|
||||
is to install all the required dependencies and to run the following commands at the root of the
|
||||
source tree:
|
||||
|
||||
```
|
||||
$ ./build.sh -p desktop -i release
|
||||
$ ./build.sh -p android release
|
||||
```shell
|
||||
./build.sh -p desktop -i release
|
||||
./build.sh -p android release
|
||||
```
|
||||
|
||||
This will build all the native components and the AAR required by this sample application.
|
||||
@@ -100,8 +100,8 @@ distribution/install directory for desktop (produced by make/ninja install). Thi
|
||||
contain `bin/matc` and `bin/cmgen`.
|
||||
|
||||
Example:
|
||||
```
|
||||
$ ./gradlew -Pfilament_tools_dir=../../dist-release assembleDebug
|
||||
```shell
|
||||
./gradlew -Pfilament_tools_dir=../../dist-release assembleDebug
|
||||
```
|
||||
|
||||
## Important: SDK location
|
||||
@@ -110,14 +110,24 @@ Either ensure your `ANDROID_HOME` environment variable is set or make sure the r
|
||||
contains a `local.properties` file with the `sdk.dir` property pointing to your installation of
|
||||
the Android SDK.
|
||||
|
||||
## Android Studio
|
||||
## Compiling
|
||||
|
||||
### Android Studio
|
||||
|
||||
You must use the latest stable release of Android Studio. To open the project, point Studio to the
|
||||
`android` folder. After opening the project and syncing to gradle, select the sample of your choice
|
||||
using the drop-down widget in the toolbar.
|
||||
|
||||
## Compiling
|
||||
|
||||
To compile and run each sample make sure you have selected the appropriate build variant
|
||||
(arm7, arm8, x86 or x86_64). If you are not sure you can simply select the "universal"
|
||||
variant which includes all the other ones.
|
||||
|
||||
### Command Line
|
||||
|
||||
From the `android` directory in the project root:
|
||||
|
||||
```shell
|
||||
./gradlew :samples:sample-hello-triangle:installDebug
|
||||
```
|
||||
|
||||
Replace `sample-hello-triangle` with your preferred project.
|
||||
|
||||
@@ -32,7 +32,6 @@ android {
|
||||
applicationId "com.google.android.filament.gltf"
|
||||
minSdkVersion 19
|
||||
targetSdkVersion versions.targetSdk
|
||||
missingDimensionStrategy 'functionality', 'full'
|
||||
}
|
||||
|
||||
// NOTE: This is a workaround required because the AGP task collectReleaseDependencies
|
||||
@@ -40,6 +39,11 @@ android {
|
||||
dependenciesInfo {
|
||||
includeInApk = false
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility versions.jdk
|
||||
targetCompatibility versions.jdk
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@@ -26,8 +26,10 @@ import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import com.google.android.filament.Fence
|
||||
import com.google.android.filament.IndirectLight
|
||||
import com.google.android.filament.Material
|
||||
import com.google.android.filament.Skybox
|
||||
import com.google.android.filament.View
|
||||
import com.google.android.filament.View.OnPickCallback
|
||||
import com.google.android.filament.utils.*
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -56,7 +58,9 @@ class MainActivity : Activity() {
|
||||
private lateinit var modelViewer: ModelViewer
|
||||
private lateinit var titlebarHint: TextView
|
||||
private val doubleTapListener = DoubleTapListener()
|
||||
private val singleTapListener = SingleTapListener()
|
||||
private lateinit var doubleTapDetector: GestureDetector
|
||||
private lateinit var singleTapDetector: GestureDetector
|
||||
private var remoteServer: RemoteServer? = null
|
||||
private var statusToast: Toast? = null
|
||||
private var statusText: String? = null
|
||||
@@ -77,6 +81,7 @@ class MainActivity : Activity() {
|
||||
choreographer = Choreographer.getInstance()
|
||||
|
||||
doubleTapDetector = GestureDetector(applicationContext, doubleTapListener)
|
||||
singleTapDetector = GestureDetector(applicationContext, singleTapListener)
|
||||
|
||||
modelViewer = ModelViewer(surfaceView)
|
||||
viewerContent.view = modelViewer.view
|
||||
@@ -88,6 +93,7 @@ class MainActivity : Activity() {
|
||||
surfaceView.setOnTouchListener { _, event ->
|
||||
modelViewer.onTouchEvent(event)
|
||||
doubleTapDetector.onTouchEvent(event)
|
||||
singleTapDetector.onTouchEvent(event)
|
||||
true
|
||||
}
|
||||
|
||||
@@ -229,6 +235,7 @@ class MainActivity : Activity() {
|
||||
modelViewer.scene.skybox = sky
|
||||
modelViewer.scene.indirectLight = ibl
|
||||
viewerContent.indirectLight = ibl
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -337,6 +344,11 @@ class MainActivity : Activity() {
|
||||
remoteServer?.close()
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
super.onBackPressed()
|
||||
finish()
|
||||
}
|
||||
|
||||
fun loadModelData(message: RemoteServer.ReceivedMessage) {
|
||||
Log.i(TAG, "Downloaded model ${message.label} (${message.buffer.capacity()} bytes)")
|
||||
clearStatusText()
|
||||
@@ -381,6 +393,36 @@ class MainActivity : Activity() {
|
||||
Log.i(TAG, "The Filament backend took $total ms to load the model geometry.")
|
||||
modelViewer.engine.destroyFence(it)
|
||||
loadStartFence = null
|
||||
|
||||
val materials = mutableSetOf<Material>()
|
||||
val rcm = modelViewer.engine.renderableManager
|
||||
modelViewer.scene.forEach {
|
||||
val entity = it
|
||||
if (rcm.hasComponent(entity)) {
|
||||
val ri = rcm.getInstance(entity)
|
||||
val c = rcm.getPrimitiveCount(ri)
|
||||
for (i in 0 until c) {
|
||||
val mi = rcm.getMaterialInstanceAt(ri, i)
|
||||
val ma = mi.material
|
||||
materials.add(ma)
|
||||
}
|
||||
}
|
||||
}
|
||||
materials.forEach {
|
||||
it.compile(
|
||||
Material.CompilerPriorityQueue.HIGH,
|
||||
Material.UserVariantFilterBit.DIRECTIONAL_LIGHTING or
|
||||
Material.UserVariantFilterBit.DYNAMIC_LIGHTING or
|
||||
Material.UserVariantFilterBit.SHADOW_RECEIVER,
|
||||
null, null)
|
||||
it.compile(
|
||||
Material.CompilerPriorityQueue.LOW,
|
||||
Material.UserVariantFilterBit.FOG or
|
||||
Material.UserVariantFilterBit.SKINNING or
|
||||
Material.UserVariantFilterBit.SSR or
|
||||
Material.UserVariantFilterBit.VSM,
|
||||
null, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -425,4 +467,19 @@ class MainActivity : Activity() {
|
||||
return super.onDoubleTap(e)
|
||||
}
|
||||
}
|
||||
|
||||
// Just for testing purposes
|
||||
inner class SingleTapListener : GestureDetector.SimpleOnGestureListener() {
|
||||
override fun onSingleTapUp(event: MotionEvent): Boolean {
|
||||
modelViewer.view.pick(
|
||||
event.x.toInt(),
|
||||
surfaceView.height - event.y.toInt(),
|
||||
surfaceView.handler, {
|
||||
val name = modelViewer.asset!!.getName(it.renderable)
|
||||
Log.v("Filament", "Picked ${it.renderable}: " + name)
|
||||
},
|
||||
)
|
||||
return super.onSingleTapUp(event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,10 @@ plugins {
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(versions.jdk)
|
||||
}
|
||||
|
||||
filamentTools {
|
||||
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
|
||||
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
|
||||
@@ -36,6 +40,11 @@ android {
|
||||
aaptOptions {
|
||||
noCompress 'filamat', 'ktx'
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility versions.jdk
|
||||
targetCompatibility versions.jdk
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.google.android.filament.*
|
||||
import com.google.android.filament.RenderableManager.*
|
||||
import com.google.android.filament.VertexBuffer.*
|
||||
import com.google.android.filament.android.DisplayHelper
|
||||
import com.google.android.filament.android.FilamentHelper
|
||||
import com.google.android.filament.android.UiHelper
|
||||
|
||||
import java.nio.ByteBuffer
|
||||
@@ -401,6 +402,8 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
|
||||
camera.setProjection(45.0, aspect, 0.1, 20.0, Camera.Fov.VERTICAL)
|
||||
|
||||
view.viewport = Viewport(0, 0, width, height)
|
||||
|
||||
FilamentHelper.synchronizePendingFrames(engine)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,10 @@ plugins {
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(versions.jdk)
|
||||
}
|
||||
|
||||
filamentTools {
|
||||
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
|
||||
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
|
||||
@@ -36,6 +40,11 @@ android {
|
||||
aaptOptions {
|
||||
noCompress 'filamat', 'ktx'
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility versions.jdk
|
||||
targetCompatibility versions.jdk
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
|
||||
@@ -20,6 +20,8 @@ import android.animation.ValueAnimator
|
||||
import android.app.Activity
|
||||
import android.opengl.Matrix
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.view.Choreographer
|
||||
import android.view.Surface
|
||||
import android.view.SurfaceView
|
||||
@@ -29,6 +31,7 @@ import com.google.android.filament.RenderableManager.PrimitiveType
|
||||
import com.google.android.filament.VertexBuffer.AttributeType
|
||||
import com.google.android.filament.VertexBuffer.VertexAttribute
|
||||
import com.google.android.filament.android.DisplayHelper
|
||||
import com.google.android.filament.android.FilamentHelper
|
||||
import com.google.android.filament.android.UiHelper
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.ByteOrder
|
||||
@@ -109,7 +112,7 @@ class MainActivity : Activity() {
|
||||
}
|
||||
|
||||
private fun setupFilament() {
|
||||
engine = Engine.create()
|
||||
engine = Engine.Builder().featureLevel(Engine.FeatureLevel.FEATURE_LEVEL_0).build()
|
||||
renderer = engine.createRenderer()
|
||||
scene = engine.createScene()
|
||||
view = engine.createView()
|
||||
@@ -119,8 +122,8 @@ class MainActivity : Activity() {
|
||||
private fun setupView() {
|
||||
scene.skybox = Skybox.Builder().color(0.035f, 0.035f, 0.035f, 1.0f).build(engine)
|
||||
|
||||
// NOTE: Try to disable post-processing (tone-mapping, etc.) to see the difference
|
||||
// view.isPostProcessingEnabled = false
|
||||
// post-processing is not supported at feature level 0
|
||||
view.isPostProcessingEnabled = false
|
||||
|
||||
// Tell the view which camera we want to use
|
||||
view.camera = camera
|
||||
@@ -156,6 +159,14 @@ class MainActivity : Activity() {
|
||||
private fun loadMaterial() {
|
||||
readUncompressedAsset("materials/baked_color.filamat").let {
|
||||
material = Material.Builder().payload(it, it.remaining()).build(engine)
|
||||
material.compile(
|
||||
Material.CompilerPriorityQueue.HIGH,
|
||||
Material.UserVariantFilterBit.ALL,
|
||||
Handler(Looper.getMainLooper())) {
|
||||
android.util.Log.i("hellotriangle",
|
||||
"Material " + material.name + " compiled.")
|
||||
}
|
||||
engine.flush()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,7 +315,17 @@ class MainActivity : Activity() {
|
||||
inner class SurfaceCallback : UiHelper.RendererCallback {
|
||||
override fun onNativeWindowChanged(surface: Surface) {
|
||||
swapChain?.let { engine.destroySwapChain(it) }
|
||||
swapChain = engine.createSwapChain(surface, uiHelper.swapChainFlags)
|
||||
|
||||
// at feature level 0, we don't have post-processing, so we need to set
|
||||
// the colorspace to sRGB (FIXME: it's not supported everywhere!)
|
||||
var flags = uiHelper.swapChainFlags
|
||||
if (engine.activeFeatureLevel == Engine.FeatureLevel.FEATURE_LEVEL_0) {
|
||||
if (SwapChain.isSRGBSwapChainSupported(engine)) {
|
||||
flags = flags or SwapChain.CONFIG_SRGB_COLORSPACE
|
||||
}
|
||||
}
|
||||
|
||||
swapChain = engine.createSwapChain(surface, flags)
|
||||
displayHelper.attach(renderer, surfaceView.display);
|
||||
}
|
||||
|
||||
@@ -327,6 +348,8 @@ class MainActivity : Activity() {
|
||||
-aspect * zoom, aspect * zoom, -zoom, zoom, 0.0, 10.0)
|
||||
|
||||
view.viewport = Viewport(0, 0, width, height)
|
||||
|
||||
FilamentHelper.synchronizePendingFrames(engine)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ material {
|
||||
|
||||
// This material disables all lighting
|
||||
shadingModel : unlit,
|
||||
featureLevel : 0
|
||||
}
|
||||
|
||||
fragment {
|
||||
|
||||
@@ -6,6 +6,10 @@ plugins {
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(versions.jdk)
|
||||
}
|
||||
|
||||
filamentTools {
|
||||
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
|
||||
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
|
||||
@@ -42,6 +46,11 @@ android {
|
||||
aaptOptions {
|
||||
noCompress 'filamat', 'ktx'
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility versions.jdk
|
||||
targetCompatibility versions.jdk
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@@ -26,6 +26,7 @@ import android.view.animation.LinearInterpolator
|
||||
|
||||
import com.google.android.filament.*
|
||||
import com.google.android.filament.android.DisplayHelper
|
||||
import com.google.android.filament.android.FilamentHelper
|
||||
import com.google.android.filament.android.UiHelper
|
||||
|
||||
import java.nio.ByteBuffer
|
||||
@@ -117,9 +118,10 @@ class MainActivity : Activity() {
|
||||
}
|
||||
|
||||
private fun setupView() {
|
||||
val ssaoOptions = view.ambientOcclusionOptions
|
||||
ssaoOptions.enabled = true
|
||||
view.ambientOcclusionOptions = ssaoOptions
|
||||
// ambient occlusion is the cheapest effect that adds a lot of quality
|
||||
view.ambientOcclusionOptions = view.ambientOcclusionOptions.apply {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
// NOTE: Try to disable post-processing (tone-mapping, etc.) to see the difference
|
||||
// view.isPostProcessingEnabled = false
|
||||
@@ -303,6 +305,8 @@ class MainActivity : Activity() {
|
||||
camera.setProjection(45.0, aspect, 0.1, 20.0, Camera.Fov.VERTICAL)
|
||||
|
||||
view.viewport = Viewport(0, 0, width, height)
|
||||
|
||||
FilamentHelper.synchronizePendingFrames(engine)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,10 @@ plugins {
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(versions.jdk)
|
||||
}
|
||||
|
||||
filamentTools {
|
||||
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
|
||||
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
|
||||
@@ -35,6 +39,11 @@ android {
|
||||
aaptOptions {
|
||||
noCompress 'filamat', 'ktx'
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility versions.jdk
|
||||
targetCompatibility versions.jdk
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.google.android.filament.*
|
||||
import com.google.android.filament.RenderableManager.*
|
||||
import com.google.android.filament.VertexBuffer.*
|
||||
import com.google.android.filament.android.DisplayHelper
|
||||
import com.google.android.filament.android.FilamentHelper
|
||||
import com.google.android.filament.android.UiHelper
|
||||
|
||||
import java.nio.ByteBuffer
|
||||
@@ -413,6 +414,8 @@ class MainActivity : Activity() {
|
||||
camera.setProjection(45.0, aspect, 0.1, 20.0, Camera.Fov.VERTICAL)
|
||||
|
||||
view.viewport = Viewport(0, 0, width, height)
|
||||
|
||||
FilamentHelper.synchronizePendingFrames(engine)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,10 @@ apply plugin: 'kotlin-android'
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(versions.jdk)
|
||||
}
|
||||
|
||||
android {
|
||||
namespace 'com.google.android.filament.livewallpaper'
|
||||
|
||||
@@ -18,6 +22,11 @@ android {
|
||||
dependenciesInfo {
|
||||
includeInApk = false
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility versions.jdk
|
||||
targetCompatibility versions.jdk
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@@ -31,6 +31,7 @@ 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.FilamentHelper
|
||||
import com.google.android.filament.android.UiHelper
|
||||
|
||||
class FilamentLiveWallpaper : WallpaperService() {
|
||||
@@ -226,6 +227,8 @@ class FilamentLiveWallpaper : WallpaperService() {
|
||||
camera.setProjection(45.0, aspect, 0.1, 20.0, Camera.Fov.VERTICAL)
|
||||
|
||||
view.viewport = Viewport(0, 0, width, height)
|
||||
|
||||
FilamentHelper.synchronizePendingFrames(engine)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,10 @@ plugins {
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(versions.jdk)
|
||||
}
|
||||
|
||||
filamentTools {
|
||||
meshInputFile = project.layout.projectDirectory.file("../../../third_party/models/shader_ball/shader_ball.obj")
|
||||
meshOutputDir = project.layout.projectDirectory.dir("src/main/assets/models")
|
||||
@@ -28,13 +32,6 @@ android {
|
||||
targetSdkVersion versions.targetSdk
|
||||
}
|
||||
|
||||
// The filamat library has two variants: full and lite. Here we default to the "full" variant.
|
||||
// Replace "full" with "lite" to use the filamat-lite variant, which has a smaller binary size
|
||||
// but comes with certain restrictions. See "Filamat Lite" in libs/filamat/README.md.
|
||||
defaultConfig {
|
||||
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 {
|
||||
@@ -46,6 +43,11 @@ android {
|
||||
aaptOptions {
|
||||
noCompress 'filamat'
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility versions.jdk
|
||||
targetCompatibility versions.jdk
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@@ -26,6 +26,7 @@ import android.view.animation.LinearInterpolator
|
||||
|
||||
import com.google.android.filament.*
|
||||
import com.google.android.filament.android.DisplayHelper
|
||||
import com.google.android.filament.android.FilamentHelper
|
||||
import com.google.android.filament.android.UiHelper
|
||||
import com.google.android.filament.filamat.MaterialBuilder
|
||||
|
||||
@@ -343,6 +344,8 @@ class MainActivity : Activity() {
|
||||
camera.setProjection(45.0, aspect, 0.1, 20.0, Camera.Fov.VERTICAL)
|
||||
|
||||
view.viewport = Viewport(0, 0, width, height)
|
||||
|
||||
FilamentHelper.synchronizePendingFrames(engine)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,10 @@ plugins {
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(versions.jdk)
|
||||
}
|
||||
|
||||
filamentTools {
|
||||
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
|
||||
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
|
||||
@@ -35,6 +39,11 @@ android {
|
||||
aaptOptions {
|
||||
noCompress 'filamat', 'ktx'
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility versions.jdk
|
||||
targetCompatibility versions.jdk
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.google.android.filament.RenderableManager.*
|
||||
import com.google.android.filament.Renderer.ClearOptions
|
||||
import com.google.android.filament.VertexBuffer.*
|
||||
import com.google.android.filament.android.DisplayHelper
|
||||
import com.google.android.filament.android.FilamentHelper
|
||||
import com.google.android.filament.android.UiHelper
|
||||
|
||||
import java.nio.ByteBuffer
|
||||
@@ -458,6 +459,8 @@ class MainActivity : Activity() {
|
||||
view1.viewport = Viewport(width / 2, 0, width / 2, height / 2)
|
||||
view2.viewport = Viewport(0, height / 2, width / 2, height / 2)
|
||||
view4.viewport = Viewport(width / 4, height / 4, width / 2, height / 2)
|
||||
|
||||
FilamentHelper.synchronizePendingFrames(engine)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,10 @@ plugins {
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(versions.jdk)
|
||||
}
|
||||
|
||||
filamentTools {
|
||||
iblInputFile = project.layout.projectDirectory.file("../../../third_party/environments/studio_small_02_2k.hdr")
|
||||
iblOutputDir = project.layout.projectDirectory.dir("src/main/assets/envs")
|
||||
@@ -38,6 +42,11 @@ android {
|
||||
aaptOptions {
|
||||
noCompress 'filamat'
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility versions.jdk
|
||||
targetCompatibility versions.jdk
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@@ -37,6 +37,7 @@ import com.google.android.filament.Camera;
|
||||
import com.google.android.filament.Engine;
|
||||
import com.google.android.filament.Entity;
|
||||
import com.google.android.filament.EntityManager;
|
||||
import com.google.android.filament.Fence;
|
||||
import com.google.android.filament.Filament;
|
||||
import com.google.android.filament.IndirectLight;
|
||||
import com.google.android.filament.LightManager;
|
||||
@@ -49,6 +50,7 @@ import com.google.android.filament.TransformManager;
|
||||
import com.google.android.filament.Viewport;
|
||||
|
||||
import com.google.android.filament.android.DisplayHelper;
|
||||
import com.google.android.filament.android.FilamentHelper;
|
||||
import com.google.android.filament.android.TextureHelper;
|
||||
import com.google.android.filament.android.UiHelper;
|
||||
|
||||
@@ -107,6 +109,7 @@ public class MainActivity extends Activity
|
||||
mCamera.setProjection(60.0, aspect, 1.0, 2000.0, Camera.Fov.HORIZONTAL);
|
||||
}
|
||||
mView.setViewport(new Viewport(0, 0, width, height));
|
||||
FilamentHelper.synchronizePendingFrames(mEngine);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -6,6 +6,10 @@ plugins {
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(versions.jdk)
|
||||
}
|
||||
|
||||
filamentTools {
|
||||
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
|
||||
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
|
||||
@@ -36,6 +40,11 @@ android {
|
||||
aaptOptions {
|
||||
noCompress 'filamat', 'ktx'
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility versions.jdk
|
||||
targetCompatibility versions.jdk
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@@ -38,6 +38,7 @@ import android.os.Build
|
||||
import android.view.MotionEvent
|
||||
import androidx.annotation.RequiresApi
|
||||
import com.google.android.filament.android.DisplayHelper
|
||||
import com.google.android.filament.android.FilamentHelper
|
||||
|
||||
|
||||
class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallback {
|
||||
@@ -401,6 +402,8 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
|
||||
camera.setProjection(45.0, aspect, 0.1, 20.0, Camera.Fov.VERTICAL)
|
||||
|
||||
view.viewport = Viewport(0, 0, width, height)
|
||||
|
||||
FilamentHelper.synchronizePendingFrames(engine)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,10 @@ plugins {
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(versions.jdk)
|
||||
}
|
||||
|
||||
filamentTools {
|
||||
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
|
||||
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
|
||||
@@ -36,6 +40,11 @@ android {
|
||||
aaptOptions {
|
||||
noCompress 'filamat', 'ktx'
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility versions.jdk
|
||||
targetCompatibility versions.jdk
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.google.android.filament.RenderableManager.PrimitiveType
|
||||
import com.google.android.filament.VertexBuffer.AttributeType
|
||||
import com.google.android.filament.VertexBuffer.VertexAttribute
|
||||
import com.google.android.filament.android.DisplayHelper
|
||||
import com.google.android.filament.android.FilamentHelper
|
||||
import com.google.android.filament.android.UiHelper
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.ByteOrder
|
||||
@@ -327,6 +328,8 @@ class MainActivity : Activity() {
|
||||
-aspect * zoom, aspect * zoom, -zoom, zoom, 0.0, 10.0)
|
||||
|
||||
view.viewport = Viewport(0, 0, width, height)
|
||||
|
||||
FilamentHelper.synchronizePendingFrames(engine)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,10 @@ plugins {
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(versions.jdk)
|
||||
}
|
||||
|
||||
filamentTools {
|
||||
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
|
||||
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
|
||||
@@ -29,7 +33,6 @@ android {
|
||||
applicationId "com.google.android.filament.textured"
|
||||
minSdkVersion versions.minSdk
|
||||
targetSdkVersion versions.targetSdk
|
||||
missingDimensionStrategy 'functionality', 'full'
|
||||
}
|
||||
|
||||
// NOTE: This is a workaround required because the AGP task collectReleaseDependencies
|
||||
@@ -43,6 +46,11 @@ android {
|
||||
aaptOptions {
|
||||
noCompress 'filamat', 'ktx'
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility versions.jdk
|
||||
targetCompatibility versions.jdk
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@@ -26,6 +26,7 @@ import android.view.animation.LinearInterpolator
|
||||
|
||||
import com.google.android.filament.*
|
||||
import com.google.android.filament.android.DisplayHelper
|
||||
import com.google.android.filament.android.FilamentHelper
|
||||
import com.google.android.filament.utils.*
|
||||
import com.google.android.filament.android.UiHelper
|
||||
|
||||
@@ -230,7 +231,7 @@ class MainActivity : Activity() {
|
||||
animator.repeatCount = ValueAnimator.INFINITE
|
||||
animator.addUpdateListener { a ->
|
||||
val v = (a.animatedValue as Float)
|
||||
camera.lookAt(cos(v) * 4.5, 1.5, sin(v) * 4.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
|
||||
camera.lookAt(cos(v) * 5.5, 1.5, sin(v) * 5.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
|
||||
}
|
||||
animator.start()
|
||||
}
|
||||
@@ -252,7 +253,7 @@ class MainActivity : Activity() {
|
||||
|
||||
// Stop the animation and any pending frame
|
||||
choreographer.removeFrameCallback(frameScheduler)
|
||||
animator.cancel();
|
||||
animator.cancel()
|
||||
|
||||
// Always detach the surface before destroying the engine
|
||||
uiHelper.detach()
|
||||
@@ -323,6 +324,8 @@ class MainActivity : Activity() {
|
||||
camera.setProjection(45.0, aspect, 0.1, 20.0, Camera.Fov.VERTICAL)
|
||||
|
||||
view.viewport = Viewport(0, 0, width, height)
|
||||
|
||||
FilamentHelper.synchronizePendingFrames(engine)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,10 @@ plugins {
|
||||
|
||||
project.ext.isSample = true
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(versions.jdk)
|
||||
}
|
||||
|
||||
filamentTools {
|
||||
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
|
||||
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
|
||||
@@ -36,6 +40,11 @@ android {
|
||||
aaptOptions {
|
||||
noCompress 'filamat', 'ktx'
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility versions.jdk
|
||||
targetCompatibility versions.jdk
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@@ -33,6 +33,7 @@ import com.google.android.filament.*
|
||||
import com.google.android.filament.RenderableManager.*
|
||||
import com.google.android.filament.VertexBuffer.*
|
||||
import com.google.android.filament.android.DisplayHelper
|
||||
import com.google.android.filament.android.FilamentHelper
|
||||
import com.google.android.filament.android.UiHelper
|
||||
|
||||
import java.nio.ByteBuffer
|
||||
@@ -139,9 +140,9 @@ class MainActivity : Activity() {
|
||||
camera = engine.createCamera(engine.entityManager.create())
|
||||
|
||||
// clear the swapchain with transparent pixels
|
||||
val options = renderer.clearOptions
|
||||
options.clear = true
|
||||
renderer.clearOptions = options
|
||||
renderer.clearOptions = renderer.clearOptions.apply {
|
||||
clear = true
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupView() {
|
||||
@@ -350,6 +351,8 @@ class MainActivity : Activity() {
|
||||
-aspect * zoom, aspect * zoom, -zoom, zoom, 0.0, 10.0)
|
||||
|
||||
view.viewport = Viewport(0, 0, width, height)
|
||||
|
||||
FilamentHelper.synchronizePendingFrames(engine)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
112
build.sh
112
build.sh
@@ -90,8 +90,8 @@ function print_help {
|
||||
echo " Desktop matc target, release build:"
|
||||
echo " \$ ./$self_name release matc"
|
||||
echo ""
|
||||
echo " Build gltf_viewer then immediately run it with no arguments:"
|
||||
echo " \$ ./$self_name release run_gltf_viewer"
|
||||
echo " Build gltf_viewer:"
|
||||
echo " \$ ./$self_name release gltf_viewer"
|
||||
echo ""
|
||||
}
|
||||
|
||||
@@ -191,6 +191,7 @@ function build_clean {
|
||||
rm -Rf android/filamat-android/build android/filamat-android/.externalNativeBuild android/filamat-android/.cxx
|
||||
rm -Rf android/gltfio-android/build android/gltfio-android/.externalNativeBuild android/gltfio-android/.cxx
|
||||
rm -Rf android/filament-utils-android/build android/filament-utils-android/.externalNativeBuild android/filament-utils-android/.cxx
|
||||
rm -f compile_commands.json
|
||||
}
|
||||
|
||||
function build_clean_aggressive {
|
||||
@@ -210,13 +211,10 @@ function build_desktop_target {
|
||||
echo "Building ${lc_target} in out/cmake-${lc_target}..."
|
||||
mkdir -p "out/cmake-${lc_target}"
|
||||
|
||||
cd "out/cmake-${lc_target}"
|
||||
pushd "out/cmake-${lc_target}" > /dev/null
|
||||
|
||||
# On macOS, set the deployment target to 10.15.
|
||||
local lc_name=$(echo "${UNAME}" | tr '[:upper:]' '[:lower:]')
|
||||
if [[ "${lc_name}" == "darwin" ]]; then
|
||||
local deployment_target="-DCMAKE_OSX_DEPLOYMENT_TARGET=10.15"
|
||||
|
||||
if [[ "${BUILD_UNIVERSAL_LIBRARIES}" == "true" ]]; then
|
||||
local architectures="-DCMAKE_OSX_ARCHITECTURES=arm64;x86_64"
|
||||
fi
|
||||
@@ -233,9 +231,10 @@ function build_desktop_target {
|
||||
${MATDBG_OPTION} \
|
||||
${MATOPT_OPTION} \
|
||||
${ASAN_UBSAN_OPTION} \
|
||||
${deployment_target} \
|
||||
${architectures} \
|
||||
../..
|
||||
ln -sf "out/cmake-${lc_target}/compile_commands.json" \
|
||||
../../compile_commands.json
|
||||
fi
|
||||
${BUILD_COMMAND} ${build_targets}
|
||||
|
||||
@@ -247,12 +246,13 @@ function build_desktop_target {
|
||||
if [[ -d "../${lc_target}/filament" ]]; then
|
||||
if [[ "${ISSUE_ARCHIVES}" == "true" ]]; then
|
||||
echo "Generating out/filament-${lc_target}-${LC_UNAME}.tgz..."
|
||||
cd "../${lc_target}"
|
||||
pushd "../${lc_target}" > /dev/null
|
||||
tar -czvf "../filament-${lc_target}-${LC_UNAME}.tgz" filament
|
||||
popd > /dev/null
|
||||
fi
|
||||
fi
|
||||
|
||||
cd ../..
|
||||
popd > /dev/null
|
||||
}
|
||||
|
||||
function build_desktop {
|
||||
@@ -270,7 +270,7 @@ function build_webgl_with_target {
|
||||
|
||||
echo "Building WebGL ${lc_target}..."
|
||||
mkdir -p "out/cmake-webgl-${lc_target}"
|
||||
cd "out/cmake-webgl-${lc_target}"
|
||||
pushd "out/cmake-webgl-${lc_target}" > /dev/null
|
||||
|
||||
if [[ ! "${BUILD_TARGETS}" ]]; then
|
||||
BUILD_TARGETS=${BUILD_CUSTOM_TARGETS}
|
||||
@@ -290,6 +290,8 @@ function build_webgl_with_target {
|
||||
-DCMAKE_INSTALL_PREFIX="../webgl-${lc_target}/filament" \
|
||||
-DWEBGL=1 \
|
||||
../..
|
||||
ln -sf "out/cmake-webgl-${lc_target}/compile_commands.json" \
|
||||
../../compile_commands.json
|
||||
${BUILD_COMMAND} ${BUILD_TARGETS}
|
||||
)
|
||||
fi
|
||||
@@ -307,17 +309,17 @@ function build_webgl_with_target {
|
||||
|
||||
if [[ "${ISSUE_ARCHIVES}" == "true" ]]; then
|
||||
echo "Generating out/filament-${lc_target}-web.tgz..."
|
||||
cd web/filament-js
|
||||
pushd web/filament-js > /dev/null
|
||||
tar -cvf "../../../filament-${lc_target}-web.tar" filament.js
|
||||
tar -rvf "../../../filament-${lc_target}-web.tar" filament.wasm
|
||||
tar -rvf "../../../filament-${lc_target}-web.tar" filament.d.ts
|
||||
cd -
|
||||
popd > /dev/null
|
||||
gzip -c "../filament-${lc_target}-web.tar" > "../filament-${lc_target}-web.tgz"
|
||||
rm "../filament-${lc_target}-web.tar"
|
||||
fi
|
||||
fi
|
||||
|
||||
cd ../..
|
||||
popd > /dev/null
|
||||
}
|
||||
|
||||
function build_webgl {
|
||||
@@ -348,7 +350,7 @@ function build_android_target {
|
||||
echo "Building Android ${lc_target} (${arch})..."
|
||||
mkdir -p "out/cmake-android-${lc_target}-${arch}"
|
||||
|
||||
cd "out/cmake-android-${lc_target}-${arch}"
|
||||
pushd "out/cmake-android-${lc_target}-${arch}" > /dev/null
|
||||
|
||||
if [[ ! -d "CMakeFiles" ]] || [[ "${ISSUE_CMAKE_ALWAYS}" == "true" ]]; then
|
||||
cmake \
|
||||
@@ -362,12 +364,14 @@ function build_android_target {
|
||||
${MATOPT_OPTION} \
|
||||
${VULKAN_ANDROID_OPTION} \
|
||||
../..
|
||||
ln -sf "out/cmake-android-${lc_target}-${arch}/compile_commands.json" \
|
||||
../../compile_commands.json
|
||||
fi
|
||||
|
||||
# We must always install Android libraries to build the AAR
|
||||
${BUILD_COMMAND} install
|
||||
|
||||
cd ../..
|
||||
popd > /dev/null
|
||||
}
|
||||
|
||||
function build_android_arch {
|
||||
@@ -388,9 +392,9 @@ function archive_android {
|
||||
if [[ -d "out/android-${lc_target}/filament" ]]; then
|
||||
if [[ "${ISSUE_ARCHIVES}" == "true" ]]; then
|
||||
echo "Generating out/filament-android-${lc_target}-${LC_UNAME}.tgz..."
|
||||
cd "out/android-${lc_target}"
|
||||
pushd "out/android-${lc_target}" > /dev/null
|
||||
tar -czvf "../filament-android-${lc_target}-${LC_UNAME}.tgz" filament
|
||||
cd ../..
|
||||
popd > /dev/null
|
||||
fi
|
||||
fi
|
||||
}
|
||||
@@ -468,7 +472,7 @@ function build_android {
|
||||
archive_android "Release"
|
||||
fi
|
||||
|
||||
cd android
|
||||
pushd android > /dev/null
|
||||
|
||||
if [[ "${ISSUE_DEBUG_BUILD}" == "true" ]]; then
|
||||
./gradlew \
|
||||
@@ -491,19 +495,20 @@ function build_android {
|
||||
./gradlew \
|
||||
-Pcom.google.android.filament.dist-dir=../out/android-debug/filament \
|
||||
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
|
||||
${MATOPT_GRADLE_OPTION} \
|
||||
:samples:${sample}:assembleDebug
|
||||
done
|
||||
fi
|
||||
|
||||
if [[ "${INSTALL_COMMAND}" ]]; then
|
||||
echo "Installing out/filamat-android-debug.aar..."
|
||||
cp filamat-android/build/outputs/aar/filamat-android-full-debug.aar ../out/filamat-android-debug.aar
|
||||
cp filamat-android/build/outputs/aar/filamat-android-debug.aar ../out/filamat-android-debug.aar
|
||||
|
||||
echo "Installing out/filament-android-debug.aar..."
|
||||
cp filament-android/build/outputs/aar/filament-android-debug.aar ../out/
|
||||
|
||||
echo "Installing out/gltfio-android-debug.aar..."
|
||||
cp gltfio-android/build/outputs/aar/gltfio-android-full-debug.aar ../out/gltfio-android-debug.aar
|
||||
cp gltfio-android/build/outputs/aar/gltfio-android-debug.aar ../out/gltfio-android-debug.aar
|
||||
|
||||
echo "Installing out/filament-utils-android-debug.aar..."
|
||||
cp filament-utils-android/build/outputs/aar/filament-utils-android-debug.aar ../out/filament-utils-android-debug.aar
|
||||
@@ -539,20 +544,20 @@ function build_android {
|
||||
./gradlew \
|
||||
-Pcom.google.android.filament.dist-dir=../out/android-release/filament \
|
||||
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
|
||||
${MATOPT_GRADLE_OPTION} \
|
||||
:samples:${sample}:assembleRelease
|
||||
done
|
||||
fi
|
||||
|
||||
if [[ "${INSTALL_COMMAND}" ]]; then
|
||||
echo "Installing out/filamat-android-release.aar..."
|
||||
cp filamat-android/build/outputs/aar/filamat-android-lite-release.aar ../out/
|
||||
cp filamat-android/build/outputs/aar/filamat-android-full-release.aar ../out/filamat-android-release.aar
|
||||
cp filamat-android/build/outputs/aar/filamat-android-release.aar ../out/filamat-android-release.aar
|
||||
|
||||
echo "Installing out/filament-android-release.aar..."
|
||||
cp filament-android/build/outputs/aar/filament-android-release.aar ../out/
|
||||
|
||||
echo "Installing out/gltfio-android-release.aar..."
|
||||
cp gltfio-android/build/outputs/aar/gltfio-android-full-release.aar ../out/gltfio-android-release.aar
|
||||
cp gltfio-android/build/outputs/aar/gltfio-android-release.aar ../out/gltfio-android-release.aar
|
||||
|
||||
echo "Installing out/filament-utils-android-release.aar..."
|
||||
cp filament-utils-android/build/outputs/aar/filament-utils-android-release.aar ../out/filament-utils-android-release.aar
|
||||
@@ -567,7 +572,7 @@ function build_android {
|
||||
fi
|
||||
fi
|
||||
|
||||
cd ..
|
||||
popd > /dev/null
|
||||
}
|
||||
|
||||
function build_ios_target {
|
||||
@@ -578,7 +583,7 @@ function build_ios_target {
|
||||
echo "Building iOS ${lc_target} (${arch}) for ${platform}..."
|
||||
mkdir -p "out/cmake-ios-${lc_target}-${arch}"
|
||||
|
||||
cd "out/cmake-ios-${lc_target}-${arch}"
|
||||
pushd "out/cmake-ios-${lc_target}-${arch}" > /dev/null
|
||||
|
||||
if [[ ! -d "CMakeFiles" ]] || [[ "${ISSUE_CMAKE_ALWAYS}" == "true" ]]; then
|
||||
cmake \
|
||||
@@ -593,6 +598,8 @@ function build_ios_target {
|
||||
${MATDBG_OPTION} \
|
||||
${MATOPT_OPTION} \
|
||||
../..
|
||||
ln -sf "out/cmake-ios-${lc_target}-${arch}/compile_commands.json" \
|
||||
../../compile_commands.json
|
||||
fi
|
||||
|
||||
${BUILD_COMMAND}
|
||||
@@ -602,7 +609,7 @@ function build_ios_target {
|
||||
${BUILD_COMMAND} ${INSTALL_COMMAND}
|
||||
fi
|
||||
|
||||
cd ../..
|
||||
popd > /dev/null
|
||||
}
|
||||
|
||||
function archive_ios {
|
||||
@@ -611,9 +618,9 @@ function archive_ios {
|
||||
if [[ -d "out/ios-${lc_target}/filament" ]]; then
|
||||
if [[ "${ISSUE_ARCHIVES}" == "true" ]]; then
|
||||
echo "Generating out/filament-${lc_target}-ios.tgz..."
|
||||
cd "out/ios-${lc_target}"
|
||||
pushd "out/ios-${lc_target}" > /dev/null
|
||||
tar -czvf "../filament-${lc_target}-ios.tgz" filament
|
||||
cd ../..
|
||||
popd > /dev/null
|
||||
fi
|
||||
fi
|
||||
}
|
||||
@@ -672,14 +679,14 @@ function build_web_docs {
|
||||
|
||||
mkdir -p out/web-docs
|
||||
cp -f docs/web-docs-package.json out/web-docs/package.json
|
||||
cd out/web-docs
|
||||
pushd out/web-docs > /dev/null
|
||||
|
||||
npm install > /dev/null
|
||||
|
||||
# Generate documents
|
||||
npx markdeep-rasterizer ../../docs/Filament.md.html ../../docs/Materials.md.html ../../docs/
|
||||
|
||||
cd ../..
|
||||
popd > /dev/null
|
||||
}
|
||||
|
||||
function validate_build_command {
|
||||
@@ -752,15 +759,28 @@ function run_tests {
|
||||
fi
|
||||
}
|
||||
|
||||
function check_debug_release_build {
|
||||
if [[ "${ISSUE_DEBUG_BUILD}" == "true" || \
|
||||
"${ISSUE_RELEASE_BUILD}" == "true" || \
|
||||
"${ISSUE_CLEAN}" == "true" || \
|
||||
"${ISSUE_WEB_DOCS}" == "true" ]]; then
|
||||
"$@";
|
||||
else
|
||||
echo "You must declare a debug or release target for $@ builds."
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Beginning of the script
|
||||
|
||||
pushd "$(dirname "$0")" > /dev/null
|
||||
|
||||
while getopts ":hacCfijmp:q:uvslwtedk:b" opt; do
|
||||
while getopts ":hacCfgijmp:q:uvslwtedk:b" opt; do
|
||||
case ${opt} in
|
||||
h)
|
||||
print_help
|
||||
exit 1
|
||||
exit 0
|
||||
;;
|
||||
a)
|
||||
ISSUE_ARCHIVES=true
|
||||
@@ -796,7 +816,7 @@ while getopts ":hacCfijmp:q:uvslwtedk:b" opt; do
|
||||
platforms=$(echo "${OPTARG}" | tr ',' '\n')
|
||||
for platform in ${platforms}
|
||||
do
|
||||
case ${platform} in
|
||||
case $(echo "${platform}" | tr '[:upper:]' '[:lower:]') in
|
||||
desktop)
|
||||
ISSUE_DESKTOP_BUILD=true
|
||||
;;
|
||||
@@ -815,6 +835,12 @@ while getopts ":hacCfijmp:q:uvslwtedk:b" opt; do
|
||||
ISSUE_DESKTOP_BUILD=true
|
||||
ISSUE_WEBGL_BUILD=false
|
||||
;;
|
||||
*)
|
||||
echo "Unknown platform ${platform}"
|
||||
echo "Platform must be one of [desktop|android|ios|webgl|all]"
|
||||
echo ""
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
;;
|
||||
@@ -827,7 +853,7 @@ while getopts ":hacCfijmp:q:uvslwtedk:b" opt; do
|
||||
abis=$(echo "${OPTARG}" | tr ',' '\n')
|
||||
for abi in ${abis}
|
||||
do
|
||||
case ${abi} in
|
||||
case $(echo "${abi}" | tr '[:upper:]' '[:lower:]') in
|
||||
armeabi-v7a)
|
||||
ABI_ARMEABI_V7A=true
|
||||
;;
|
||||
@@ -846,6 +872,12 @@ while getopts ":hacCfijmp:q:uvslwtedk:b" opt; do
|
||||
ABI_X86=true
|
||||
ABI_X86_64=true
|
||||
;;
|
||||
*)
|
||||
echo "Unknown abi ${abi}"
|
||||
echo "ABI must be one of [armeabi-v7a|arm64-v8a|x86|x86_64|all]"
|
||||
echo ""
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
;;
|
||||
@@ -909,9 +941,9 @@ fi
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
for arg; do
|
||||
if [[ "${arg}" == "release" ]]; then
|
||||
if [[ $(echo "${arg}" | tr '[:upper:]' '[:lower:]') == "release" ]]; then
|
||||
ISSUE_RELEASE_BUILD=true
|
||||
elif [[ "${arg}" == "debug" ]]; then
|
||||
elif [[ $(echo "${arg}" | tr '[:upper:]' '[:lower:]') == "debug" ]]; then
|
||||
ISSUE_DEBUG_BUILD=true
|
||||
else
|
||||
BUILD_CUSTOM_TARGETS="${BUILD_CUSTOM_TARGETS} ${arg}"
|
||||
@@ -929,19 +961,19 @@ if [[ "${ISSUE_CLEAN_AGGRESSIVE}" == "true" ]]; then
|
||||
fi
|
||||
|
||||
if [[ "${ISSUE_DESKTOP_BUILD}" == "true" ]]; then
|
||||
build_desktop
|
||||
check_debug_release_build build_desktop
|
||||
fi
|
||||
|
||||
if [[ "${ISSUE_ANDROID_BUILD}" == "true" ]]; then
|
||||
build_android
|
||||
check_debug_release_build build_android
|
||||
fi
|
||||
|
||||
if [[ "${ISSUE_IOS_BUILD}" == "true" ]]; then
|
||||
build_ios
|
||||
check_debug_release_build build_ios
|
||||
fi
|
||||
|
||||
if [[ "${ISSUE_WEBGL_BUILD}" == "true" ]]; then
|
||||
build_webgl
|
||||
check_debug_release_build build_webgl
|
||||
fi
|
||||
|
||||
if [[ "${ISSUE_WEB_DOCS}" == "true" ]]; then
|
||||
|
||||
@@ -44,13 +44,20 @@ elif [[ "$LC_UNAME" == "darwin" ]]; then
|
||||
fi
|
||||
source `dirname $0`/../common/build-common.sh
|
||||
|
||||
if [[ "$GITHUB_WORKFLOW" ]]; then
|
||||
java_version=$(java -version 2>&1 | head -1 | cut -d'"' -f2 | sed '/^1\./s///' | cut -d'.' -f1)
|
||||
if [[ "$java_version" < 17 ]]; then
|
||||
echo "Android builds require Java 17, found version ${java_version} instead"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# Unless explicitly specified, NDK version will be set to match exactly the required one
|
||||
FILAMENT_NDK_VERSION=${FILAMENT_NDK_VERSION:-$(cat `dirname $0`/ndk.version)}
|
||||
|
||||
# Install the required NDK version specifically (if not present)
|
||||
if [[ ! -d "${ANDROID_HOME}/ndk/$FILAMENT_NDK_VERSION" ]]; then
|
||||
# NOTE: We MUST use Java 1.8 to run sdkmanager currently, it fails starting with Java 11
|
||||
JAVA_HOME=${JAVA_HOME_8_X64} ${ANDROID_HOME}/tools/bin/sdkmanager "ndk;$FILAMENT_NDK_VERSION" > /dev/null
|
||||
${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager "ndk;$FILAMENT_NDK_VERSION" > /dev/null
|
||||
fi
|
||||
|
||||
# Only build 1 64 bit target during presubmit to cut down build times during presubmit
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
|
||||
set -e
|
||||
|
||||
case "$(uname -s)" in
|
||||
Darwin*) IS_DARWIN=1;;
|
||||
*) ;;
|
||||
esac
|
||||
|
||||
function print_help {
|
||||
local SELF_NAME
|
||||
SELF_NAME=$(basename "$0")
|
||||
@@ -45,7 +50,11 @@ function replace {
|
||||
FIND_STR="${1//\{\{VERSION\}\}/${VERSION_REGEX}}"
|
||||
REPLACE_STR="${1//\{\{VERSION\}\}/${NEW_VERSION}}"
|
||||
local FILE_NAME="$2"
|
||||
sed -i '' -E "s/${FIND_STR}/${REPLACE_STR}/" "${FILE_NAME}"
|
||||
if [ $IS_DARWIN == 1 ]; then
|
||||
sed -i '' -E "s/${FIND_STR}/${REPLACE_STR}/" "${FILE_NAME}"
|
||||
else
|
||||
sed -i -E "s/${FIND_STR}/${REPLACE_STR}/" "${FILE_NAME}"
|
||||
fi
|
||||
}
|
||||
|
||||
# The following are the canonical locations where the Filament version number is referenced.
|
||||
|
||||
@@ -3,12 +3,4 @@
|
||||
if [[ "$GITHUB_WORKFLOW" ]]; then
|
||||
echo "Running workflow $GITHUB_WORKFLOW (event: $GITHUB_EVENT_NAME, action: $GITHUB_ACTION)"
|
||||
CONTINUOUS_INTEGRATION=true
|
||||
|
||||
# Force Java to be Java 11 minimum, it defaults to 8 in GitHub runners for some platforms
|
||||
export JAVA_HOME=${JAVA_HOME_11_X64}
|
||||
java_version=$(java -version 2>&1 | head -1 | cut -d'"' -f2 | sed '/^1\./s///' | cut -d'.' -f1)
|
||||
if [[ "$java_version" < 11 ]]; then
|
||||
echo "Android builds require Java 11, found version ${java_version} instead"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -5,7 +5,6 @@ libs/math/test_math
|
||||
libs/image/test_image compare libs/image/tests/reference/
|
||||
libs/utils/test_utils
|
||||
libs/filamat/test_filamat
|
||||
libs/filamat/test_filamat_lite
|
||||
tools/matc/test_matc
|
||||
tools/cmgen/test_cmgen compare
|
||||
tools/glslminifier/test_glslminifier
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user